Skip to content

Commit 096383c

Browse files
holimanzzyalbert
authored andcommitted
cmd/geth, cmd/evm, params: implement Arrow Glacier (EIP 4345) (ethereum#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.
1 parent 8de35da commit 096383c

22 files changed

+158
-30
lines changed

cmd/evm/t8n_test.go

+33-1
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,45 @@ func TestT8n(t *testing.T) {
171171
output: t8nOutput{result: true},
172172
expOut: "exp2.json",
173173
},
174+
{ // Difficulty calculation - with uncles + Berlin
175+
base: "./testdata/14",
176+
input: t8nInput{
177+
"alloc.json", "txs.json", "env.uncles.json", "Berlin", "",
178+
},
179+
output: t8nOutput{result: true},
180+
expOut: "exp_berlin.json",
181+
},
182+
{ // Difficulty calculation on arrow glacier
183+
base: "./testdata/19",
184+
input: t8nInput{
185+
"alloc.json", "txs.json", "env.json", "London", "",
186+
},
187+
output: t8nOutput{result: true},
188+
expOut: "exp_london.json",
189+
},
190+
{ // Difficulty calculation on arrow glacier
191+
base: "./testdata/19",
192+
input: t8nInput{
193+
"alloc.json", "txs.json", "env.json", "ArrowGlacier", "",
194+
},
195+
output: t8nOutput{result: true},
196+
expOut: "exp_arrowglacier.json",
197+
},
174198
} {
175199

176200
args := []string{"t8n"}
177201
args = append(args, tc.output.get()...)
178202
args = append(args, tc.input.get(tc.base)...)
203+
var qArgs []string // quoted args for debugging purposes
204+
for _, arg := range args {
205+
if len(arg) == 0 {
206+
qArgs = append(qArgs, `""`)
207+
} else {
208+
qArgs = append(qArgs, arg)
209+
}
210+
}
211+
tt.Logf("args: %v\n", strings.Join(qArgs, " "))
179212
tt.Run("evm-test", args...)
180-
tt.Logf("args: %v\n", strings.Join(args, " "))
181213
// Compare the expected output, if provided
182214
if tc.expOut != "" {
183215
want, err := os.ReadFile(fmt.Sprintf("%v/%v", tc.base, tc.expOut))

cmd/evm/testdata/14/exp_berlin.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"result": {
3+
"stateRoot": "0x6f058887ca01549716789c380ede95aecc510e6d1fdc4dbf67d053c7c07f4bdc",
4+
"txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
5+
"receiptRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
6+
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
7+
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
8+
"receipts": [],
9+
"currentDifficulty": "0x1ff9000000000"
10+
}
11+
}

cmd/evm/testdata/19/alloc.json

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
3+
"balance": "0x5ffd4878be161d74",
4+
"code": "0x",
5+
"nonce": "0xac",
6+
"storage": {}
7+
},
8+
"0x8a8eafb1cf62bfbeb1741769dae1a9dd47996192":{
9+
"balance": "0xfeedbead",
10+
"nonce" : "0x00"
11+
}
12+
}

cmd/evm/testdata/19/env.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"currentCoinbase": "0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b",
3+
"currentGasLimit": "0x750a163df65e8a",
4+
"currentBaseFee": "0x500",
5+
"currentNumber": "13000000",
6+
"currentTimestamp": "100015",
7+
"parentTimestamp" : "99999",
8+
"parentDifficulty" : "0x2000000000000"
9+
}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"result": {
3+
"stateRoot": "0x6f058887ca01549716789c380ede95aecc510e6d1fdc4dbf67d053c7c07f4bdc",
4+
"txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
5+
"receiptRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
6+
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
7+
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
8+
"currentDifficulty": "0x2000000200000",
9+
"receipts": []
10+
}
11+
}

cmd/evm/testdata/19/exp_london.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"result": {
3+
"stateRoot": "0x6f058887ca01549716789c380ede95aecc510e6d1fdc4dbf67d053c7c07f4bdc",
4+
"txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
5+
"receiptRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
6+
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
7+
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
8+
"currentDifficulty": "0x2000080000000",
9+
"receipts": []
10+
}
11+
}

cmd/evm/testdata/19/readme.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
## Difficulty calculation
2+
3+
This test shows how the `evm t8n` can be used to calculate the (ethash) difficulty, if none is provided by the caller,
4+
this time on `ArrowGlacier` (Eip 4345).
5+
6+
Calculating it (with an empty set of txs) using `ArrowGlacier` rules (and no provided unclehash for the parent block):
7+
```
8+
[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
9+
```

cmd/evm/testdata/19/txs.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]

cmd/geth/config.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
158158
// makeFullNode loads geth configuration and creates the Ethereum backend.
159159
func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
160160
stack, cfg := makeConfigNode(ctx)
161-
if ctx.GlobalIsSet(utils.OverrideLondonFlag.Name) {
162-
cfg.Eth.OverrideLondon = new(big.Int).SetUint64(ctx.GlobalUint64(utils.OverrideLondonFlag.Name))
161+
if ctx.GlobalIsSet(utils.OverrideArrowGlacierFlag.Name) {
162+
cfg.Eth.OverrideArrowGlacier = new(big.Int).SetUint64(ctx.GlobalUint64(utils.OverrideArrowGlacierFlag.Name))
163163
}
164164
backend, eth := utils.RegisterEthService(stack, &cfg.Eth)
165165
debug.ID = enode.PubkeyToIDV4(&cfg.Node.NodeKey().PublicKey).TerminalString()

cmd/geth/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ var (
6666
utils.NoUSBFlag,
6767
utils.USBFlag,
6868
utils.SmartCardDaemonPathFlag,
69-
utils.OverrideLondonFlag,
69+
utils.OverrideArrowGlacierFlag,
7070
utils.EthashCacheDirFlag,
7171
utils.EthashCachesInMemoryFlag,
7272
utils.EthashCachesOnDiskFlag,

cmd/utils/flags.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,9 @@ var (
227227
Usage: "Megabytes of memory allocated to bloom-filter for pruning",
228228
Value: 2048,
229229
}
230-
OverrideLondonFlag = cli.Uint64Flag{
231-
Name: "override.london",
232-
Usage: "Manually specify London fork-block, overriding the bundled setting",
230+
OverrideArrowGlacierFlag = cli.Uint64Flag{
231+
Name: "override.arrowglacier",
232+
Usage: "Manually specify Arrow Glacier fork-block, overriding the bundled setting",
233233
}
234234
// Light server and client settings
235235
LightServeFlag = cli.IntFlag{

consensus/ethash/consensus.go

+7
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ var (
4545
maxUncles = 2 // Maximum number of uncles allowed in a single block
4646
allowedFutureBlockTimeSeconds = int64(15) // Max seconds from current time allowed for blocks, before they're considered future blocks
4747

48+
// calcDifficultyEip4345 is the difficulty adjustment algorithm as specified by EIP 4345.
49+
// It offsets the bomb a total of 10.7M blocks.
50+
// Specification EIP-4345: https://eips.ethereum.org/EIPS/eip-4345
51+
calcDifficultyEip4345 = makeDifficultyCalculator(big.NewInt(10_700_000))
52+
4853
// calcDifficultyEip3554 is the difficulty adjustment algorithm as specified by EIP 3554.
4954
// It offsets the bomb a total of 9.7M blocks.
5055
// Specification EIP-3554: https://eips.ethereum.org/EIPS/eip-3554
@@ -330,6 +335,8 @@ func (ethash *Ethash) CalcDifficulty(chain consensus.ChainHeaderReader, time uin
330335
func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Header) *big.Int {
331336
next := new(big.Int).Add(parent.Number, big1)
332337
switch {
338+
case config.IsArrowGlacier(next):
339+
return calcDifficultyEip4345(time, parent)
333340
case config.IsLondon(next):
334341
return calcDifficultyEip3554(time, parent)
335342
case config.IsMuirGlacier(next):

core/forkid/forkid_test.go

+6-4
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,10 @@ func TestCreation(t *testing.T) {
6363
{12243999, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // Last Muir Glacier block
6464
{12244000, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // First Berlin block
6565
{12964999, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // Last Berlin block
66-
{12965000, ID{Hash: checksumToBytes(0xb715077d), Next: 0}}, // First London block
67-
{20000000, ID{Hash: checksumToBytes(0xb715077d), Next: 0}}, // Future London block
66+
{12965000, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // First London block
67+
{13772999, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // Last London block
68+
{13773000, ID{Hash: checksumToBytes(0x20c327fc), Next: 0}}, /// First Arrow Glacier block
69+
{20000000, ID{Hash: checksumToBytes(0x20c327fc), Next: 0}}, // Future Arrow Glacier block
6870
},
6971
},
7072
}
@@ -141,11 +143,11 @@ func TestValidation(t *testing.T) {
141143
// Local is mainnet Petersburg, remote is Rinkeby Petersburg.
142144
{7987396, ID{Hash: checksumToBytes(0xafec6b27), Next: 0}, ErrLocalIncompatibleOrStale},
143145

144-
// Local is mainnet London, far in the future. Remote announces Gopherium (non existing fork)
146+
// Local is mainnet Arrow Glacier, far in the future. Remote announces Gopherium (non existing fork)
145147
// at some future block 88888888, for itself, but past block for local. Local is incompatible.
146148
//
147149
// This case detects non-upgraded nodes with majority hash power (typical Ropsten mess).
148-
{88888888, ID{Hash: checksumToBytes(0xb715077d), Next: 88888888}, ErrLocalIncompatibleOrStale},
150+
{88888888, ID{Hash: checksumToBytes(0x20c327fc), Next: 88888888}, ErrLocalIncompatibleOrStale},
149151

150152
// Local is mainnet Byzantium. Remote is also in Byzantium, but announces Gopherium (non existing
151153
// fork) at block 7279999, before Petersburg. Local is incompatible.

core/genesis.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig
158158
return SetupGenesisBlockWithOverride(db, genesis, nil)
159159
}
160160

161-
func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, overrideLondon *big.Int) (*params.ChainConfig, common.Hash, error) {
161+
func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, overrideArrowGlacier *big.Int) (*params.ChainConfig, common.Hash, error) {
162162
if genesis != nil && genesis.Config == nil {
163163
return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig
164164
}
@@ -204,8 +204,8 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override
204204
}
205205
// Get the existing chain configuration.
206206
newcfg := genesis.configOrDefault(stored)
207-
if overrideLondon != nil {
208-
newcfg.LondonBlock = overrideLondon
207+
if overrideArrowGlacier != nil {
208+
newcfg.ArrowGlacierBlock = overrideArrowGlacier
209209
}
210210
if err := newcfg.CheckConfigForkOrder(); err != nil {
211211
return newcfg, common.Hash{}, err

eth/backend.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
135135
if err != nil {
136136
return nil, err
137137
}
138-
chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideLondon)
138+
chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideArrowGlacier)
139139
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
140140
return nil, genesisErr
141141
}

eth/ethconfig/config.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,8 @@ type Config struct {
220220
// CheckpointOracle is the configuration for checkpoint oracle.
221221
CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"`
222222

223-
// Berlin block override (TODO: remove after the fork)
224-
OverrideLondon *big.Int `toml:",omitempty"`
223+
// Arrow Glacier block override (TODO: remove after the fork)
224+
OverrideArrowGlacier *big.Int `toml:",omitempty"`
225225
}
226226

227227
// CreateConsensusEngine creates a consensus engine for the given chain configuration.

eth/ethconfig/gen_config.go

+5-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

eth/gasprice/gasprice_test.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,13 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke
107107
signer = types.LatestSigner(gspec.Config)
108108
)
109109
config.LondonBlock = londonBlock
110+
config.ArrowGlacierBlock = londonBlock
110111
engine := ethash.NewFaker()
111112
db := rawdb.NewMemoryDatabase()
112-
genesis, _ := gspec.Commit(db)
113-
113+
genesis, err := gspec.Commit(db)
114+
if err != nil {
115+
t.Fatal(err)
116+
}
114117
// Generate testing blocks
115118
blocks, _ := core.GenerateChain(gspec.Config, genesis, engine, db, testHead+1, func(i int, b *core.BlockGen) {
116119
b.SetCoinbase(common.Address{1})

les/client.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*LightEthereum, error) {
8888
if err != nil {
8989
return nil, err
9090
}
91-
chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideLondon)
91+
chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideArrowGlacier)
9292
if _, isCompat := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !isCompat {
9393
return nil, genesisErr
9494
}

0 commit comments

Comments
 (0)