Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Granite hardfork #109

Merged
merged 8 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ var (
Name: "override.fjord",
Usage: "Manually specify the Optimism Fjord fork timestamp, overriding the bundled setting",
}
OverrideOptimismGraniteFlag = flags.BigFlag{
Name: "override.granite",
Usage: "Manually specify the Optimism Granite fork timestamp, overriding the bundled setting",
}
// Ethash settings
EthashCachesInMemoryFlag = cli.IntFlag{
Name: "ethash.cachesinmem",
Expand Down Expand Up @@ -1971,6 +1975,9 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C
cfg.OverrideOptimismFjordTime = flags.GlobalBig(ctx, OverrideOptimismFjordFlag.Name)
cfg.TxPool.OptimismFjordTime = cfg.OverrideOptimismFjordTime
}
if ctx.IsSet(OverrideOptimismGraniteFlag.Name) {
cfg.OverrideOptimismGraniteTime = flags.GlobalBig(ctx, OverrideOptimismGraniteFlag.Name)
}
if ctx.IsSet(InternalConsensusFlag.Name) && clparams.EmbeddedSupported(cfg.NetworkID) {
cfg.InternalCL = ctx.Bool(InternalConsensusFlag.Name)
}
Expand Down
4 changes: 4 additions & 0 deletions core/genesis_write.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ type ChainOverrides struct {
OverrideOptimismCanyonTime *big.Int
OverrideOptimismEcotoneTime *big.Int
OverrideOptimismFjordTime *big.Int
OverrideOptimismGraniteTime *big.Int
}

// CommitGenesisBlock writes or updates the genesis block in db.
Expand Down Expand Up @@ -152,6 +153,9 @@ func WriteGenesisBlock(tx kv.RwTx, genesis *types.Genesis, overrides *ChainOverr
if overrides.OverrideOptimismFjordTime != nil {
config.FjordTime = overrides.OverrideOptimismFjordTime
}
if overrides.OverrideOptimismGraniteTime != nil {
config.GraniteTime = overrides.OverrideOptimismGraniteTime
}
}

if (storedHash == libcommon.Hash{}) {
Expand Down
41 changes: 41 additions & 0 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,22 @@ var PrecompiledContractsFjord = map[libcommon.Address]PrecompiledContract{
libcommon.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
}

// PrecompiledContractsGranite contains the default set of pre-compiled Ethereum
// contracts used in the Granite release.
var PrecompiledContractsGranite = map[libcommon.Address]PrecompiledContract{
libcommon.BytesToAddress([]byte{1}): &ecrecover{},
libcommon.BytesToAddress([]byte{2}): &sha256hash{},
libcommon.BytesToAddress([]byte{3}): &ripemd160hash{},
libcommon.BytesToAddress([]byte{4}): &dataCopy{},
libcommon.BytesToAddress([]byte{5}): &bigModExp{eip2565: true},
libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
libcommon.BytesToAddress([]byte{8}): &bn256PairingGranite{},
libcommon.BytesToAddress([]byte{9}): &blake2F{},
libcommon.BytesToAddress([]byte{0x0a}): &pointEvaluation{},
libcommon.BytesToAddress([]byte{0x01, 0x00}): &p256Verify{},
}

var PrecompiledContractsNapoli = map[libcommon.Address]PrecompiledContract{
libcommon.BytesToAddress([]byte{0x01}): &ecrecover{},
libcommon.BytesToAddress([]byte{0x02}): &sha256hash{},
Expand Down Expand Up @@ -167,6 +183,7 @@ var PrecompiledContractsPrague = map[libcommon.Address]PrecompiledContract{
}

var (
PrecompiledAddressesGranite []libcommon.Address
PrecompiledAddressesFjord []libcommon.Address
PrecompiledAddressesPrague []libcommon.Address
PrecompiledAddressesNapoli []libcommon.Address
Expand Down Expand Up @@ -196,6 +213,9 @@ func init() {
for k := range PrecompiledContractsFjord {
PrecompiledAddressesFjord = append(PrecompiledAddressesFjord, k)
}
for k := range PrecompiledContractsGranite {
PrecompiledAddressesGranite = append(PrecompiledAddressesGranite, k)
}
for k := range PrecompiledContractsNapoli {
PrecompiledAddressesNapoli = append(PrecompiledAddressesNapoli, k)
}
Expand All @@ -207,6 +227,8 @@ func init() {
// ActivePrecompiles returns the precompiles enabled with the current configuration.
func ActivePrecompiles(rules *chain.Rules) []libcommon.Address {
switch {
case rules.IsOptimismGranite:
return PrecompiledAddressesGranite
case rules.IsOptimismFjord:
return PrecompiledAddressesFjord
case rules.IsPrague:
Expand Down Expand Up @@ -595,6 +617,9 @@ var (

// errBadPairingInput is returned if the bn256 pairing input is invalid.
errBadPairingInput = errors.New("bad elliptic curve pairing size")

// errBadPairingInputSize is returned if the bn256 pairing input size is invalid.
errBadPairingInputSize = errors.New("bad elliptic curve pairing input size")
)

// runBn256Pairing implements the Bn256Pairing precompile, referenced by both
Expand Down Expand Up @@ -628,6 +653,22 @@ func runBn256Pairing(input []byte) ([]byte, error) {
return false32Byte, nil
}

// bn256PairingGranite implements a pairing pre-compile for the bn256 curve
// conforming to Granite consensus rules.
type bn256PairingGranite struct{}

// RequiredGas returns the gas required to execute the pre-compiled contract.
func (c *bn256PairingGranite) RequiredGas(input []byte) uint64 {
return new(bn256PairingIstanbul).RequiredGas(input)
}

func (c *bn256PairingGranite) Run(input []byte) ([]byte, error) {
if len(input) > int(params.Bn256PairingMaxInputSizeGranite) {
return nil, errBadPairingInputSize
}
return runBn256Pairing(input)
}

// bn256PairingIstanbul implements a pairing pre-compile for the bn256 curve
// conforming to Istanbul consensus rules.
type bn256PairingIstanbul struct{}
Expand Down
12 changes: 11 additions & 1 deletion core/vm/contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
libcommon "github.com/ledgerwatch/erigon-lib/common"

"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/params"
)

// precompiledTest defines the input/output pairs for precompiled contract tests.
Expand Down Expand Up @@ -56,7 +57,7 @@ var allPrecompiles = map[libcommon.Address]PrecompiledContract{
libcommon.BytesToAddress([]byte{0xf5}): &bigModExp{eip2565: true},
libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
libcommon.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
libcommon.BytesToAddress([]byte{8}): &bn256PairingGranite{},
libcommon.BytesToAddress([]byte{9}): &blake2F{},
libcommon.BytesToAddress([]byte{10}): &bls12381G1Add{},
libcommon.BytesToAddress([]byte{11}): &bls12381G1Mul{},
Expand Down Expand Up @@ -279,6 +280,15 @@ func TestPrecompileBlake2FMalformedInput(t *testing.T) {
}
}

func TestPrecompileBn256PairingTooLargeInput(t *testing.T) {
big := make([]byte, params.Bn256PairingMaxInputSizeGranite+1)
testPrecompiledFailure("08", precompiledFailureTest{
Input: common.Bytes2Hex(big),
ExpectedError: "bad elliptic curve pairing input size",
Name: "bn256Pairing_input_too_big",
}, t)
}

func TestPrecompiledEcrecover(t *testing.T) { testJson("ecRecover", "01", t) }

func testJson(name, addr string, t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ var emptyCodeHash = crypto.Keccak256Hash(nil)
func (evm *EVM) precompile(addr libcommon.Address) (PrecompiledContract, bool) {
var precompiles map[libcommon.Address]PrecompiledContract
switch {
case evm.chainRules.IsOptimismGranite:
precompiles = PrecompiledContractsGranite
case evm.chainRules.IsOptimismFjord:
precompiles = PrecompiledContractsFjord
case evm.chainRules.IsPrague:
Expand Down
14 changes: 13 additions & 1 deletion erigon-lib/chain/chain_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ type Config struct {
// Delta: the Delta upgrade does not affect the execution-layer, and is thus not configurable in the chain config.
EcotoneTime *big.Int `json:"ecotoneTime,omitempty"` // Ecotone switch time (nil = no fork, 0 = already on optimism ecotone)
FjordTime *big.Int `json:"fjordTime,omitempty"` // Fjord switch time (nil = no fork, 0 = already on optimism fjord)
GraniteTime *big.Int `json:"graniteTime,omitempty"` // Granite switch time (nil = no fork, 0 = already on Optimism Granite)

// Optional EIP-4844 parameters
MinBlobGasPrice *uint64 `json:"minBlobGasPrice,omitempty"`
Expand Down Expand Up @@ -125,7 +126,7 @@ type BorConfig interface {
func (c *Config) String() string {
engine := c.getEngine()

return fmt.Sprintf("{ChainID: %v, Homestead: %v, DAO: %v, Tangerine Whistle: %v, Spurious Dragon: %v, Byzantium: %v, Constantinople: %v, Petersburg: %v, Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, Gray Glacier: %v, Terminal Total Difficulty: %v, Merge Netsplit: %v, Shanghai: %v, Cancun: %v, Prague: %v, Osaka: %v, BedrockBlock: %v, RegolithTime: %v, CanyonTime: %v, EcotoneTime: %v, FjordTime: %v, Engine: %v , NoPruneContracts: %v}",
return fmt.Sprintf("{ChainID: %v, Homestead: %v, DAO: %v, Tangerine Whistle: %v, Spurious Dragon: %v, Byzantium: %v, Constantinople: %v, Petersburg: %v, Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, Gray Glacier: %v, Terminal Total Difficulty: %v, Merge Netsplit: %v, Shanghai: %v, Cancun: %v, Prague: %v, Osaka: %v, BedrockBlock: %v, RegolithTime: %v, CanyonTime: %v, EcotoneTime: %v, FjordTime: %v, GraniteTime: %v, Engine: %v , NoPruneContracts: %v}",
c.ChainID,
c.HomesteadBlock,
c.DAOForkBlock,
Expand All @@ -151,6 +152,7 @@ func (c *Config) String() string {
c.CanyonTime,
c.EcotoneTime,
c.FjordTime,
c.GraniteTime,
engine,
c.NoPruneContracts,
)
Expand Down Expand Up @@ -293,6 +295,10 @@ func (c *Config) IsFjord(time uint64) bool {
return isForked(c.FjordTime, time)
}

func (c *Config) IsGranite(time uint64) bool {
return isForked(c.GraniteTime, time)
}

// IsOptimism returns whether the node is an optimism node or not.
func (c *Config) IsOptimism() bool {
return c.Optimism != nil
Expand All @@ -319,6 +325,10 @@ func (c *Config) IsOptimismFjord(time uint64) bool {
return c.IsOptimism() && c.IsFjord(time)
}

func (c *Config) IsOptimismGranite(time uint64) bool {
return c.IsOptimism() && c.IsGranite(time)
}

// IsOptimismPreBedrock returns true iff this is an optimism node & bedrock is not yet active
func (c *Config) IsOptimismPreBedrock(num uint64) bool {
return c.IsOptimism() && !c.IsBedrock(num)
Expand Down Expand Up @@ -612,6 +622,7 @@ type Rules struct {
IsAura bool
IsOptimismBedrock, IsOptimismRegolith bool
IsOptimismCanyon, IsOptimismFjord bool
IsOptimismGranite bool
}

// Rules ensures c's ChainID is not nil and returns a new Rules instance
Expand Down Expand Up @@ -642,6 +653,7 @@ func (c *Config) Rules(num uint64, time uint64) *Rules {
IsOptimismRegolith: c.IsOptimismRegolith(time),
IsOptimismCanyon: c.IsOptimismCanyon(time),
IsOptimismFjord: c.IsOptimismFjord(time),
IsOptimismGranite: c.IsOptimismGranite(time),
}
}

Expand Down
7 changes: 7 additions & 0 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger
OverrideOptimismCanyonTime: config.OverrideOptimismCanyonTime,
OverrideOptimismEcotoneTime: config.OverrideOptimismEcotoneTime,
OverrideOptimismFjordTime: config.OverrideOptimismFjordTime,
OverrideOptimismGraniteTime: config.OverrideOptimismGraniteTime,
OverridePragueTime: config.OverridePragueTime,
}
chainConfig, genesis, genesisErr = core.WriteGenesisBlock(tx, genesisSpec, overrides, tmpdir, logger)
Expand All @@ -337,6 +338,12 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger
if chainConfig.EcotoneTime == nil {
log.Warn("Optimism EcotoneTime has not been set")
}
if chainConfig.FjordTime == nil {
log.Warn("Optimism FjordTime has not been set")
}
if chainConfig.GraniteTime == nil {
log.Warn("Optimism GraniteTime has not been set")
}
}

setBorDefaultMinerGasPrice(chainConfig, config, logger)
Expand Down
1 change: 1 addition & 0 deletions eth/ethconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ type Config struct {
OverrideOptimismCanyonTime *big.Int `toml:",omitempty"`
OverrideOptimismEcotoneTime *big.Int `toml:",omitempty"`
OverrideOptimismFjordTime *big.Int `toml:",omitempty"`
OverrideOptimismGraniteTime *big.Int `toml:",omitempty"`

// Embedded Silkworm support
SilkwormExecution bool
Expand Down
Loading