mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-11 12:54:13 +00:00
handle PoA block difficulty during block creation
- in vmState - in txpool - in sealing engine fix #1105
This commit is contained in:
parent
6325712aa6
commit
77be2f66d2
@ -12,8 +12,6 @@
|
||||
## Mining Support for Clique PoA Consensus Protocol
|
||||
## ================================================
|
||||
##
|
||||
## Note that mining in currently unsupported by `NIMBUS`
|
||||
##
|
||||
## For details see
|
||||
## `EIP-225 <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-225.md>`_
|
||||
## and
|
||||
@ -322,7 +320,7 @@ proc seal*(c: Clique; ethBlock: var EthBlock):
|
||||
ok()
|
||||
|
||||
# clique/clique.go(673): func (c *Clique) CalcDifficulty(chain [..]
|
||||
proc calcDifficulty(c: Clique;
|
||||
proc calcDifficulty*(c: Clique;
|
||||
parent: BlockHeader): Result[DifficultyInt,CliqueError]
|
||||
{.gcsafe, raises: [Defect,CatchableError].} =
|
||||
## For the Consensus Engine, `calcDifficulty()` is the difficulty adjustment
|
||||
|
@ -126,8 +126,6 @@ proc generateBlock(engine: SealingEngineRef,
|
||||
timestamp = getTime(),
|
||||
prevRandao = Hash256()): Result[void, string] =
|
||||
# deviation from standard block generator
|
||||
# - no local and remote transactions inclusion(need tx pool)
|
||||
# - no receipts from tx
|
||||
# - no DAO hard fork
|
||||
# - no local and remote uncles inclusion
|
||||
|
||||
@ -188,6 +186,20 @@ proc sealingLoop(engine: SealingEngineRef): Future[void] {.async.} =
|
||||
|
||||
clique.authorize(engine.signer, signerFunc)
|
||||
|
||||
proc diffCalculator(timeStamp: EthTime, parent: BlockHeader): DifficultyInt {.gcsafe, raises:[].} =
|
||||
# pesky Nim effect system
|
||||
try:
|
||||
discard timestamp
|
||||
let rc = clique.calcDifficulty(parent)
|
||||
if rc.isErr:
|
||||
return 0.u256
|
||||
rc.get()
|
||||
except:
|
||||
0.u256
|
||||
|
||||
# switch to PoA difficulty calculator
|
||||
engine.txPool.calcDifficulty = diffCalculator
|
||||
|
||||
# convert times.Duration to chronos.Duration
|
||||
let period = chronos.seconds(clique.cfg.period.inSeconds)
|
||||
|
||||
|
@ -772,6 +772,11 @@ proc `feeRecipient=`*(xp: TxPoolRef; beneficiary: EthAddress) =
|
||||
## a.k.a miner in PoW chain or coinbase
|
||||
xp.chain.miner = beneficiary
|
||||
|
||||
proc `calcDifficulty=`*(xp: TxPoolRef; val: DifficultyCalculator) =
|
||||
## Setter, either PoW or PoA difficulty calculator
|
||||
## PoS difficulty always zero
|
||||
xp.chain.calcDifficulty = val
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public functions, per-tx-item operations
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -20,6 +20,7 @@ import
|
||||
../../forks,
|
||||
../../p2p/executor,
|
||||
../../utils,
|
||||
../../utils/difficulty,
|
||||
../../vm_state,
|
||||
../../vm_types,
|
||||
./tx_chain/[tx_basefee, tx_gaslimits],
|
||||
@ -53,6 +54,8 @@ type
|
||||
txRoot: Hash256 ## `rootHash` after packing
|
||||
stateRoot: Hash256 ## `stateRoot` after packing
|
||||
|
||||
DifficultyCalculator* = proc(timeStamp: EthTime, parent: BlockHeader): DifficultyInt {.gcsafe, raises:[].}
|
||||
|
||||
TxChainRef* = ref object ##\
|
||||
## State cache of the transaction environment for creating a new\
|
||||
## block. This state is typically synchrionised with the canonical\
|
||||
@ -69,6 +72,9 @@ type
|
||||
# EIP-4399 and EIP-3675
|
||||
prevRandao: Hash256 ## PoS block randomness
|
||||
|
||||
# overrideable difficulty calculator
|
||||
calcDifficulty: DifficultyCalculator
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Private functions
|
||||
# ------------------------------------------------------------------------------
|
||||
@ -77,12 +83,16 @@ proc resetTxEnv(dh: TxChainRef; parent: BlockHeader; fee: Option[UInt256])
|
||||
{.gcsafe,raises: [Defect,CatchableError].} =
|
||||
dh.txEnv.reset
|
||||
|
||||
let timestamp = getTime().utc.toTime
|
||||
# we don't consider PoS difficulty here
|
||||
# because that is handled in vmState
|
||||
dh.txEnv.vmState = BaseVMState.new(
|
||||
parent = parent,
|
||||
timestamp = getTime().utc.toTime,
|
||||
timestamp = timestamp,
|
||||
gasLimit = (if dh.maxMode: dh.limits.maxLimit else: dh.limits.trgLimit),
|
||||
fee = fee,
|
||||
prevRandao= dh.prevRandao,
|
||||
difficulty= dh.calcDifficulty(timestamp, parent),
|
||||
miner = dh.miner,
|
||||
chainDB = dh.db)
|
||||
|
||||
@ -118,6 +128,12 @@ proc new*(T: type TxChainRef; db: BaseChainDB; miner: EthAddress): T
|
||||
result.miner = miner
|
||||
result.lhwm.lwmTrg = TRG_THRESHOLD_PER_CENT
|
||||
result.lhwm.hwmMax = MAX_THRESHOLD_PER_CENT
|
||||
result.calcDifficulty = proc(timeStamp: EthTime, parent: BlockHeader):
|
||||
DifficultyInt {.gcsafe, raises:[].} =
|
||||
try:
|
||||
db.config.calcDifficulty(timestamp, parent)
|
||||
except:
|
||||
0.u256
|
||||
result.update(db.getCanonicalHead)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
@ -311,6 +327,10 @@ proc `prevRandao=`*(dh: TxChainRef; val: Hash256) =
|
||||
## Setter
|
||||
dh.prevRandao = val
|
||||
|
||||
proc `calcDifficulty=`*(dh: TxChainRef; val: DifficultyCalculator) =
|
||||
## Setter
|
||||
dh.calcDifficulty = val
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# End
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -67,6 +67,7 @@ proc init(
|
||||
gasLimit: GasInt;
|
||||
fee: Option[UInt256];
|
||||
prevRandao: Hash256;
|
||||
difficulty: UInt256;
|
||||
miner: EthAddress;
|
||||
chainDB: BaseChainDB;
|
||||
ttdReached: bool;
|
||||
@ -80,6 +81,7 @@ proc init(
|
||||
self.gasLimit = gasLimit
|
||||
self.fee = fee
|
||||
self.prevRandao = prevRandao
|
||||
self.blockDifficulty = difficulty
|
||||
self.chainDB = chainDB
|
||||
self.ttdReached = ttdReached
|
||||
self.tracer = tracer
|
||||
@ -96,6 +98,7 @@ proc init(
|
||||
gasLimit: GasInt;
|
||||
fee: Option[UInt256];
|
||||
prevRandao: Hash256;
|
||||
difficulty: UInt256;
|
||||
miner: EthAddress;
|
||||
chainDB: BaseChainDB;
|
||||
tracerFlags: set[TracerFlags])
|
||||
@ -109,6 +112,7 @@ proc init(
|
||||
gasLimit = gasLimit,
|
||||
fee = fee,
|
||||
prevRandao= prevRandao,
|
||||
difficulty= difficulty,
|
||||
miner = miner,
|
||||
chainDB = chainDB,
|
||||
ttdReached= chainDB.isTtdReached(parent.blockHash),
|
||||
@ -132,6 +136,7 @@ proc new*(
|
||||
gasLimit: GasInt; ## tx env: gas limit
|
||||
fee: Option[UInt256]; ## tx env: optional base fee
|
||||
prevRandao: Hash256; ## tx env: POS block randomness
|
||||
difficulty: UInt256, ## tx env: difficulty
|
||||
miner: EthAddress; ## tx env: coinbase(PoW) or signer(PoA)
|
||||
chainDB: BaseChainDB; ## block chain database
|
||||
tracerFlags: set[TracerFlags] = {};
|
||||
@ -152,6 +157,7 @@ proc new*(
|
||||
gasLimit = gasLimit,
|
||||
fee = fee,
|
||||
prevRandao = prevRandao,
|
||||
difficulty = difficulty,
|
||||
miner = miner,
|
||||
chainDB = chainDB,
|
||||
tracerFlags = tracerFlags)
|
||||
@ -162,6 +168,7 @@ proc reinit*(self: BaseVMState; ## Object descriptor
|
||||
gasLimit: GasInt; ## tx env: gas limit
|
||||
fee: Option[UInt256]; ## tx env: optional base fee
|
||||
prevRandao:Hash256; ## tx env: POS block randomness
|
||||
difficulty:UInt256, ## tx env: difficulty
|
||||
miner: EthAddress; ## tx env: coinbase(PoW) or signer(PoA)
|
||||
pruneTrie: bool = true): bool
|
||||
{.gcsafe, raises: [Defect,CatchableError].} =
|
||||
@ -187,6 +194,7 @@ proc reinit*(self: BaseVMState; ## Object descriptor
|
||||
gasLimit = gasLimit,
|
||||
fee = fee,
|
||||
prevRandao = prevRandao,
|
||||
difficulty = difficulty,
|
||||
miner = miner,
|
||||
chainDB = db,
|
||||
ttdReached = db.isTtdReached(parent.blockHash),
|
||||
@ -211,6 +219,7 @@ proc reinit*(self: BaseVMState; ## Object descriptor
|
||||
gasLimit = header.gasLimit,
|
||||
fee = header.fee,
|
||||
prevRandao= header.prevRandao,
|
||||
difficulty= header.difficulty,
|
||||
miner = self.chainDB.getMinerAddress(header),
|
||||
pruneTrie = pruneTrie)
|
||||
|
||||
@ -249,6 +258,7 @@ proc init*(
|
||||
gasLimit = header.gasLimit,
|
||||
fee = header.fee,
|
||||
prevRandao = header.prevRandao,
|
||||
difficulty = header.difficulty,
|
||||
miner = chainDB.getMinerAddress(header),
|
||||
chainDB = chainDB,
|
||||
tracerFlags = tracerFlags)
|
||||
@ -305,12 +315,6 @@ proc setupTxContext*(vmState: BaseVMState, origin: EthAddress, gasPrice: GasInt,
|
||||
vmState.chainDB.config.toFork(vmState.parent.blockNumber + 1)
|
||||
vmState.gasCosts = vmState.fork.forkToSchedule
|
||||
|
||||
proc consensusEnginePoA*(vmState: BaseVMState): bool =
|
||||
# PoA consensus engine have no reward for miner
|
||||
# TODO: this need to be fixed somehow
|
||||
# using `real` engine configuration
|
||||
vmState.chainDB.config.poaEngine
|
||||
|
||||
method coinbase*(vmState: BaseVMState): EthAddress {.base, gcsafe.} =
|
||||
vmState.minerAddress
|
||||
|
||||
@ -324,7 +328,7 @@ method difficulty*(vmState: BaseVMState): UInt256 {.base, gcsafe.} =
|
||||
# EIP-4399/EIP-3675
|
||||
UInt256.fromBytesBE(vmState.prevRandao.data, allowPadding = false)
|
||||
else:
|
||||
vmState.chainDB.config.calcDifficulty(vmState.timestamp, vmState.parent)
|
||||
vmState.blockDifficulty
|
||||
|
||||
method baseFee*(vmState: BaseVMState): UInt256 {.base, gcsafe.} =
|
||||
if vmState.fee.isSome:
|
||||
|
@ -39,6 +39,7 @@ type
|
||||
gasLimit* : GasInt
|
||||
fee* : Option[UInt256]
|
||||
prevRandao* : Hash256
|
||||
blockDifficulty*: UInt256
|
||||
ttdReached* : bool
|
||||
name* : string
|
||||
flags* : set[VMFlag]
|
||||
|
@ -65,6 +65,7 @@ proc init(
|
||||
gasLimit: GasInt;
|
||||
fee: Option[UInt256];
|
||||
prevRandao: Hash256;
|
||||
difficulty: UInt256;
|
||||
miner: EthAddress;
|
||||
chainDB: BaseChainDB;
|
||||
ttdReached: bool;
|
||||
@ -78,6 +79,7 @@ proc init(
|
||||
self.gasLimit = gasLimit
|
||||
self.fee = fee
|
||||
self.prevRandao = prevRandao
|
||||
self.blockDifficulty = difficulty
|
||||
self.chainDB = chainDB
|
||||
self.ttdReached = ttdReached
|
||||
self.tracer = tracer
|
||||
@ -94,6 +96,7 @@ proc init(
|
||||
gasLimit: GasInt;
|
||||
fee: Option[UInt256];
|
||||
prevRandao: Hash256;
|
||||
difficulty: UInt256;
|
||||
miner: EthAddress;
|
||||
chainDB: BaseChainDB;
|
||||
tracerFlags: set[TracerFlags])
|
||||
@ -107,6 +110,7 @@ proc init(
|
||||
gasLimit = gasLimit,
|
||||
fee = fee,
|
||||
prevRandao= prevRandao,
|
||||
difficulty= difficulty,
|
||||
miner = miner,
|
||||
chainDB = chainDB,
|
||||
ttdReached= chainDB.isTtdReached(parent.blockHash),
|
||||
@ -130,6 +134,7 @@ proc new*(
|
||||
gasLimit: GasInt; ## tx env: gas limit
|
||||
fee: Option[UInt256]; ## tx env: optional base fee
|
||||
prevRandao: Hash256; ## tx env: POS block randomness
|
||||
difficulty: UInt256, ## tx env: difficulty
|
||||
miner: EthAddress; ## tx env: coinbase(PoW) or signer(PoA)
|
||||
chainDB: BaseChainDB; ## block chain database
|
||||
tracerFlags: set[TracerFlags] = {};
|
||||
@ -150,6 +155,7 @@ proc new*(
|
||||
gasLimit = gasLimit,
|
||||
fee = fee,
|
||||
prevRandao = prevRandao,
|
||||
difficulty = difficulty,
|
||||
miner = miner,
|
||||
chainDB = chainDB,
|
||||
tracerFlags = tracerFlags)
|
||||
@ -160,6 +166,7 @@ proc reinit*(self: BaseVMState; ## Object descriptor
|
||||
gasLimit: GasInt; ## tx env: gas limit
|
||||
fee: Option[UInt256]; ## tx env: optional base fee
|
||||
prevRandao:Hash256; ## tx env: POS block randomness
|
||||
difficulty:UInt256, ## tx env: difficulty
|
||||
miner: EthAddress; ## tx env: coinbase(PoW) or signer(PoA)
|
||||
pruneTrie: bool = true): bool
|
||||
{.gcsafe, raises: [Defect,CatchableError].} =
|
||||
@ -185,6 +192,7 @@ proc reinit*(self: BaseVMState; ## Object descriptor
|
||||
gasLimit = gasLimit,
|
||||
fee = fee,
|
||||
prevRandao = prevRandao,
|
||||
difficulty = difficulty,
|
||||
miner = miner,
|
||||
chainDB = db,
|
||||
ttdReached = db.isTtdReached(parent.blockHash),
|
||||
@ -209,6 +217,7 @@ proc reinit*(self: BaseVMState; ## Object descriptor
|
||||
gasLimit = header.gasLimit,
|
||||
fee = header.fee,
|
||||
prevRandao= header.prevRandao,
|
||||
difficulty= header.difficulty,
|
||||
miner = self.chainDB.getMinerAddress(header),
|
||||
pruneTrie = pruneTrie)
|
||||
|
||||
@ -247,6 +256,7 @@ proc init*(
|
||||
gasLimit = header.gasLimit,
|
||||
fee = header.fee,
|
||||
prevRandao = header.prevRandao,
|
||||
difficulty = header.difficulty,
|
||||
miner = chainDB.getMinerAddress(header),
|
||||
chainDB = chainDB,
|
||||
tracerFlags = tracerFlags)
|
||||
@ -290,13 +300,6 @@ proc new*(
|
||||
tracerFlags = tracerFlags,
|
||||
pruneTrie = pruneTrie)
|
||||
|
||||
|
||||
proc consensusEnginePoA*(vmState: BaseVMState): bool =
|
||||
# PoA consensus engine have no reward for miner
|
||||
# TODO: this need to be fixed somehow
|
||||
# using `real` engine configuration
|
||||
vmState.chainDB.config.poaEngine
|
||||
|
||||
method coinbase*(vmState: BaseVMState): EthAddress {.base, gcsafe.} =
|
||||
vmState.minerAddress
|
||||
|
||||
@ -310,7 +313,7 @@ method difficulty*(vmState: BaseVMState): UInt256 {.base, gcsafe.} =
|
||||
# EIP-4399/EIP-3675
|
||||
UInt256.fromBytesBE(vmState.prevRandao.data, allowPadding = false)
|
||||
else:
|
||||
vmState.chainDB.config.calcDifficulty(vmState.timestamp, vmState.parent)
|
||||
vmState.blockDifficulty
|
||||
|
||||
method baseFee*(vmState: BaseVMState): UInt256 {.base, gcsafe.} =
|
||||
if vmState.fee.isSome:
|
||||
|
@ -30,6 +30,7 @@ type
|
||||
gasLimit* : GasInt
|
||||
fee* : Option[UInt256]
|
||||
prevRandao* : Hash256
|
||||
blockDifficulty*: UInt256
|
||||
ttdReached* : bool
|
||||
name* : string
|
||||
flags* : set[VMFlag]
|
||||
|
@ -26,7 +26,6 @@ export
|
||||
vms.blockNumber,
|
||||
vms.buildWitness,
|
||||
vms.coinbase,
|
||||
vms.consensusEnginePoA,
|
||||
vms.difficulty,
|
||||
vms.disableTracing,
|
||||
vms.enableTracing,
|
||||
|
Loading…
x
Reference in New Issue
Block a user