diff --git a/nimbus/p2p/clique/clique_sealer.nim b/nimbus/p2p/clique/clique_sealer.nim index cbab38cb19..a7818cbd13 100644 --- a/nimbus/p2p/clique/clique_sealer.nim +++ b/nimbus/p2p/clique/clique_sealer.nim @@ -12,8 +12,6 @@ ## Mining Support for Clique PoA Consensus Protocol ## ================================================ ## -## Note that mining in currently unsupported by `NIMBUS` -## ## For details see ## `EIP-225 `_ ## 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 diff --git a/nimbus/sealer.nim b/nimbus/sealer.nim index 816c5e8cda..53885a077d 100644 --- a/nimbus/sealer.nim +++ b/nimbus/sealer.nim @@ -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) diff --git a/nimbus/utils/tx_pool.nim b/nimbus/utils/tx_pool.nim index b399b99e7a..3ee3b82b0b 100644 --- a/nimbus/utils/tx_pool.nim +++ b/nimbus/utils/tx_pool.nim @@ -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 # ------------------------------------------------------------------------------ diff --git a/nimbus/utils/tx_pool/tx_chain.nim b/nimbus/utils/tx_pool/tx_chain.nim index 736bc8c192..346c5eb80f 100644 --- a/nimbus/utils/tx_pool/tx_chain.nim +++ b/nimbus/utils/tx_pool/tx_chain.nim @@ -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 # ------------------------------------------------------------------------------ diff --git a/nimbus/vm/state.nim b/nimbus/vm/state.nim index b96d6ed495..b5ea2edee5 100644 --- a/nimbus/vm/state.nim +++ b/nimbus/vm/state.nim @@ -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: diff --git a/nimbus/vm/types.nim b/nimbus/vm/types.nim index 70d3eeaf7a..e0c4244258 100644 --- a/nimbus/vm/types.nim +++ b/nimbus/vm/types.nim @@ -39,6 +39,7 @@ type gasLimit* : GasInt fee* : Option[UInt256] prevRandao* : Hash256 + blockDifficulty*: UInt256 ttdReached* : bool name* : string flags* : set[VMFlag] diff --git a/nimbus/vm2/state.nim b/nimbus/vm2/state.nim index 57bed4fadb..1a409fc975 100644 --- a/nimbus/vm2/state.nim +++ b/nimbus/vm2/state.nim @@ -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: diff --git a/nimbus/vm2/types.nim b/nimbus/vm2/types.nim index 9c72e194c2..7fba453ecf 100644 --- a/nimbus/vm2/types.nim +++ b/nimbus/vm2/types.nim @@ -30,6 +30,7 @@ type gasLimit* : GasInt fee* : Option[UInt256] prevRandao* : Hash256 + blockDifficulty*: UInt256 ttdReached* : bool name* : string flags* : set[VMFlag] diff --git a/nimbus/vm_state.nim b/nimbus/vm_state.nim index e486b39aa5..c7519fd9e9 100644 --- a/nimbus/vm_state.nim +++ b/nimbus/vm_state.nim @@ -26,7 +26,6 @@ export vms.blockNumber, vms.buildWitness, vms.coinbase, - vms.consensusEnginePoA, vms.difficulty, vms.disableTracing, vms.enableTracing,