cmd/geth, cmd/evm, params: implement Arrow Glacier (EIP 4345) (#23810)
This PR adds support for ArrowGlacier, as defined by https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/arrow-glacier.md https://eips.ethereum.org/EIPS/eip-4345 > Starting with FORK_BLOCK_NUMBER the client will calculate the difficulty based on a fake block number suggesting to the client that the difficulty bomb is adjusting 10,700,000 blocks later than the actual block number. This also adds support for evm t8n to return the calculated difficulty, so it can be used to construct test.
This commit is contained in:
parent
bff330335b
commit
32150f8aa9
@ -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))
|
||||
|
11
cmd/evm/testdata/14/exp_berlin.json
vendored
Normal file
11
cmd/evm/testdata/14/exp_berlin.json
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"result": {
|
||||
"stateRoot": "0x6f058887ca01549716789c380ede95aecc510e6d1fdc4dbf67d053c7c07f4bdc",
|
||||
"txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"receiptRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"receipts": [],
|
||||
"currentDifficulty": "0x1ff9000000000"
|
||||
}
|
||||
}
|
12
cmd/evm/testdata/19/alloc.json
vendored
Normal file
12
cmd/evm/testdata/19/alloc.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||
"balance": "0x5ffd4878be161d74",
|
||||
"code": "0x",
|
||||
"nonce": "0xac",
|
||||
"storage": {}
|
||||
},
|
||||
"0x8a8eafb1cf62bfbeb1741769dae1a9dd47996192":{
|
||||
"balance": "0xfeedbead",
|
||||
"nonce" : "0x00"
|
||||
}
|
||||
}
|
9
cmd/evm/testdata/19/env.json
vendored
Normal file
9
cmd/evm/testdata/19/env.json
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"currentCoinbase": "0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"currentGasLimit": "0x750a163df65e8a",
|
||||
"currentBaseFee": "0x500",
|
||||
"currentNumber": "13000000",
|
||||
"currentTimestamp": "100015",
|
||||
"parentTimestamp" : "99999",
|
||||
"parentDifficulty" : "0x2000000000000"
|
||||
}
|
11
cmd/evm/testdata/19/exp_arrowglacier.json
vendored
Normal file
11
cmd/evm/testdata/19/exp_arrowglacier.json
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"result": {
|
||||
"stateRoot": "0x6f058887ca01549716789c380ede95aecc510e6d1fdc4dbf67d053c7c07f4bdc",
|
||||
"txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"receiptRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"currentDifficulty": "0x2000000200000",
|
||||
"receipts": []
|
||||
}
|
||||
}
|
11
cmd/evm/testdata/19/exp_london.json
vendored
Normal file
11
cmd/evm/testdata/19/exp_london.json
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"result": {
|
||||
"stateRoot": "0x6f058887ca01549716789c380ede95aecc510e6d1fdc4dbf67d053c7c07f4bdc",
|
||||
"txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"receiptRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"currentDifficulty": "0x2000080000000",
|
||||
"receipts": []
|
||||
}
|
||||
}
|
9
cmd/evm/testdata/19/readme.md
vendored
Normal file
9
cmd/evm/testdata/19/readme.md
vendored
Normal file
@ -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
|
||||
```
|
1
cmd/evm/testdata/19/txs.json
vendored
Normal file
1
cmd/evm/testdata/19/txs.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
[]
|
@ -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)
|
||||
|
||||
|
@ -66,7 +66,7 @@ var (
|
||||
utils.NoUSBFlag,
|
||||
utils.USBFlag,
|
||||
utils.SmartCardDaemonPathFlag,
|
||||
utils.OverrideLondonFlag,
|
||||
utils.OverrideArrowGlacierFlag,
|
||||
utils.EthashCacheDirFlag,
|
||||
utils.EthashCachesInMemoryFlag,
|
||||
utils.EthashCachesOnDiskFlag,
|
||||
|
@ -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{
|
||||
|
@ -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):
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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})
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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),
|
||||
},
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user