preparation for London hard fork

This preparation is needed for subsequent
EIPs included in London.

- Add London to Fork enum
- Block number to fork
- Parsing London fork in chain config
- Prepare gas costs table for London
- Prepare EVM opcode dispatcher for London
- Block rewards for London
- Prepare hive script for London
This commit is contained in:
jangko 2021-06-28 09:01:18 +07:00
parent b5de442d33
commit 5159ad7aac
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
14 changed files with 58 additions and 18 deletions

View File

@ -64,5 +64,6 @@ def to_bool:
"istanbulBlock": env.HIVE_FORK_ISTANBUL|to_int,
"muirGlacierBlock": env.HIVE_FORK_MUIR_GLACIER|to_int,
"berlinBlock": env.HIVE_FORK_BERLIN|to_int
"londonBlock": env.HIVE_FORK_LONDON|to_int
}|remove_empty
}

View File

@ -30,6 +30,7 @@
# - [x] HIVE_FORK_ISTANBUL block number for Istanbul transition
# - [x] HIVE_FORK_MUIRGLACIER block number for Muir Glacier transition
# - [x] HIVE_FORK_BERLIN block number for Berlin transition
# - [x] HIVE_FORK_LONDON block number for London transition
#
# Clique PoA:
#

View File

@ -32,6 +32,7 @@ type
istanbulBlock : Option[BlockNumber]
muirGlacierBlock : Option[BlockNumber]
berlinBlock : Option[BlockNumber]
londonBlock : Option[BlockNumber]
ChainConfig* = object
chainId* : ChainId
@ -52,6 +53,7 @@ type
istanbulBlock* : BlockNumber
muirGlacierBlock* : BlockNumber
berlinBlock* : BlockNumber
londonBlock* : BlockNumber
# TODO: this need to be fixed somehow
# using `real` engine configuration
@ -174,7 +176,8 @@ proc loadCustomGenesis*(fileName: string, cg: var CustomGenesis): bool =
error "Forks can't be assigned out of order", fork=fork
return false
validateFork(berlinBlock, high(BlockNumber).toBlockNumber)
validateFork(londonBlock, high(BlockNumber).toBlockNumber)
validateFork(berlinBlock, cg.config.londonBlock)
validateFork(muirGlacierBlock, cg.config.berlinBlock)
validateFork(istanbulBlock, cg.config.muirGlacierBlock)
validateFork(petersburgBlock, cg.config.istanbulBlock)

View File

@ -159,7 +159,8 @@ proc `$`*(c: ChainId): string =
$(c.int)
proc toFork*(c: ChainConfig, number: BlockNumber): Fork =
if number >= c.berlinBlock: FkBerlin
if number >= c.londonBlock: FkLondon
elif number >= c.berlinBlock: FkBerlin
elif number >= c.istanbulBlock: FkIstanbul
elif number >= c.petersburgBlock: FkPetersburg
elif number >= c.constantinopleBlock: FkConstantinople
@ -190,7 +191,8 @@ proc chainConfig*(id: NetworkId): ChainConfig =
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
berlinBlock: 12_244_000.toBlockNumber, # 15/04/2021 10:07:03
londonBlock: high(BlockNumber)
)
of RopstenNet:
ChainConfig(
@ -207,7 +209,8 @@ proc chainConfig*(id: NetworkId): ChainConfig =
petersburgBlock:4_939_394.toBlockNumber,
istanbulBlock: 6_485_846.toBlockNumber,
muirGlacierBlock: 7_117_117.toBlockNumber,
berlinBlock: 9_812_189.toBlockNumber
berlinBlock: 9_812_189.toBlockNumber,
londonBlock: high(BlockNumber)
)
of RinkebyNet:
ChainConfig(
@ -224,7 +227,8 @@ proc chainConfig*(id: NetworkId): ChainConfig =
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
berlinBlock: 8_290_928.toBlockNumber,
londonBlock: high(BlockNumber)
)
of GoerliNet:
ChainConfig(
@ -241,7 +245,8 @@ proc chainConfig*(id: NetworkId): ChainConfig =
petersburgBlock: 0.toBlockNumber,
istanbulBlock: 1_561_651.toBlockNumber,
muirGlacierBlock: 4_460_644.toBlockNumber, # never occured in goerli network
berlinBlock: 4_460_644.toBlockNumber
berlinBlock: 4_460_644.toBlockNumber,
londonBlock: high(BlockNumber)
)
else:
# everything else will use CustomNet config

View File

@ -17,3 +17,4 @@ type
FkPetersburg = "Petersburg"
FkIstanbul = "Istanbul"
FkBerlin = "Berlin"
FkLondon = "London"

View File

@ -30,7 +30,8 @@ type
Petersburg,
Istanbul,
MuirGlacier,
Berlin
Berlin,
London
Chain* = ref object of AbstractChainDB
db: BaseChainDB
@ -40,7 +41,8 @@ type
extraValidation: bool
func toChainFork(c: ChainConfig, number: BlockNumber): ChainFork =
if number >= c.berlinBlock: Berlin
if number >= c.londonBlock: London
elif number >= c.berlinBlock: Berlin
elif number >= c.muirGlacierBlock: MuirGlacier
elif number >= c.istanbulBlock: Istanbul
elif number >= c.petersburgBlock: Petersburg
@ -71,6 +73,7 @@ func getNextFork(c: ChainConfig, fork: ChainFork): uint64 =
toNextFork(c.istanbulBlock),
toNextFork(c.muirGlacierBlock),
toNextFork(c.berlinBlock),
toNextFork(c.londonBlock)
]
if fork == high(ChainFork):

View File

@ -151,8 +151,7 @@ proc validateGasLimit*(c: var BaseChainDB; header: BlockHeader): CliqueResult {.
# params/config.go(450): func (c *ChainConfig) IsLondon(num [..]
proc isLondonOrLater*(c: var ChainConfig; number: BlockNumber): bool =
## FIXME: London is not defined yet, will come after Berlin
FkBerlin < c.toFork(number)
c.toFork(number) >= FkLondon
# consensus/misc/eip1559.go(55): func CalcBaseFee(config [..]
proc calc1599BaseFee*(c: var ChainConfig; parent: BlockHeader): UInt256 =

View File

@ -90,7 +90,8 @@ const
eth2, # FkConstantinople
eth2, # FkPetersburg
eth2, # FkIstanbul
eth2 # FkBerlin
eth2, # FkBerlin
eth2 # FkLondon
]
proc calculateReward(fork: Fork, header: BlockHeader, body: BlockBody, vmState: BaseVMState) =

View File

@ -25,6 +25,7 @@ type
block_gas_limit* : int64 # The block gas limit.
block_difficulty*: evmc_uint256be # The block difficulty.
chain_id* : evmc_uint256be # The blockchain's ChainID.
block_base_fee* : evmc_uint256be # The block base fee.
nimbus_message* = object
kind*: evmc_call_kind

View File

@ -33,7 +33,7 @@ proc hostGetStorageImpl(ctx: Computation, address: EthAddress, key: var evmc_byt
ctx.vmState.accountDB.getStorage(address, Uint256.fromEvmc(key)).toEvmc()
proc sstoreNetGasMetering(ctx: Computation): bool {.inline.} =
ctx.fork in {FkConstantinople, FkIstanbul, FkBerlin}
ctx.fork in {FkConstantinople, FkIstanbul, FkBerlin, FkLondon}
proc hostSetStorageImpl(ctx: Computation, address: EthAddress,
key, value: var evmc_bytes32): evmc_storage_status {.cdecl.} =

View File

@ -738,7 +738,8 @@ const
FkConstantinople: SpuriousGasFees,
FkPetersburg: SpuriousGasFees,
FkIstanbul: IstanbulGasFees,
FkBerlin: BerlinGasFees
FkBerlin: BerlinGasFees,
FkLondon: BerlinGasFees
]
@ -749,6 +750,7 @@ gasCosts(FkSpurious, spurious, SpuriousGasCosts)
gasCosts(FkConstantinople, constantinople, ConstantinopleGasCosts)
gasCosts(FkIstanbul, istanbul, IstanbulGasCosts)
gasCosts(FkBerlin, berlin, BerlinGasCosts)
gasCosts(FkLondon, london, LondonGasCosts)
proc forkToSchedule*(fork: Fork): GasCosts =
if fork < FkHomestead:
@ -763,8 +765,10 @@ proc forkToSchedule*(fork: Fork): GasCosts =
SpuriousGasCosts
elif fork < FkBerlin:
IstanbulGasCosts
else:
elif fork < FkLondon:
BerlinGasCosts
else:
LondonGasCosts
const
## Precompile costs

View File

@ -248,6 +248,12 @@ proc genBerlinJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compileTi
let BerlinOpDispatch {.compileTime.}: array[Op, NimNode] = genBerlinJumpTable(IstanbulOpDispatch)
proc genLondonJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compileTime.} =
result = ops
# incoming EIP-3198 and EIP-3529
let LondonOpDispatch {.compileTime.}: array[Op, NimNode] = genLondonJumpTable(BerlinOpDispatch)
proc opTableToCaseStmt(opTable: array[Op, NimNode], c: NimNode): NimNode =
let instr = quote do: `c`.instr
@ -336,6 +342,9 @@ macro genIstanbulDispatch(c: Computation): untyped =
macro genBerlinDispatch(c: Computation): untyped =
result = opTableToCaseStmt(BerlinOpDispatch, c)
macro genLondonDispatch(c: Computation): untyped =
result = opTableToCaseStmt(LondonOpDispatch, c)
proc frontierVM(c: Computation) =
genFrontierDispatch(c)
@ -363,6 +372,9 @@ proc istanbulVM(c: Computation) {.gcsafe.} =
proc berlinVM(c: Computation) {.gcsafe.} =
genBerlinDispatch(c)
proc londonVM(c: Computation) {.gcsafe.} =
genLondonDispatch(c)
proc selectVM(c: Computation, fork: Fork) {.gcsafe.} =
# TODO: Optimise getting fork and updating opCodeExec only when necessary
case fork
@ -382,8 +394,10 @@ proc selectVM(c: Computation, fork: Fork) {.gcsafe.} =
c.petersburgVM()
of FkIstanbul:
c.istanbulVM()
else:
of FkBerlin:
c.berlinVM()
else:
c.londonVM()
proc executeOpcodes(c: Computation) =
let fork = c.fork

View File

@ -708,7 +708,8 @@ const
FkConstantinople: SpuriousGasFees,
FkPetersburg: SpuriousGasFees,
FkIstanbul: IstanbulGasFees,
FkBerlin: BerlinGasFees
FkBerlin: BerlinGasFees,
FkLondon: BerlinGasFees
]
@ -719,6 +720,7 @@ gasCosts(FkSpurious, spurious, SpuriousGasCosts)
gasCosts(FkConstantinople, constantinople, ConstantinopleGasCosts)
gasCosts(FkIstanbul, istanbul, IstanbulGasCosts)
gasCosts(FkBerlin, berlin, BerlinGasCosts)
gasCosts(FkLondon, london, LondonGasCosts)
proc forkToSchedule*(fork: Fork): GasCosts =
if fork < FkHomestead:
@ -733,8 +735,10 @@ proc forkToSchedule*(fork: Fork): GasCosts =
SpuriousGasCosts
elif fork < FkBerlin:
IstanbulGasCosts
else:
elif fork < FkLondon:
BerlinGasCosts
else:
LondonGasCosts
const
## Precompile costs

View File

@ -78,6 +78,9 @@ const
Vm2OpBerlinAndLater* =
Vm2OpIstanbulAndLater - {FkIstanbul}
Vm2OpLondonAndLater* =
Vm2OpBerlinAndLater - {FkBerlin}
# ------------------------------------------------------------------------------
# End
# ------------------------------------------------------------------------------