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 <jamie@shareable.org>
This commit is contained in:
Jamie Lokier 2021-12-10 13:12:19 +00:00
parent 55f7a4425f
commit 74253c88e3
No known key found for this signature in database
GPG Key ID: CBC25C68435C30A2
7 changed files with 111 additions and 72 deletions

View File

@ -38,6 +38,7 @@ type
muirGlacierBlock : Option[BlockNumber] muirGlacierBlock : Option[BlockNumber]
berlinBlock : Option[BlockNumber] berlinBlock : Option[BlockNumber]
londonBlock : Option[BlockNumber] londonBlock : Option[BlockNumber]
arrowGlacierBlock : Option[BlockNumber]
clique : CliqueOptions clique : CliqueOptions
ChainConfig* = object ChainConfig* = object
@ -60,6 +61,7 @@ type
muirGlacierBlock* : BlockNumber muirGlacierBlock* : BlockNumber
berlinBlock* : BlockNumber berlinBlock* : BlockNumber
londonBlock* : BlockNumber londonBlock* : BlockNumber
arrowGlacierBlock* : BlockNumber
poaEngine* : bool poaEngine* : bool
cliquePeriod* : int cliquePeriod* : int
@ -202,7 +204,8 @@ proc loadNetworkParams*(fileName: string, cg: var NetworkParams):
error "Forks can't be assigned out of order", fork=fork error "Forks can't be assigned out of order", fork=fork
return false return false
validateFork(londonBlock, high(BlockNumber).toBlockNumber) validateFork(arrowGlacierBlock, high(BlockNumber))
validateFork(londonBlock, cg.config.arrowGlacierBlock)
validateFork(berlinBlock, cg.config.londonBlock) validateFork(berlinBlock, cg.config.londonBlock)
validateFork(muirGlacierBlock, cg.config.berlinBlock) validateFork(muirGlacierBlock, cg.config.berlinBlock)
validateFork(istanbulBlock, cg.config.muirGlacierBlock) validateFork(istanbulBlock, cg.config.muirGlacierBlock)
@ -227,6 +230,7 @@ proc parseGenesisAlloc*(data: string, ga: var GenesisAlloc): bool =
return true return true
proc toFork*(c: ChainConfig, number: BlockNumber): Fork = 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 if number >= c.londonBlock: FkLondon
elif number >= c.berlinBlock: FkBerlin elif number >= c.berlinBlock: FkBerlin
elif number >= c.istanbulBlock: FkIstanbul elif number >= c.istanbulBlock: FkIstanbul
@ -247,74 +251,83 @@ proc chainConfigForNetwork(id: NetworkId): ChainConfig =
ChainConfig( ChainConfig(
poaEngine: false, poaEngine: false,
chainId: MainNet.ChainId, chainId: MainNet.ChainId,
homesteadBlock: 1_150_000.toBlockNumber, # 14/03/2016 20:49:53 # Genesis (Frontier): # 2015-07-30 15:26:13 UTC
daoForkBlock: 1_920_000.toBlockNumber, # 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, daoForkSupport: true,
eip150Block: 2_463_000.toBlockNumber, # 18/10/2016 17:19:31 eip150Block: 2_463_000.toBlockNumber, # 2016-10-18 13:19:31 UTC
eip150Hash: toDigest("2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), eip150Hash: toDigest("2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
eip155Block: 2_675_000.toBlockNumber, # 22/11/2016 18:15:44 eip155Block: 2_675_000.toBlockNumber, # Same as EIP-158
eip158Block: 2_675_000.toBlockNumber, eip158Block: 2_675_000.toBlockNumber, # 2016-11-22 16:15:44 UTC
byzantiumBlock: 4_370_000.toBlockNumber, # 16/10/2017 09:22:11 byzantiumBlock: 4_370_000.toBlockNumber, # 2017-10-16 05:22:11 UTC
constantinopleBlock: 7_280_000.toBlockNumber, # Never Occured in MainNet constantinopleBlock: 7_280_000.toBlockNumber, # Skipped on Mainnet
petersburgBlock:7_280_000.toBlockNumber, # 28/02/2019 07:52:04 petersburgBlock: 7_280_000.toBlockNumber, # 2019-02-28 19:52:04 UTC
istanbulBlock: 9_069_000.toBlockNumber, # 08/12/2019 12:25:09 istanbulBlock: 9_069_000.toBlockNumber, # 2019-12-08 00:25:09 UTC
muirGlacierBlock: 9_200_000.toBlockNumber, # 02/01/2020 08:30:49 muirGlacierBlock: 9_200_000.toBlockNumber, # 2020-01-02 08:30:49 UTC
berlinBlock: 12_244_000.toBlockNumber, # 15/04/2021 10:07:03 berlinBlock: 12_244_000.toBlockNumber, # 2021-04-15 10:07:03 UTC
londonBlock: 12_965_000.toBlockNumber, # 05/08/2021 12:33:42 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: of RopstenNet:
ChainConfig( ChainConfig(
poaEngine: false, poaEngine: false,
chainId: RopstenNet.ChainId, chainId: RopstenNet.ChainId,
homesteadBlock: 0.toBlockNumber, # Genesis: # 2016-11-20 11:48:50 UTC
homesteadBlock: 0.toBlockNumber, # Included in genesis
daoForkSupport: false, daoForkSupport: false,
eip150Block: 0.toBlockNumber, eip150Block: 0.toBlockNumber, # Included in genesis
eip150Hash: toDigest("41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"), eip150Hash: toDigest("41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"),
eip155Block: 10.toBlockNumber, eip155Block: 10.toBlockNumber, # Same as EIP-158
eip158Block: 10.toBlockNumber, eip158Block: 10.toBlockNumber, # 2016-11-20 11:50:44 UTC
byzantiumBlock: 1_700_000.toBlockNumber, byzantiumBlock: 1_700_000.toBlockNumber, # 2017-09-19 01:08:28 UTC
constantinopleBlock: 4_230_000.toBlockNumber, constantinopleBlock: 4_230_000.toBlockNumber, # 2018-10-13 17:19:06 UTC
petersburgBlock:4_939_394.toBlockNumber, petersburgBlock: 4_939_394.toBlockNumber, # 2019-02-02 07:39:08 UTC
istanbulBlock: 6_485_846.toBlockNumber, istanbulBlock: 6_485_846.toBlockNumber, # 2019-09-30 03:38:06 UTC
muirGlacierBlock: 7_117_117.toBlockNumber, muirGlacierBlock: 7_117_117.toBlockNumber, # 2020-01-13 06:37:37 UTC
berlinBlock: 9_812_189.toBlockNumber, berlinBlock: 9_812_189.toBlockNumber, # 2021-03-10 13:32:08 UTC
londonBlock: 10_499_401.toBlockNumber # June 24, 2021 londonBlock: 10_499_401.toBlockNumber, # 2021-06-24 02:03:37 UTC
arrowGlacierBlock: high(BlockNumber), # No current plan
) )
of RinkebyNet: of RinkebyNet:
ChainConfig( ChainConfig(
poaEngine: true, poaEngine: true,
chainId: RinkebyNet.ChainId, chainId: RinkebyNet.ChainId,
homesteadBlock: 1.toBlockNumber, # Genesis: # 2017-04-12 15:20:50 UTC
homesteadBlock: 1.toBlockNumber, # 2017-04-12 15:20:58 UTC
daoForkSupport: false, daoForkSupport: false,
eip150Block: 2.toBlockNumber, eip150Block: 2.toBlockNumber, # 2017-04-12 15:21:14 UTC
eip150Hash: toDigest("9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"), eip150Hash: toDigest("9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"),
eip155Block: 3.toBlockNumber, eip155Block: 3.toBlockNumber, # Same as EIP-158
eip158Block: 3.toBlockNumber, eip158Block: 3.toBlockNumber, # 2017-04-12 15:21:29 UTC
byzantiumBlock: 1_035_301.toBlockNumber, byzantiumBlock: 1_035_301.toBlockNumber, # 2017-10-09 12:08:23 UTC
constantinopleBlock: 3_660_663.toBlockNumber, constantinopleBlock: 3_660_663.toBlockNumber, # 2019-01-09 13:00:55 UTC
petersburgBlock:4_321_234.toBlockNumber, petersburgBlock: 4_321_234.toBlockNumber, # 2019-05-04 05:32:45 UTC
istanbulBlock: 5_435_345.toBlockNumber, istanbulBlock: 5_435_345.toBlockNumber, # 2019-11-13 18:21:53 UTC
muirGlacierBlock: 8_290_928.toBlockNumber, # never occured in rinkeby network muirGlacierBlock: 8_290_928.toBlockNumber, # Skipped on Rinkeby
berlinBlock: 8_290_928.toBlockNumber, berlinBlock: 8_290_928.toBlockNumber, # 2021-03-24 14:48:36 UTC
londonBlock: 8_897_988.toBlockNumber # July 7, 2021 londonBlock: 8_897_988.toBlockNumber, # 2021-07-08 01:27:32 UTC
arrowGlacierBlock: high(BlockNumber), # No current plan
) )
of GoerliNet: of GoerliNet:
ChainConfig( ChainConfig(
poaEngine: true, poaEngine: true,
chainId: GoerliNet.ChainId, chainId: GoerliNet.ChainId,
homesteadBlock: 0.toBlockNumber, # Genesis: # 2015-07-30 15:26:13 UTC
homesteadBlock: 0.toBlockNumber, # Included in genesis
daoForkSupport: false, daoForkSupport: false,
eip150Block: 0.toBlockNumber, eip150Block: 0.toBlockNumber, # Included in genesis
eip150Hash: toDigest("0000000000000000000000000000000000000000000000000000000000000000"), eip150Hash: toDigest("0000000000000000000000000000000000000000000000000000000000000000"),
eip155Block: 0.toBlockNumber, eip155Block: 0.toBlockNumber, # Included in genesis
eip158Block: 0.toBlockNumber, eip158Block: 0.toBlockNumber, # Included in genesis
byzantiumBlock: 0.toBlockNumber, byzantiumBlock: 0.toBlockNumber, # Included in genesis
constantinopleBlock: 0.toBlockNumber, constantinopleBlock: 0.toBlockNumber, # Included in genesis
petersburgBlock: 0.toBlockNumber, petersburgBlock: 0.toBlockNumber, # Included in genesis
istanbulBlock: 1_561_651.toBlockNumber, istanbulBlock: 1_561_651.toBlockNumber, # 2019-10-30 13:53:05 UTC
muirGlacierBlock: 4_460_644.toBlockNumber, # never occured in goerli network muirGlacierBlock: 4_460_644.toBlockNumber, # Skipped in Goerli
berlinBlock: 4_460_644.toBlockNumber, berlinBlock: 4_460_644.toBlockNumber, # 2021-03-18 05:29:51 UTC
londonBlock: 5_062_605.toBlockNumber # June 30, 2021 londonBlock: 5_062_605.toBlockNumber, # 2021-07-01 03:19:39 UTC
arrowGlacierBlock: high(BlockNumber), # No current plan
) )
else: else:
ChainConfig() ChainConfig()

View File

@ -23,8 +23,10 @@ import
stint stint
type type
# Chain's forks not always equals to EVM's forks
ChainFork* = enum 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, Frontier,
Homestead, Homestead,
DAOFork, DAOFork,
@ -36,7 +38,8 @@ type
Istanbul, Istanbul,
MuirGlacier, MuirGlacier,
Berlin, Berlin,
London London,
ArrowGlacier
Chain* = ref object of AbstractChainDB Chain* = ref object of AbstractChainDB
db: BaseChainDB db: BaseChainDB
@ -85,7 +88,8 @@ func getNextFork(c: ChainConfig, fork: ChainFork): uint64 =
toNextFork(c.istanbulBlock), toNextFork(c.istanbulBlock),
toNextFork(c.muirGlacierBlock), toNextFork(c.muirGlacierBlock),
toNextFork(c.berlinBlock), toNextFork(c.berlinBlock),
toNextFork(c.londonBlock) toNextFork(c.londonBlock),
toNextFork(c.arrowGlacierBlock)
] ]
if fork == high(ChainFork): if fork == high(ChainFork):

View File

@ -24,7 +24,8 @@ import
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func toChainFork(c: ChainConfig, number: BlockNumber): ChainFork = 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.berlinBlock: Berlin
elif number >= c.muirGlacierBlock: MuirGlacier elif number >= c.muirGlacierBlock: MuirGlacier
elif number >= c.istanbulBlock: Istanbul elif number >= c.istanbulBlock: Istanbul

View File

@ -134,22 +134,39 @@ func makeDifficultyCalculator(bombDelay: static[int], timeStamp: EthTime, parent
result = diff result = diff
template calcDifficultyByzantium*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt = template calcDifficultyByzantium*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
## "EIP-649: Metropolis Difficulty Bomb Delay and Block Reward Reduction"
## <https://eips.ethereum.org/EIPS/eip-649>
makeDifficultyCalculator(3_000_000, timeStamp, parent) makeDifficultyCalculator(3_000_000, timeStamp, parent)
template calcDifficultyConstantinople*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt = template calcDifficultyConstantinople*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
## "EIP-1234: Constantinople Difficulty Bomb Delay and Block Reward Adjustment"
## <https://eips.ethereum.org/EIPS/eip-1234>
## Keep using Byzantium's rules but offset the bomb 5.0M blocks.
makeDifficultyCalculator(5_000_000, timeStamp, parent) makeDifficultyCalculator(5_000_000, timeStamp, parent)
template calcDifficultyMuirGlacier*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt = template calcDifficultyMuirGlacier*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
# EIP-2384 ## "EIP-2384: Muir Glacier Difficulty Bomb Delay"
## <https://eips.ethereum.org/EIPS/eip-2384>
## Offset the bomb 4.0M more blocks than Constantinople, total 9.0M blocks.
makeDifficultyCalculator(9_000_000, timeStamp, parent) makeDifficultyCalculator(9_000_000, timeStamp, parent)
template calcDifficultyLondon*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt = template calcDifficultyLondon*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
# EIP-3554 ## "EIP-3554: Difficulty Bomb Delay to December 2021"
## <https://eips.ethereum.org/EIPS/eip-3554>
## Offset the bomb a total of 9.7M blocks.
makeDifficultyCalculator(9_700_000, timeStamp, parent) makeDifficultyCalculator(9_700_000, timeStamp, parent)
template calcDifficultyArrowGlacier*(timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
## "EIP-4345: Difficulty Bomb Delay to June 2022"
## <https://eips.ethereum.org/EIPS/eip-4345>
## Offset the bomb a total of 10.7M blocks.
makeDifficultyCalculator(10_700_000, timeStamp, parent)
func calcDifficulty*(c: ChainConfig, timeStamp: EthTime, parent: BlockHeader): DifficultyInt = func calcDifficulty*(c: ChainConfig, timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
let next = parent.blockNumber + bigOne 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) result = calcDifficultyLondon(timeStamp, parent)
elif next >= c.muirGlacierBlock: elif next >= c.muirGlacierBlock:
result = calcDifficultyMuirGlacier(timeStamp, parent) result = calcDifficultyMuirGlacier(timeStamp, parent)

View File

@ -145,6 +145,7 @@ func vmConfiguration(network: string, c: var ChainConfig) =
c.muirGlacierBlock = number[FkBerlin] c.muirGlacierBlock = number[FkBerlin]
c.berlinBlock = number[FkBerlin] c.berlinBlock = number[FkBerlin]
c.londonBlock = number[FkLondon] c.londonBlock = number[FkLondon]
c.arrowGlacierBlock = number[FkLondon]
case network case network
of "EIP150": of "EIP150":

View File

@ -26,8 +26,10 @@ const
(blockNumber: 12243999'u64, id: (crc: 0xE029E991'u32, nextFork: 12244000'u64)), # Last MuirGlacier block (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: 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: 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: 12965000'u64, id: (crc: 0xb715077d'u32, nextFork: 13773000'u64)), # First London block
(blockNumber: 20000000'u64, id: (crc: 0xb715077d'u32, nextFork: 0'u64)), # Future 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 = [ RopstenNetIDs = [

View File

@ -40,7 +40,8 @@ proc setupChain(): BaseChainDB =
istanbulBlock : 0.toBlockNumber, istanbulBlock : 0.toBlockNumber,
muirGlacierBlock : 0.toBlockNumber, muirGlacierBlock : 0.toBlockNumber,
berlinBlock : 10.toBlockNumber, berlinBlock : 10.toBlockNumber,
londonBlock : high(BlockNumber).toBlockNumber londonBlock : high(BlockNumber),
arrowGlacierBlock : high(BlockNumber)
) )
var jn = json.parseFile(dataFolder / "oneUncle.json") var jn = json.parseFile(dataFolder / "oneUncle.json")