diff --git a/cmd/evm/t8n_test.go b/cmd/evm/t8n_test.go index de6b0e5ccb..b4b816f57a 100644 --- a/cmd/evm/t8n_test.go +++ b/cmd/evm/t8n_test.go @@ -171,13 +171,45 @@ func TestT8n(t *testing.T) { output: t8nOutput{result: true}, expOut: "exp2.json", }, + { // Difficulty calculation - with uncles + Berlin + base: "./testdata/14", + input: t8nInput{ + "alloc.json", "txs.json", "env.uncles.json", "Berlin", "", + }, + output: t8nOutput{result: true}, + expOut: "exp_berlin.json", + }, + { // Difficulty calculation on arrow glacier + base: "./testdata/19", + input: t8nInput{ + "alloc.json", "txs.json", "env.json", "London", "", + }, + output: t8nOutput{result: true}, + expOut: "exp_london.json", + }, + { // Difficulty calculation on arrow glacier + base: "./testdata/19", + input: t8nInput{ + "alloc.json", "txs.json", "env.json", "ArrowGlacier", "", + }, + output: t8nOutput{result: true}, + expOut: "exp_arrowglacier.json", + }, } { args := []string{"t8n"} args = append(args, tc.output.get()...) args = append(args, tc.input.get(tc.base)...) + var qArgs []string // quoted args for debugging purposes + for _, arg := range args { + if len(arg) == 0 { + qArgs = append(qArgs, `""`) + } else { + qArgs = append(qArgs, arg) + } + } + tt.Logf("args: %v\n", strings.Join(qArgs, " ")) tt.Run("evm-test", args...) - tt.Logf("args: %v\n", strings.Join(args, " ")) // Compare the expected output, if provided if tc.expOut != "" { want, err := os.ReadFile(fmt.Sprintf("%v/%v", tc.base, tc.expOut)) diff --git a/cmd/evm/testdata/14/exp_berlin.json b/cmd/evm/testdata/14/exp_berlin.json new file mode 100644 index 0000000000..e564788315 --- /dev/null +++ b/cmd/evm/testdata/14/exp_berlin.json @@ -0,0 +1,11 @@ +{ + "result": { + "stateRoot": "0x6f058887ca01549716789c380ede95aecc510e6d1fdc4dbf67d053c7c07f4bdc", + "txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "receipts": [], + "currentDifficulty": "0x1ff9000000000" + } +} \ No newline at end of file diff --git a/cmd/evm/testdata/19/alloc.json b/cmd/evm/testdata/19/alloc.json new file mode 100644 index 0000000000..cef1a25ff0 --- /dev/null +++ b/cmd/evm/testdata/19/alloc.json @@ -0,0 +1,12 @@ +{ + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0x5ffd4878be161d74", + "code": "0x", + "nonce": "0xac", + "storage": {} + }, + "0x8a8eafb1cf62bfbeb1741769dae1a9dd47996192":{ + "balance": "0xfeedbead", + "nonce" : "0x00" + } +} \ No newline at end of file diff --git a/cmd/evm/testdata/19/env.json b/cmd/evm/testdata/19/env.json new file mode 100644 index 0000000000..0c64392aff --- /dev/null +++ b/cmd/evm/testdata/19/env.json @@ -0,0 +1,9 @@ +{ + "currentCoinbase": "0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "currentGasLimit": "0x750a163df65e8a", + "currentBaseFee": "0x500", + "currentNumber": "13000000", + "currentTimestamp": "100015", + "parentTimestamp" : "99999", + "parentDifficulty" : "0x2000000000000" +} diff --git a/cmd/evm/testdata/19/exp_arrowglacier.json b/cmd/evm/testdata/19/exp_arrowglacier.json new file mode 100644 index 0000000000..4c5f8e0fbd --- /dev/null +++ b/cmd/evm/testdata/19/exp_arrowglacier.json @@ -0,0 +1,11 @@ +{ + "result": { + "stateRoot": "0x6f058887ca01549716789c380ede95aecc510e6d1fdc4dbf67d053c7c07f4bdc", + "txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "currentDifficulty": "0x2000000200000", + "receipts": [] + } +} \ No newline at end of file diff --git a/cmd/evm/testdata/19/exp_london.json b/cmd/evm/testdata/19/exp_london.json new file mode 100644 index 0000000000..9dc1b9d4f3 --- /dev/null +++ b/cmd/evm/testdata/19/exp_london.json @@ -0,0 +1,11 @@ +{ + "result": { + "stateRoot": "0x6f058887ca01549716789c380ede95aecc510e6d1fdc4dbf67d053c7c07f4bdc", + "txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "currentDifficulty": "0x2000080000000", + "receipts": [] + } +} \ No newline at end of file diff --git a/cmd/evm/testdata/19/readme.md b/cmd/evm/testdata/19/readme.md new file mode 100644 index 0000000000..5fae183f48 --- /dev/null +++ b/cmd/evm/testdata/19/readme.md @@ -0,0 +1,9 @@ +## Difficulty calculation + +This test shows how the `evm t8n` can be used to calculate the (ethash) difficulty, if none is provided by the caller, +this time on `ArrowGlacier` (Eip 4345). + +Calculating it (with an empty set of txs) using `ArrowGlacier` rules (and no provided unclehash for the parent block): +``` +[user@work evm]$ ./evm t8n --input.alloc=./testdata/14/alloc.json --input.txs=./testdata/14/txs.json --input.env=./testdata/14/env.json --output.result=stdout --state.fork=ArrowGlacier +``` \ No newline at end of file diff --git a/cmd/evm/testdata/19/txs.json b/cmd/evm/testdata/19/txs.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/cmd/evm/testdata/19/txs.json @@ -0,0 +1 @@ +[] diff --git a/cmd/geth/config.go b/cmd/geth/config.go index c97a64f173..08b9a1154f 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -156,8 +156,8 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { // makeFullNode loads geth configuration and creates the Ethereum backend. func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) { stack, cfg := makeConfigNode(ctx) - if ctx.GlobalIsSet(utils.OverrideLondonFlag.Name) { - cfg.Eth.OverrideLondon = new(big.Int).SetUint64(ctx.GlobalUint64(utils.OverrideLondonFlag.Name)) + if ctx.GlobalIsSet(utils.OverrideArrowGlacierFlag.Name) { + cfg.Eth.OverrideArrowGlacier = new(big.Int).SetUint64(ctx.GlobalUint64(utils.OverrideArrowGlacierFlag.Name)) } backend, eth := utils.RegisterEthService(stack, &cfg.Eth) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 46c8a8b2e2..9d80ce0bed 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -66,7 +66,7 @@ var ( utils.NoUSBFlag, utils.USBFlag, utils.SmartCardDaemonPathFlag, - utils.OverrideLondonFlag, + utils.OverrideArrowGlacierFlag, utils.EthashCacheDirFlag, utils.EthashCachesInMemoryFlag, utils.EthashCachesOnDiskFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 0a7a7482a5..b3d9f395b0 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -235,9 +235,9 @@ var ( Usage: "Megabytes of memory allocated to bloom-filter for pruning", Value: 2048, } - OverrideLondonFlag = cli.Uint64Flag{ - Name: "override.london", - Usage: "Manually specify London fork-block, overriding the bundled setting", + OverrideArrowGlacierFlag = cli.Uint64Flag{ + Name: "override.arrowglacier", + Usage: "Manually specify Arrow Glacier fork-block, overriding the bundled setting", } // Light server and client settings LightServeFlag = cli.IntFlag{ diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 6ad9fc22be..7fa427f68b 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -45,6 +45,11 @@ var ( maxUncles = 2 // Maximum number of uncles allowed in a single block allowedFutureBlockTimeSeconds = int64(15) // Max seconds from current time allowed for blocks, before they're considered future blocks + // calcDifficultyEip4345 is the difficulty adjustment algorithm as specified by EIP 4345. + // It offsets the bomb a total of 10.7M blocks. + // Specification EIP-4345: https://eips.ethereum.org/EIPS/eip-4345 + calcDifficultyEip4345 = makeDifficultyCalculator(big.NewInt(10_700_000)) + // calcDifficultyEip3554 is the difficulty adjustment algorithm as specified by EIP 3554. // It offsets the bomb a total of 9.7M blocks. // Specification EIP-3554: https://eips.ethereum.org/EIPS/eip-3554 @@ -330,6 +335,8 @@ func (ethash *Ethash) CalcDifficulty(chain consensus.ChainHeaderReader, time uin func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Header) *big.Int { next := new(big.Int).Add(parent.Number, big1) switch { + case config.IsArrowGlacier(next): + return calcDifficultyEip4345(time, parent) case config.IsLondon(next): return calcDifficultyEip3554(time, parent) case config.IsMuirGlacier(next): diff --git a/core/forkid/forkid_test.go b/core/forkid/forkid_test.go index 916bffadc0..84c34561d1 100644 --- a/core/forkid/forkid_test.go +++ b/core/forkid/forkid_test.go @@ -63,8 +63,10 @@ func TestCreation(t *testing.T) { {12243999, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // Last Muir Glacier block {12244000, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // First Berlin block {12964999, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // Last Berlin block - {12965000, ID{Hash: checksumToBytes(0xb715077d), Next: 0}}, // First London block - {20000000, ID{Hash: checksumToBytes(0xb715077d), Next: 0}}, // Future London block + {12965000, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // First London block + {13772999, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // Last London block + {13773000, ID{Hash: checksumToBytes(0x20c327fc), Next: 0}}, /// First Arrow Glacier block + {20000000, ID{Hash: checksumToBytes(0x20c327fc), Next: 0}}, // Future Arrow Glacier block }, }, // Ropsten test cases @@ -205,11 +207,11 @@ func TestValidation(t *testing.T) { // Local is mainnet Petersburg, remote is Rinkeby Petersburg. {7987396, ID{Hash: checksumToBytes(0xafec6b27), Next: 0}, ErrLocalIncompatibleOrStale}, - // Local is mainnet London, far in the future. Remote announces Gopherium (non existing fork) + // Local is mainnet Arrow Glacier, far in the future. Remote announces Gopherium (non existing fork) // at some future block 88888888, for itself, but past block for local. Local is incompatible. // // This case detects non-upgraded nodes with majority hash power (typical Ropsten mess). - {88888888, ID{Hash: checksumToBytes(0xb715077d), Next: 88888888}, ErrLocalIncompatibleOrStale}, + {88888888, ID{Hash: checksumToBytes(0x20c327fc), Next: 88888888}, ErrLocalIncompatibleOrStale}, // Local is mainnet Byzantium. Remote is also in Byzantium, but announces Gopherium (non existing // fork) at block 7279999, before Petersburg. Local is incompatible. diff --git a/core/genesis.go b/core/genesis.go index af36247471..1c1534fbb5 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -158,7 +158,7 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig return SetupGenesisBlockWithOverride(db, genesis, nil) } -func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, overrideLondon *big.Int) (*params.ChainConfig, common.Hash, error) { +func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, overrideArrowGlacier *big.Int) (*params.ChainConfig, common.Hash, error) { if genesis != nil && genesis.Config == nil { return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig } @@ -204,8 +204,8 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override } // Get the existing chain configuration. newcfg := genesis.configOrDefault(stored) - if overrideLondon != nil { - newcfg.LondonBlock = overrideLondon + if overrideArrowGlacier != nil { + newcfg.ArrowGlacierBlock = overrideArrowGlacier } if err := newcfg.CheckConfigForkOrder(); err != nil { return newcfg, common.Hash{}, err diff --git a/eth/backend.go b/eth/backend.go index 9bfa844c73..ae4e6e85d7 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -131,7 +131,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if err != nil { return nil, err } - chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideLondon) + chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideArrowGlacier) if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok { return nil, genesisErr } diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 52391d417d..29b47af259 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -202,8 +202,8 @@ type Config struct { // CheckpointOracle is the configuration for checkpoint oracle. CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"` - // Berlin block override (TODO: remove after the fork) - OverrideLondon *big.Int `toml:",omitempty"` + // Arrow Glacier block override (TODO: remove after the fork) + OverrideArrowGlacier *big.Int `toml:",omitempty"` } // CreateConsensusEngine creates a consensus engine for the given chain configuration. diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index ed4c928508..1f1ee3aafb 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -59,7 +59,7 @@ func (c Config) MarshalTOML() (interface{}, error) { RPCTxFeeCap float64 Checkpoint *params.TrustedCheckpoint `toml:",omitempty"` CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"` - OverrideLondon *big.Int `toml:",omitempty"` + OverrideArrowGlacier *big.Int `toml:",omitempty"` } var enc Config enc.Genesis = c.Genesis @@ -103,7 +103,7 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.RPCTxFeeCap = c.RPCTxFeeCap enc.Checkpoint = c.Checkpoint enc.CheckpointOracle = c.CheckpointOracle - enc.OverrideLondon = c.OverrideLondon + enc.OverrideArrowGlacier = c.OverrideArrowGlacier return &enc, nil } @@ -151,7 +151,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { RPCTxFeeCap *float64 Checkpoint *params.TrustedCheckpoint `toml:",omitempty"` CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"` - OverrideLondon *big.Int `toml:",omitempty"` + OverrideArrowGlacier *big.Int `toml:",omitempty"` } var dec Config if err := unmarshal(&dec); err != nil { @@ -280,8 +280,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.CheckpointOracle != nil { c.CheckpointOracle = dec.CheckpointOracle } - if dec.OverrideLondon != nil { - c.OverrideLondon = dec.OverrideLondon + if dec.OverrideArrowGlacier != nil { + c.OverrideArrowGlacier = dec.OverrideArrowGlacier } return nil } diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index 1e249ae14b..2d394200a0 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -107,10 +107,13 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke signer = types.LatestSigner(gspec.Config) ) config.LondonBlock = londonBlock + config.ArrowGlacierBlock = londonBlock engine := ethash.NewFaker() db := rawdb.NewMemoryDatabase() - genesis, _ := gspec.Commit(db) - + genesis, err := gspec.Commit(db) + if err != nil { + t.Fatal(err) + } // Generate testing blocks blocks, _ := core.GenerateChain(gspec.Config, genesis, engine, db, testHead+1, func(i int, b *core.BlockGen) { b.SetCoinbase(common.Address{1}) diff --git a/les/client.go b/les/client.go index 5d07c783e9..93319cb936 100644 --- a/les/client.go +++ b/les/client.go @@ -88,7 +88,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*LightEthereum, error) { if err != nil { return nil, err } - chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideLondon) + chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideArrowGlacier) if _, isCompat := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !isCompat { return nil, genesisErr } diff --git a/params/config.go b/params/config.go index fdbff93024..4715fbacda 100644 --- a/params/config.go +++ b/params/config.go @@ -69,6 +69,7 @@ var ( MuirGlacierBlock: big.NewInt(9_200_000), BerlinBlock: big.NewInt(12_244_000), LondonBlock: big.NewInt(12_965_000), + ArrowGlacierBlock: big.NewInt(13_773_000), Ethash: new(EthashConfig), } @@ -151,6 +152,7 @@ var ( MuirGlacierBlock: nil, BerlinBlock: big.NewInt(8_290_928), LondonBlock: big.NewInt(8_897_988), + ArrowGlacierBlock: nil, Clique: &CliqueConfig{ Period: 15, Epoch: 30000, @@ -193,6 +195,7 @@ var ( MuirGlacierBlock: nil, BerlinBlock: big.NewInt(4_460_644), LondonBlock: big.NewInt(5_062_605), + ArrowGlacierBlock: nil, Clique: &CliqueConfig{ Period: 15, Epoch: 30000, @@ -225,16 +228,16 @@ var ( // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil} + AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil} // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the Clique consensus. // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}} + AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}} - TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil} + TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil} TestRules = TestChainConfig.Rules(new(big.Int)) ) @@ -313,6 +316,7 @@ type ChainConfig struct { MuirGlacierBlock *big.Int `json:"muirGlacierBlock,omitempty"` // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated) BerlinBlock *big.Int `json:"berlinBlock,omitempty"` // Berlin switch block (nil = no fork, 0 = already on berlin) LondonBlock *big.Int `json:"londonBlock,omitempty"` // London switch block (nil = no fork, 0 = already on london) + ArrowGlacierBlock *big.Int `json:"arrowGlacierBlock,omitempty"` // Eip-4345 (bomb delay) switch block (nil = no fork, 0 = already activated) // TerminalTotalDifficulty is the amount of total difficulty reached by // the network that triggers the consensus upgrade. @@ -353,7 +357,7 @@ func (c *ChainConfig) String() string { default: engine = "unknown" } - return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Engine: %v}", + return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, Engine: %v}", c.ChainID, c.HomesteadBlock, c.DAOForkBlock, @@ -368,6 +372,7 @@ func (c *ChainConfig) String() string { c.MuirGlacierBlock, c.BerlinBlock, c.LondonBlock, + c.ArrowGlacierBlock, engine, ) } @@ -434,6 +439,11 @@ func (c *ChainConfig) IsLondon(num *big.Int) bool { return isForked(c.LondonBlock, num) } +// IsArrowGlacier returns whether num is either equal to the Arrow Glacier (EIP-4345) fork block or greater. +func (c *ChainConfig) IsArrowGlacier(num *big.Int) bool { + return isForked(c.ArrowGlacierBlock, num) +} + // IsTerminalPoWBlock returns whether the given block is the last block of PoW stage. func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *big.Int) bool { if c.TerminalTotalDifficulty == nil { @@ -482,6 +492,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error { {name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true}, {name: "berlinBlock", block: c.BerlinBlock}, {name: "londonBlock", block: c.LondonBlock}, + {name: "arrowGlacierBlock", block: c.ArrowGlacierBlock, optional: true}, } { if lastFork.name != "" { // Next one must be higher number @@ -551,6 +562,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi if isForkIncompatible(c.LondonBlock, newcfg.LondonBlock, head) { return newCompatError("London fork block", c.LondonBlock, newcfg.LondonBlock) } + if isForkIncompatible(c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock, head) { + return newCompatError("Arrow Glacier fork block", c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock) + } return nil } diff --git a/tests/difficulty_test.go b/tests/difficulty_test.go index acbf96e712..192dff12cc 100644 --- a/tests/difficulty_test.go +++ b/tests/difficulty_test.go @@ -76,6 +76,9 @@ func TestDifficulty(t *testing.T) { dt.config("EIP2384", params.ChainConfig{ MuirGlacierBlock: big.NewInt(0), }) + dt.config("EIP4345", params.ChainConfig{ + ArrowGlacierBlock: big.NewInt(0), + }) dt.config("difficulty.json", mainnetChainConfig) dt.walk(t, difficultyTestDir, func(t *testing.T, name string, test *DifficultyTest) { diff --git a/tests/init.go b/tests/init.go index b0a38e68b0..d6b5b3043d 100644 --- a/tests/init.go +++ b/tests/init.go @@ -151,6 +151,7 @@ var Forks = map[string]*params.ChainConfig{ ConstantinopleBlock: big.NewInt(0), PetersburgBlock: big.NewInt(0), IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), BerlinBlock: big.NewInt(0), }, "BerlinToLondonAt5": { @@ -163,6 +164,7 @@ var Forks = map[string]*params.ChainConfig{ ConstantinopleBlock: big.NewInt(0), PetersburgBlock: big.NewInt(0), IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), BerlinBlock: big.NewInt(0), LondonBlock: big.NewInt(5), }, @@ -176,10 +178,11 @@ var Forks = map[string]*params.ChainConfig{ ConstantinopleBlock: big.NewInt(0), PetersburgBlock: big.NewInt(0), IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), BerlinBlock: big.NewInt(0), LondonBlock: big.NewInt(0), }, - "Aleut": { + "ArrowGlacier": { ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), EIP150Block: big.NewInt(0), @@ -189,8 +192,10 @@ var Forks = map[string]*params.ChainConfig{ ConstantinopleBlock: big.NewInt(0), PetersburgBlock: big.NewInt(0), IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), BerlinBlock: big.NewInt(0), LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), }, }