From 74253c88e37efc4379321b135a5652eb09faef03 Mon Sep 17 00:00:00 2001 From: Jamie Lokier Date: Fri, 10 Dec 2021 13:12:19 +0000 Subject: [PATCH] Arrow Glacier fork Add the new [Arrow Glacier fork](https://eips.ethereum.org/EIPS/eip-4345). Only the difficulty calculation is changed, but as a new fork it still affects a number of places in the code. To the best of my knowledge the change is only scheduled on Mainnet. In addition: - The fork date comments in `chain_config.nim` have been checked against the real networks, set consistently in UTC instead of random timezones, and made neater. Maybe we'll keep these when transferring config to a file someday. - It's added to forkid hash tests (EIP-2124/EIP-2364), of course. Signed-off-by: Jamie Lokier --- nimbus/chain_config.nim | 137 +++++++++++++++++--------------- nimbus/p2p/chain/chain_desc.nim | 10 ++- nimbus/p2p/chain/chain_misc.nim | 3 +- nimbus/utils/difficulty.nim | 23 +++++- tests/test_blockchain_json.nim | 1 + tests/test_forkid.nim | 6 +- tests/test_graphql.nim | 3 +- 7 files changed, 111 insertions(+), 72 deletions(-) diff --git a/nimbus/chain_config.nim b/nimbus/chain_config.nim index 2714eda11..c6680582a 100644 --- a/nimbus/chain_config.nim +++ b/nimbus/chain_config.nim @@ -38,6 +38,7 @@ type muirGlacierBlock : Option[BlockNumber] berlinBlock : Option[BlockNumber] londonBlock : Option[BlockNumber] + arrowGlacierBlock : Option[BlockNumber] clique : CliqueOptions ChainConfig* = object @@ -60,6 +61,7 @@ type muirGlacierBlock* : BlockNumber berlinBlock* : BlockNumber londonBlock* : BlockNumber + arrowGlacierBlock* : BlockNumber poaEngine* : bool cliquePeriod* : int @@ -202,7 +204,8 @@ proc loadNetworkParams*(fileName: string, cg: var NetworkParams): error "Forks can't be assigned out of order", fork=fork return false - validateFork(londonBlock, high(BlockNumber).toBlockNumber) + validateFork(arrowGlacierBlock, high(BlockNumber)) + validateFork(londonBlock, cg.config.arrowGlacierBlock) validateFork(berlinBlock, cg.config.londonBlock) validateFork(muirGlacierBlock, cg.config.berlinBlock) validateFork(istanbulBlock, cg.config.muirGlacierBlock) @@ -227,6 +230,7 @@ proc parseGenesisAlloc*(data: string, ga: var GenesisAlloc): bool = return true proc toFork*(c: ChainConfig, number: BlockNumber): Fork = + ## Map to EVM fork, which doesn't include the DAO or Glacier forks. if number >= c.londonBlock: FkLondon elif number >= c.berlinBlock: FkBerlin elif number >= c.istanbulBlock: FkIstanbul @@ -245,76 +249,85 @@ proc chainConfigForNetwork(id: NetworkId): ChainConfig = result = case id of MainNet: ChainConfig( - poaEngine: false, - chainId: MainNet.ChainId, - homesteadBlock: 1_150_000.toBlockNumber, # 14/03/2016 20:49:53 - daoForkBlock: 1_920_000.toBlockNumber, - daoForkSupport: true, - eip150Block: 2_463_000.toBlockNumber, # 18/10/2016 17:19:31 - eip150Hash: toDigest("2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), - eip155Block: 2_675_000.toBlockNumber, # 22/11/2016 18:15:44 - eip158Block: 2_675_000.toBlockNumber, - byzantiumBlock: 4_370_000.toBlockNumber, # 16/10/2017 09:22:11 - constantinopleBlock: 7_280_000.toBlockNumber, # Never Occured in MainNet - petersburgBlock:7_280_000.toBlockNumber, # 28/02/2019 07:52:04 - istanbulBlock: 9_069_000.toBlockNumber, # 08/12/2019 12:25:09 - muirGlacierBlock: 9_200_000.toBlockNumber, # 02/01/2020 08:30:49 - berlinBlock: 12_244_000.toBlockNumber, # 15/04/2021 10:07:03 - londonBlock: 12_965_000.toBlockNumber, # 05/08/2021 12:33:42 + poaEngine: false, + chainId: MainNet.ChainId, + # Genesis (Frontier): # 2015-07-30 15:26:13 UTC + # Frontier Thawing: 200_000.toBlockNumber, # 2015-09-07 21:33:09 UTC + homesteadBlock: 1_150_000.toBlockNumber, # 2016-03-14 18:49:53 UTC + daoForkBlock: 1_920_000.toBlockNumber, # 2016-07-20 13:20:40 UTC + daoForkSupport: true, + eip150Block: 2_463_000.toBlockNumber, # 2016-10-18 13:19:31 UTC + eip150Hash: toDigest("2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), + eip155Block: 2_675_000.toBlockNumber, # Same as EIP-158 + eip158Block: 2_675_000.toBlockNumber, # 2016-11-22 16:15:44 UTC + byzantiumBlock: 4_370_000.toBlockNumber, # 2017-10-16 05:22:11 UTC + constantinopleBlock: 7_280_000.toBlockNumber, # Skipped on Mainnet + petersburgBlock: 7_280_000.toBlockNumber, # 2019-02-28 19:52:04 UTC + istanbulBlock: 9_069_000.toBlockNumber, # 2019-12-08 00:25:09 UTC + muirGlacierBlock: 9_200_000.toBlockNumber, # 2020-01-02 08:30:49 UTC + berlinBlock: 12_244_000.toBlockNumber, # 2021-04-15 10:07:03 UTC + londonBlock: 12_965_000.toBlockNumber, # 2021-08-05 12:33:42 UTC + arrowGlacierBlock: 13_773_000.toBlockNumber, # 2021-12-09 19:55:23 UTC ) of RopstenNet: ChainConfig( - poaEngine: false, - chainId: RopstenNet.ChainId, - homesteadBlock: 0.toBlockNumber, - daoForkSupport: false, - eip150Block: 0.toBlockNumber, - eip150Hash: toDigest("41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"), - eip155Block: 10.toBlockNumber, - eip158Block: 10.toBlockNumber, - byzantiumBlock: 1_700_000.toBlockNumber, - constantinopleBlock: 4_230_000.toBlockNumber, - petersburgBlock:4_939_394.toBlockNumber, - istanbulBlock: 6_485_846.toBlockNumber, - muirGlacierBlock: 7_117_117.toBlockNumber, - berlinBlock: 9_812_189.toBlockNumber, - londonBlock: 10_499_401.toBlockNumber # June 24, 2021 + poaEngine: false, + chainId: RopstenNet.ChainId, + # Genesis: # 2016-11-20 11:48:50 UTC + homesteadBlock: 0.toBlockNumber, # Included in genesis + daoForkSupport: false, + eip150Block: 0.toBlockNumber, # Included in genesis + eip150Hash: toDigest("41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"), + eip155Block: 10.toBlockNumber, # Same as EIP-158 + eip158Block: 10.toBlockNumber, # 2016-11-20 11:50:44 UTC + byzantiumBlock: 1_700_000.toBlockNumber, # 2017-09-19 01:08:28 UTC + constantinopleBlock: 4_230_000.toBlockNumber, # 2018-10-13 17:19:06 UTC + petersburgBlock: 4_939_394.toBlockNumber, # 2019-02-02 07:39:08 UTC + istanbulBlock: 6_485_846.toBlockNumber, # 2019-09-30 03:38:06 UTC + muirGlacierBlock: 7_117_117.toBlockNumber, # 2020-01-13 06:37:37 UTC + berlinBlock: 9_812_189.toBlockNumber, # 2021-03-10 13:32:08 UTC + londonBlock: 10_499_401.toBlockNumber, # 2021-06-24 02:03:37 UTC + arrowGlacierBlock: high(BlockNumber), # No current plan ) of RinkebyNet: ChainConfig( - poaEngine: true, - chainId: RinkebyNet.ChainId, - homesteadBlock: 1.toBlockNumber, - daoForkSupport: false, - eip150Block: 2.toBlockNumber, - eip150Hash: toDigest("9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"), - eip155Block: 3.toBlockNumber, - eip158Block: 3.toBlockNumber, - byzantiumBlock: 1_035_301.toBlockNumber, - constantinopleBlock: 3_660_663.toBlockNumber, - petersburgBlock:4_321_234.toBlockNumber, - istanbulBlock: 5_435_345.toBlockNumber, - muirGlacierBlock: 8_290_928.toBlockNumber, # never occured in rinkeby network - berlinBlock: 8_290_928.toBlockNumber, - londonBlock: 8_897_988.toBlockNumber # July 7, 2021 + poaEngine: true, + chainId: RinkebyNet.ChainId, + # Genesis: # 2017-04-12 15:20:50 UTC + homesteadBlock: 1.toBlockNumber, # 2017-04-12 15:20:58 UTC + daoForkSupport: false, + eip150Block: 2.toBlockNumber, # 2017-04-12 15:21:14 UTC + eip150Hash: toDigest("9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"), + eip155Block: 3.toBlockNumber, # Same as EIP-158 + eip158Block: 3.toBlockNumber, # 2017-04-12 15:21:29 UTC + byzantiumBlock: 1_035_301.toBlockNumber, # 2017-10-09 12:08:23 UTC + constantinopleBlock: 3_660_663.toBlockNumber, # 2019-01-09 13:00:55 UTC + petersburgBlock: 4_321_234.toBlockNumber, # 2019-05-04 05:32:45 UTC + istanbulBlock: 5_435_345.toBlockNumber, # 2019-11-13 18:21:53 UTC + muirGlacierBlock: 8_290_928.toBlockNumber, # Skipped on Rinkeby + berlinBlock: 8_290_928.toBlockNumber, # 2021-03-24 14:48:36 UTC + londonBlock: 8_897_988.toBlockNumber, # 2021-07-08 01:27:32 UTC + arrowGlacierBlock: high(BlockNumber), # No current plan ) of GoerliNet: ChainConfig( - poaEngine: true, - chainId: GoerliNet.ChainId, - homesteadBlock: 0.toBlockNumber, - daoForkSupport: false, - eip150Block: 0.toBlockNumber, - eip150Hash: toDigest("0000000000000000000000000000000000000000000000000000000000000000"), - eip155Block: 0.toBlockNumber, - eip158Block: 0.toBlockNumber, - byzantiumBlock: 0.toBlockNumber, - constantinopleBlock: 0.toBlockNumber, - petersburgBlock: 0.toBlockNumber, - istanbulBlock: 1_561_651.toBlockNumber, - muirGlacierBlock: 4_460_644.toBlockNumber, # never occured in goerli network - berlinBlock: 4_460_644.toBlockNumber, - londonBlock: 5_062_605.toBlockNumber # June 30, 2021 + poaEngine: true, + chainId: GoerliNet.ChainId, + # Genesis: # 2015-07-30 15:26:13 UTC + homesteadBlock: 0.toBlockNumber, # Included in genesis + daoForkSupport: false, + eip150Block: 0.toBlockNumber, # Included in genesis + eip150Hash: toDigest("0000000000000000000000000000000000000000000000000000000000000000"), + eip155Block: 0.toBlockNumber, # Included in genesis + eip158Block: 0.toBlockNumber, # Included in genesis + byzantiumBlock: 0.toBlockNumber, # Included in genesis + constantinopleBlock: 0.toBlockNumber, # Included in genesis + petersburgBlock: 0.toBlockNumber, # Included in genesis + istanbulBlock: 1_561_651.toBlockNumber, # 2019-10-30 13:53:05 UTC + muirGlacierBlock: 4_460_644.toBlockNumber, # Skipped in Goerli + berlinBlock: 4_460_644.toBlockNumber, # 2021-03-18 05:29:51 UTC + londonBlock: 5_062_605.toBlockNumber, # 2021-07-01 03:19:39 UTC + arrowGlacierBlock: high(BlockNumber), # No current plan ) else: ChainConfig() diff --git a/nimbus/p2p/chain/chain_desc.nim b/nimbus/p2p/chain/chain_desc.nim index ec74fa9fe..916affe57 100644 --- a/nimbus/p2p/chain/chain_desc.nim +++ b/nimbus/p2p/chain/chain_desc.nim @@ -23,8 +23,10 @@ import stint type - # Chain's forks not always equals to EVM's forks ChainFork* = enum + ## `ChainFork` has extra forks not in the EVM fork list. These are the + ## unique `DAOFork`, and Glacier forks `MuirGlacier` and `ArrowGlacier`. + ## At the Glacier forks, only block difficulty calculation changed. Frontier, Homestead, DAOFork, @@ -36,7 +38,8 @@ type Istanbul, MuirGlacier, Berlin, - London + London, + ArrowGlacier Chain* = ref object of AbstractChainDB db: BaseChainDB @@ -85,7 +88,8 @@ func getNextFork(c: ChainConfig, fork: ChainFork): uint64 = toNextFork(c.istanbulBlock), toNextFork(c.muirGlacierBlock), toNextFork(c.berlinBlock), - toNextFork(c.londonBlock) + toNextFork(c.londonBlock), + toNextFork(c.arrowGlacierBlock) ] if fork == high(ChainFork): diff --git a/nimbus/p2p/chain/chain_misc.nim b/nimbus/p2p/chain/chain_misc.nim index eb502e7ee..3c9b54cb4 100644 --- a/nimbus/p2p/chain/chain_misc.nim +++ b/nimbus/p2p/chain/chain_misc.nim @@ -24,7 +24,8 @@ import # ------------------------------------------------------------------------------ func toChainFork(c: ChainConfig, number: BlockNumber): ChainFork = - if number >= c.londonBlock: London + if number >= c.arrowGlacierBlock: ArrowGlacier + elif number >= c.londonBlock: London elif number >= c.berlinBlock: Berlin elif number >= c.muirGlacierBlock: MuirGlacier elif number >= c.istanbulBlock: Istanbul diff --git a/nimbus/utils/difficulty.nim b/nimbus/utils/difficulty.nim index 4ba6e7ba7..56baef7cd 100644 --- a/nimbus/utils/difficulty.nim +++ b/nimbus/utils/difficulty.nim @@ -134,22 +134,39 @@ func makeDifficultyCalculator(bombDelay: static[int], timeStamp: EthTime, parent result = diff template calcDifficultyByzantium*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt = + ## "EIP-649: Metropolis Difficulty Bomb Delay and Block Reward Reduction" + ## makeDifficultyCalculator(3_000_000, timeStamp, parent) template calcDifficultyConstantinople*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt = + ## "EIP-1234: Constantinople Difficulty Bomb Delay and Block Reward Adjustment" + ## + ## Keep using Byzantium's rules but offset the bomb 5.0M blocks. makeDifficultyCalculator(5_000_000, timeStamp, parent) template calcDifficultyMuirGlacier*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt = - # EIP-2384 + ## "EIP-2384: Muir Glacier Difficulty Bomb Delay" + ## + ## Offset the bomb 4.0M more blocks than Constantinople, total 9.0M blocks. makeDifficultyCalculator(9_000_000, timeStamp, parent) template calcDifficultyLondon*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt = - # EIP-3554 + ## "EIP-3554: Difficulty Bomb Delay to December 2021" + ## + ## Offset the bomb a total of 9.7M blocks. makeDifficultyCalculator(9_700_000, timeStamp, parent) +template calcDifficultyArrowGlacier*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt = + ## "EIP-4345: Difficulty Bomb Delay to June 2022" + ## + ## Offset the bomb a total of 10.7M blocks. + makeDifficultyCalculator(10_700_000, timeStamp, parent) + func calcDifficulty*(c: ChainConfig, timeStamp: EthTime, parent: BlockHeader): DifficultyInt = let next = parent.blockNumber + bigOne - if next >= c.londonBlock: + if next >= c.arrowGlacierBlock: + result = calcDifficultyArrowGlacier(timeStamp, parent) + elif next >= c.londonBlock: result = calcDifficultyLondon(timeStamp, parent) elif next >= c.muirGlacierBlock: result = calcDifficultyMuirGlacier(timeStamp, parent) diff --git a/tests/test_blockchain_json.nim b/tests/test_blockchain_json.nim index 475a07fee..7d993d486 100644 --- a/tests/test_blockchain_json.nim +++ b/tests/test_blockchain_json.nim @@ -145,6 +145,7 @@ func vmConfiguration(network: string, c: var ChainConfig) = c.muirGlacierBlock = number[FkBerlin] c.berlinBlock = number[FkBerlin] c.londonBlock = number[FkLondon] + c.arrowGlacierBlock = number[FkLondon] case network of "EIP150": diff --git a/tests/test_forkid.nim b/tests/test_forkid.nim index 7b8e20a80..3ae73f91e 100644 --- a/tests/test_forkid.nim +++ b/tests/test_forkid.nim @@ -26,8 +26,10 @@ const (blockNumber: 12243999'u64, id: (crc: 0xE029E991'u32, nextFork: 12244000'u64)), # Last MuirGlacier block (blockNumber: 12244000'u64, id: (crc: 0x0eb440f6'u32, nextFork: 12965000'u64)), # First Berlin block (blockNumber: 12964999'u64, id: (crc: 0x0eb440f6'u32, nextFork: 12965000'u64)), # Last Berlin block - (blockNumber: 12965000'u64, id: (crc: 0xb715077d'u32, nextFork: 0'u64)), # First London block - (blockNumber: 20000000'u64, id: (crc: 0xb715077d'u32, nextFork: 0'u64)), # Future London block + (blockNumber: 12965000'u64, id: (crc: 0xb715077d'u32, nextFork: 13773000'u64)), # First London block + (blockNumber: 13772999'u64, id: (crc: 0xb715077d'u32, nextFork: 13773000'u64)), # Last London block + (blockNumber: 13773000'u64, id: (crc: 0x20c327fc'u32, nextFork: 0'u64)), # First Arrow Glacier block + (blockNumber: 20000000'u64, id: (crc: 0x20c327fc'u32, nextFork: 0'u64)), # Future Arrow Glacier block ] RopstenNetIDs = [ diff --git a/tests/test_graphql.nim b/tests/test_graphql.nim index a5f572561..75c096f20 100644 --- a/tests/test_graphql.nim +++ b/tests/test_graphql.nim @@ -40,7 +40,8 @@ proc setupChain(): BaseChainDB = istanbulBlock : 0.toBlockNumber, muirGlacierBlock : 0.toBlockNumber, berlinBlock : 10.toBlockNumber, - londonBlock : high(BlockNumber).toBlockNumber + londonBlock : high(BlockNumber), + arrowGlacierBlock : high(BlockNumber) ) var jn = json.parseFile(dataFolder / "oneUncle.json")