mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-11 21:04:11 +00:00
Update terminal total difficulty handling (#992)
why: Testing against a replay unit test for Devnet4 made it necessary to adjust the TTD handling. Without updated, importing fails at block #5646 which is the parent of the terminal PoW block. Similar considerations apply for Devnet5 and Kiln.
This commit is contained in:
parent
a4b70918ed
commit
534fb528a4
@ -67,7 +67,6 @@ type
|
|||||||
txEnv: TxChainPackerEnv ## Assorted parameters, tx packer environment
|
txEnv: TxChainPackerEnv ## Assorted parameters, tx packer environment
|
||||||
|
|
||||||
# EIP-4399 and EIP-3675
|
# EIP-4399 and EIP-3675
|
||||||
ttdReached: bool ## Total Terminal Difficulty reached
|
|
||||||
prevRandao: Hash256 ## POS block randomness
|
prevRandao: Hash256 ## POS block randomness
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@ -85,8 +84,7 @@ proc resetTxEnv(dh: TxChainRef; parent: BlockHeader; fee: Option[UInt256])
|
|||||||
fee = fee,
|
fee = fee,
|
||||||
prevRandao= dh.prevRandao,
|
prevRandao= dh.prevRandao,
|
||||||
miner = dh.miner,
|
miner = dh.miner,
|
||||||
chainDB = dh.db,
|
chainDB = dh.db)
|
||||||
ttdReached= dh.ttdReached)
|
|
||||||
|
|
||||||
dh.txEnv.txRoot = BLANK_ROOT_HASH
|
dh.txEnv.txRoot = BLANK_ROOT_HASH
|
||||||
dh.txEnv.stateRoot = dh.txEnv.vmState.parent.stateRoot
|
dh.txEnv.stateRoot = dh.txEnv.vmState.parent.stateRoot
|
||||||
@ -309,10 +307,6 @@ proc `txRoot=`*(dh: TxChainRef; val: Hash256) =
|
|||||||
## Setter
|
## Setter
|
||||||
dh.txEnv.txRoot = val
|
dh.txEnv.txRoot = val
|
||||||
|
|
||||||
proc `ttdReached=`*(dh: TxChainRef; val: bool) =
|
|
||||||
## Setter
|
|
||||||
dh.ttdReached = val
|
|
||||||
|
|
||||||
proc `prevRandao=`*(dh: TxChainRef; val: Hash256) =
|
proc `prevRandao=`*(dh: TxChainRef; val: Hash256) =
|
||||||
## Setter
|
## Setter
|
||||||
dh.prevRandao = val
|
dh.prevRandao = val
|
||||||
|
@ -40,11 +40,18 @@ template safeExecutor(info: string; code: untyped) =
|
|||||||
let e = getCurrentException()
|
let e = getCurrentException()
|
||||||
raise newException(VmStateError, info & "(): " & $e.name & " -- " & e.msg)
|
raise newException(VmStateError, info & "(): " & $e.name & " -- " & e.msg)
|
||||||
|
|
||||||
proc getMinerAddress(chainDB: BaseChainDB; header: BlockHeader, ttdReached: bool): EthAddress
|
proc isTtdReached(db: BaseChainDB; blockHash: Hash256): bool
|
||||||
|
{.gcsafe, raises: [Defect,RlpError].} =
|
||||||
|
## Returns `true` iff the stored sum of difficulties has reached the
|
||||||
|
## terminal total difficulty, see EIP3675.
|
||||||
|
if db.config.terminalTotalDifficulty.isSome:
|
||||||
|
return db.config.terminalTotalDifficulty.get <= db.getScore(blockHash)
|
||||||
|
|
||||||
|
proc getMinerAddress(chainDB: BaseChainDB; header: BlockHeader): EthAddress
|
||||||
{.gcsafe, raises: [Defect,CatchableError].} =
|
{.gcsafe, raises: [Defect,CatchableError].} =
|
||||||
if not chainDB.config.poaEngine or ttdReached:
|
if not chainDB.config.poaEngine or chainDB.isTtdReached(header.parentHash):
|
||||||
return header.coinbase
|
return header.coinbase
|
||||||
|
|
||||||
let account = header.ecRecover
|
let account = header.ecRecover
|
||||||
if account.isErr:
|
if account.isErr:
|
||||||
let msg = "Could not recover account address: " & $account.error
|
let msg = "Could not recover account address: " & $account.error
|
||||||
@ -91,7 +98,6 @@ proc init(
|
|||||||
prevRandao: Hash256;
|
prevRandao: Hash256;
|
||||||
miner: EthAddress;
|
miner: EthAddress;
|
||||||
chainDB: BaseChainDB;
|
chainDB: BaseChainDB;
|
||||||
ttdReached: bool;
|
|
||||||
tracerFlags: set[TracerFlags])
|
tracerFlags: set[TracerFlags])
|
||||||
{.gcsafe, raises: [Defect,CatchableError].} =
|
{.gcsafe, raises: [Defect,CatchableError].} =
|
||||||
var tracer: TransactionTracer
|
var tracer: TransactionTracer
|
||||||
@ -105,7 +111,7 @@ proc init(
|
|||||||
prevRandao= prevRandao,
|
prevRandao= prevRandao,
|
||||||
miner = miner,
|
miner = miner,
|
||||||
chainDB = chainDB,
|
chainDB = chainDB,
|
||||||
ttdReached= ttdReached,
|
ttdReached= chainDB.isTtdReached(parent.blockHash),
|
||||||
tracer = tracer)
|
tracer = tracer)
|
||||||
|
|
||||||
# --------------
|
# --------------
|
||||||
@ -128,7 +134,6 @@ proc new*(
|
|||||||
prevRandao: Hash256; ## tx env: POS block randomness
|
prevRandao: Hash256; ## tx env: POS block randomness
|
||||||
miner: EthAddress; ## tx env: coinbase(PoW) or signer(PoA)
|
miner: EthAddress; ## tx env: coinbase(PoW) or signer(PoA)
|
||||||
chainDB: BaseChainDB; ## block chain database
|
chainDB: BaseChainDB; ## block chain database
|
||||||
ttdReached: bool; ## total terminal difficulty reached
|
|
||||||
tracerFlags: set[TracerFlags] = {};
|
tracerFlags: set[TracerFlags] = {};
|
||||||
pruneTrie: bool = true): T
|
pruneTrie: bool = true): T
|
||||||
{.gcsafe, raises: [Defect,CatchableError].} =
|
{.gcsafe, raises: [Defect,CatchableError].} =
|
||||||
@ -149,7 +154,6 @@ proc new*(
|
|||||||
prevRandao = prevRandao,
|
prevRandao = prevRandao,
|
||||||
miner = miner,
|
miner = miner,
|
||||||
chainDB = chainDB,
|
chainDB = chainDB,
|
||||||
ttdReached = ttdReached,
|
|
||||||
tracerFlags = tracerFlags)
|
tracerFlags = tracerFlags)
|
||||||
|
|
||||||
proc reinit*(self: BaseVMState; ## Object descriptor
|
proc reinit*(self: BaseVMState; ## Object descriptor
|
||||||
@ -159,7 +163,6 @@ proc reinit*(self: BaseVMState; ## Object descriptor
|
|||||||
fee: Option[Uint256]; ## tx env: optional base fee
|
fee: Option[Uint256]; ## tx env: optional base fee
|
||||||
prevRandao:Hash256; ## tx env: POS block randomness
|
prevRandao:Hash256; ## tx env: POS block randomness
|
||||||
miner: EthAddress; ## tx env: coinbase(PoW) or signer(PoA)
|
miner: EthAddress; ## tx env: coinbase(PoW) or signer(PoA)
|
||||||
ttdReached:bool; ## total terminal difficulty reached
|
|
||||||
pruneTrie: bool = true): bool
|
pruneTrie: bool = true): bool
|
||||||
{.gcsafe, raises: [Defect,CatchableError].} =
|
{.gcsafe, raises: [Defect,CatchableError].} =
|
||||||
## Re-initialise state descriptor. The `AccountsCache` database is
|
## Re-initialise state descriptor. The `AccountsCache` database is
|
||||||
@ -186,7 +189,7 @@ proc reinit*(self: BaseVMState; ## Object descriptor
|
|||||||
prevRandao = prevRandao,
|
prevRandao = prevRandao,
|
||||||
miner = miner,
|
miner = miner,
|
||||||
chainDB = db,
|
chainDB = db,
|
||||||
ttdReached = ttdReached,
|
ttdReached = db.isTtdReached(parent.blockHash),
|
||||||
tracer = tracer)
|
tracer = tracer)
|
||||||
return true
|
return true
|
||||||
# else: false
|
# else: false
|
||||||
@ -202,17 +205,13 @@ proc reinit*(self: BaseVMState; ## Object descriptor
|
|||||||
##
|
##
|
||||||
## It requires the `header` argument properly initalised so that for PoA
|
## It requires the `header` argument properly initalised so that for PoA
|
||||||
## networks, the miner address is retrievable via `ecRecover()`.
|
## networks, the miner address is retrievable via `ecRecover()`.
|
||||||
let ttdReached = self.chainDB.totalDifficulty + header.difficulty > self.chainDB.ttd
|
result = self.reinit(
|
||||||
let miner = self.chainDB.getMinerAddress(header, ttdReached)
|
|
||||||
|
|
||||||
self.reinit(
|
|
||||||
parent = parent,
|
parent = parent,
|
||||||
timestamp = header.timestamp,
|
timestamp = header.timestamp,
|
||||||
gasLimit = header.gasLimit,
|
gasLimit = header.gasLimit,
|
||||||
fee = header.fee,
|
fee = header.fee,
|
||||||
prevRandao= header.prevRandao,
|
prevRandao= header.prevRandao,
|
||||||
miner = miner,
|
miner = self.chainDB.getMinerAddress(header),
|
||||||
ttdReached= ttdReached,
|
|
||||||
pruneTrie = pruneTrie)
|
pruneTrie = pruneTrie)
|
||||||
|
|
||||||
proc reinit*(self: BaseVMState; ## Object descriptor
|
proc reinit*(self: BaseVMState; ## Object descriptor
|
||||||
@ -243,18 +242,16 @@ proc init*(
|
|||||||
##
|
##
|
||||||
## It requires the `header` argument properly initalised so that for PoA
|
## It requires the `header` argument properly initalised so that for PoA
|
||||||
## networks, the miner address is retrievable via `ecRecover()`.
|
## networks, the miner address is retrievable via `ecRecover()`.
|
||||||
let ttdReached = chainDB.totalDifficulty + header.difficulty > chainDB.ttd
|
self.init(
|
||||||
let miner = chainDB.getMinerAddress(header, ttdReached)
|
ac = AccountsCache.init(chainDB.db, parent.stateRoot, pruneTrie),
|
||||||
self.init(AccountsCache.init(chainDB.db, parent.stateRoot, pruneTrie),
|
parent = parent,
|
||||||
parent,
|
timestamp = header.timestamp,
|
||||||
header.timestamp,
|
gasLimit = header.gasLimit,
|
||||||
header.gasLimit,
|
fee = header.fee,
|
||||||
header.fee,
|
prevRandao = header.prevRandao,
|
||||||
header.prevRandao,
|
miner = chainDB.getMinerAddress(header),
|
||||||
miner,
|
chainDB = chainDB,
|
||||||
chainDB,
|
tracerFlags = tracerFlags)
|
||||||
ttdReached,
|
|
||||||
tracerFlags)
|
|
||||||
|
|
||||||
proc new*(
|
proc new*(
|
||||||
T: type BaseVMState;
|
T: type BaseVMState;
|
||||||
|
@ -39,9 +39,16 @@ template safeExecutor(info: string; code: untyped) =
|
|||||||
let e = getCurrentException()
|
let e = getCurrentException()
|
||||||
raise newException(VmStateError, info & "(): " & $e.name & " -- " & e.msg)
|
raise newException(VmStateError, info & "(): " & $e.name & " -- " & e.msg)
|
||||||
|
|
||||||
proc getMinerAddress(chainDB: BaseChainDB; header: BlockHeader, ttdReached: bool): EthAddress
|
proc isTtdReached(db: BaseChainDB; blockHash: Hash256): bool
|
||||||
|
{.gcsafe, raises: [Defect,RlpError].} =
|
||||||
|
## Returns `true` iff the stored sum of difficulties has reached the
|
||||||
|
## terminal total difficulty, see EIP3675.
|
||||||
|
if db.config.terminalTotalDifficulty.isSome:
|
||||||
|
return db.config.terminalTotalDifficulty.get <= db.getScore(blockHash)
|
||||||
|
|
||||||
|
proc getMinerAddress(chainDB: BaseChainDB; header: BlockHeader): EthAddress
|
||||||
{.gcsafe, raises: [Defect,CatchableError].} =
|
{.gcsafe, raises: [Defect,CatchableError].} =
|
||||||
if not chainDB.config.poaEngine or ttdReached:
|
if not chainDB.config.poaEngine or chainDB.isTtdReached(header.parentHash):
|
||||||
return header.coinbase
|
return header.coinbase
|
||||||
|
|
||||||
let account = header.ecRecover
|
let account = header.ecRecover
|
||||||
@ -90,7 +97,6 @@ proc init(
|
|||||||
prevRandao: Hash256;
|
prevRandao: Hash256;
|
||||||
miner: EthAddress;
|
miner: EthAddress;
|
||||||
chainDB: BaseChainDB;
|
chainDB: BaseChainDB;
|
||||||
ttdReached: bool;
|
|
||||||
tracerFlags: set[TracerFlags])
|
tracerFlags: set[TracerFlags])
|
||||||
{.gcsafe, raises: [Defect,CatchableError].} =
|
{.gcsafe, raises: [Defect,CatchableError].} =
|
||||||
var tracer: TransactionTracer
|
var tracer: TransactionTracer
|
||||||
@ -104,7 +110,7 @@ proc init(
|
|||||||
prevRandao= prevRandao,
|
prevRandao= prevRandao,
|
||||||
miner = miner,
|
miner = miner,
|
||||||
chainDB = chainDB,
|
chainDB = chainDB,
|
||||||
ttdReached= ttdReached,
|
ttdReached= chainDB.isTtdReached(parent.blockHash),
|
||||||
tracer = tracer)
|
tracer = tracer)
|
||||||
|
|
||||||
# --------------
|
# --------------
|
||||||
@ -127,7 +133,6 @@ proc new*(
|
|||||||
prevRandao: Hash256; ## tx env: POS block randomness
|
prevRandao: Hash256; ## tx env: POS block randomness
|
||||||
miner: EthAddress; ## tx env: coinbase(PoW) or signer(PoA)
|
miner: EthAddress; ## tx env: coinbase(PoW) or signer(PoA)
|
||||||
chainDB: BaseChainDB; ## block chain database
|
chainDB: BaseChainDB; ## block chain database
|
||||||
ttdReached: bool; ## total terminal difficulty reached
|
|
||||||
tracerFlags: set[TracerFlags] = {};
|
tracerFlags: set[TracerFlags] = {};
|
||||||
pruneTrie: bool = true): T
|
pruneTrie: bool = true): T
|
||||||
{.gcsafe, raises: [Defect,CatchableError].} =
|
{.gcsafe, raises: [Defect,CatchableError].} =
|
||||||
@ -148,7 +153,6 @@ proc new*(
|
|||||||
prevRandao = prevRandao,
|
prevRandao = prevRandao,
|
||||||
miner = miner,
|
miner = miner,
|
||||||
chainDB = chainDB,
|
chainDB = chainDB,
|
||||||
ttdReached = ttdReached,
|
|
||||||
tracerFlags = tracerFlags)
|
tracerFlags = tracerFlags)
|
||||||
|
|
||||||
proc reinit*(self: BaseVMState; ## Object descriptor
|
proc reinit*(self: BaseVMState; ## Object descriptor
|
||||||
@ -158,7 +162,6 @@ proc reinit*(self: BaseVMState; ## Object descriptor
|
|||||||
fee: Option[Uint256]; ## tx env: optional base fee
|
fee: Option[Uint256]; ## tx env: optional base fee
|
||||||
prevRandao:Hash256; ## tx env: POS block randomness
|
prevRandao:Hash256; ## tx env: POS block randomness
|
||||||
miner: EthAddress; ## tx env: coinbase(PoW) or signer(PoA)
|
miner: EthAddress; ## tx env: coinbase(PoW) or signer(PoA)
|
||||||
ttdReached:bool; ## total terminal difficulty reached
|
|
||||||
pruneTrie: bool = true): bool
|
pruneTrie: bool = true): bool
|
||||||
{.gcsafe, raises: [Defect,CatchableError].} =
|
{.gcsafe, raises: [Defect,CatchableError].} =
|
||||||
## Re-initialise state descriptor. The `AccountsCache` database is
|
## Re-initialise state descriptor. The `AccountsCache` database is
|
||||||
@ -185,7 +188,7 @@ proc reinit*(self: BaseVMState; ## Object descriptor
|
|||||||
prevRandao = prevRandao,
|
prevRandao = prevRandao,
|
||||||
miner = miner,
|
miner = miner,
|
||||||
chainDB = db,
|
chainDB = db,
|
||||||
ttdReached = ttdReached,
|
ttdReached = db.isTtdReached(parent.blockHash),
|
||||||
tracer = tracer)
|
tracer = tracer)
|
||||||
return true
|
return true
|
||||||
# else: false
|
# else: false
|
||||||
@ -201,16 +204,13 @@ proc reinit*(self: BaseVMState; ## Object descriptor
|
|||||||
##
|
##
|
||||||
## It requires the `header` argument properly initalised so that for PoA
|
## It requires the `header` argument properly initalised so that for PoA
|
||||||
## networks, the miner address is retrievable via `ecRecover()`.
|
## networks, the miner address is retrievable via `ecRecover()`.
|
||||||
let ttdReached = self.chainDB.totalDifficulty + header.difficulty > self.chainDB.ttd
|
result = self.reinit(
|
||||||
let miner = self.chainDB.getMinerAddress(header, ttdReached)
|
|
||||||
self.reinit(
|
|
||||||
parent = parent,
|
parent = parent,
|
||||||
timestamp = header.timestamp,
|
timestamp = header.timestamp,
|
||||||
gasLimit = header.gasLimit,
|
gasLimit = header.gasLimit,
|
||||||
fee = header.fee,
|
fee = header.fee,
|
||||||
prevRandao= header.prevRandao,
|
prevRandao= header.prevRandao,
|
||||||
miner = miner,
|
miner = self.chainDB.getMinerAddress(header),
|
||||||
ttdReached= ttdReached,
|
|
||||||
pruneTrie = pruneTrie)
|
pruneTrie = pruneTrie)
|
||||||
|
|
||||||
proc reinit*(self: BaseVMState; ## Object descriptor
|
proc reinit*(self: BaseVMState; ## Object descriptor
|
||||||
@ -241,18 +241,16 @@ proc init*(
|
|||||||
##
|
##
|
||||||
## It requires the `header` argument properly initalised so that for PoA
|
## It requires the `header` argument properly initalised so that for PoA
|
||||||
## networks, the miner address is retrievable via `ecRecover()`.
|
## networks, the miner address is retrievable via `ecRecover()`.
|
||||||
let ttdReached = chainDB.totalDifficulty + header.difficulty > chainDB.ttd
|
self.init(
|
||||||
let miner = chainDB.getMinerAddress(header, ttdReached)
|
ac = AccountsCache.init(chainDB.db, parent.stateRoot, pruneTrie),
|
||||||
self.init(AccountsCache.init(chainDB.db, parent.stateRoot, pruneTrie),
|
parent = parent,
|
||||||
parent,
|
timestamp = header.timestamp,
|
||||||
header.timestamp,
|
gasLimit = header.gasLimit,
|
||||||
header.gasLimit,
|
fee = header.fee,
|
||||||
header.fee,
|
prevRandao = header.prevRandao,
|
||||||
header.prevRandao,
|
miner = chainDB.getMinerAddress(header),
|
||||||
miner,
|
chainDB = chainDB,
|
||||||
chainDB,
|
tracerFlags = tracerFlags)
|
||||||
ttdReached,
|
|
||||||
tracerFlags)
|
|
||||||
|
|
||||||
proc new*(
|
proc new*(
|
||||||
T: type BaseVMState;
|
T: type BaseVMState;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user