diff --git a/nimbus/common/common.nim b/nimbus/common/common.nim index a50567e1e..54034ebb3 100644 --- a/nimbus/common/common.nim +++ b/nimbus/common/common.nim @@ -16,7 +16,8 @@ import ./evmforks, ./genesis, ../utils/[utils, ec_recover], - ../db/[db_chain, storage_types] + ../db/[db_chain, storage_types], + ../core/[pow, clique] export chain_config, @@ -65,13 +66,27 @@ type # one of POW/POA/POS, updated after calling `hardForkTransition` consensusType: ConsensusType + pow: PowRef ##\ + ## Wrapper around `hashimotoLight()` and lookup cache + + poa: Clique ##\ + ## For non-PoA networks this descriptor is ignored. + # ------------------------------------------------------------------------------ -# Private helper functions +# Forward declarations # ------------------------------------------------------------------------------ proc hardForkTransition*(com: CommonRef, number: BlockNumber, td: Option[DifficultyInt]) {.gcsafe.} +func cliquePeriod*(com: CommonRef): int + +func cliqueEpoch*(com: CommonRef): int + +# ------------------------------------------------------------------------------ +# Private helper functions +# ------------------------------------------------------------------------------ + proc consensusTransition(com: CommonRef, fork: HardFork) = if fork >= MergeFork: com.consensusType = ConsensusType.POS @@ -124,6 +139,13 @@ proc init(com : CommonRef, com.currentFork, com.db.db) com.setForkId(com.genesisHeader) + # Initalise the PoA state regardless of whether it is needed on the current + # network. For non-PoA networks this descriptor is ignored. + com.poa = newClique(com.db, com.cliquePeriod, com.cliqueEpoch) + + # Always initialise the PoW epoch cache even though it migh no be used + com.pow = PowRef.new + # ------------------------------------------------------------------------------ # Public constructors # ------------------------------------------------------------------------------ @@ -226,8 +248,10 @@ proc hardForkTransition*(com: CommonRef, parentHash: Hash256, number: BlockNumber) {.gcsafe, raises: [Defect, CatchableError].} = + # if mergeForkBlock is present, it has higher + # priority than TTD if com.config.mergeForkBlock.isSome or - com.config.terminalTotalDifficulty.isSome: + com.config.terminalTotalDifficulty.isNone: let fork = com.toHardFork(number) com.currentFork = fork com.consensusTransition(fork) @@ -325,6 +349,13 @@ proc initializeEmptyDb*(com: CommonRef) # ------------------------------------------------------------------------------ # Getters # ------------------------------------------------------------------------------ +proc poa*(com: CommonRef): Clique = + ## Getter + com.poa + +proc pow*(com: CommonRef): PowRef = + ## Getter + com.pow func db*(com: CommonRef): ChainDBRef = com.db diff --git a/nimbus/core/chain/chain_desc.nim b/nimbus/core/chain/chain_desc.nim index 405842061..9bf1fe5f0 100644 --- a/nimbus/core/chain/chain_desc.nim +++ b/nimbus/core/chain/chain_desc.nim @@ -38,58 +38,31 @@ type ## First block to when `extraValidation` will be applied (only ## effective if `extraValidation` is true.) - pow: PowRef ##\ - ## Wrapper around `hashimotoLight()` and lookup cache - - poa: Clique ##\ - ## For non-PoA networks (when `db.config.poaEngine` is `false`), - ## this descriptor is ignored. - {.push raises: [Defect].} # ------------------------------------------------------------------------------ # Private constructor helper # ------------------------------------------------------------------------------ -proc initChain(c: ChainRef; com: CommonRef; poa: Clique; extraValidation: bool) +proc initChain(c: ChainRef; com: CommonRef; extraValidation: bool) {.gcsafe, raises: [Defect,CatchableError].} = - ## Constructor for the `Chain` descriptor object. For most applications, - ## the `poa` argument is transparent and should be initilaised on the fly - ## which is available below. + ## Constructor for the `Chain` descriptor object. c.com = com c.validateBlock = true c.extraValidation = extraValidation - # Initalise the PoA state regardless of whether it is needed on the current - # network. For non-PoA networks (when `db.config.poaEngine` is `false`), - # this descriptor is ignored. - c.poa = com.newClique - - # Always initialise the PoW epoch cache even though it migh no be used - # unless `extraValidation` is set `true`. - c.pow = PowRef.new - # ------------------------------------------------------------------------------ # Public constructors # ------------------------------------------------------------------------------ -proc newChain*(com: CommonRef; poa: Clique; extraValidation: bool): ChainRef - {.gcsafe, raises: [Defect,CatchableError].} = - ## Constructor for the `Chain` descriptor object. For most applications, - ## the `poa` argument is transparent and should be initilaised on the fly - ## which is available below. The argument `extraValidation` enables extra - ## block chain validation if set `true`. - new result - result.initChain(com, poa, extraValidation) - proc newChain*(com: CommonRef, extraValidation: bool): ChainRef {.gcsafe, raises: [Defect,CatchableError].} = - ## Constructor for the `Chain` descriptor object with default initialisation - ## for the PoA handling. The argument `extraValidation` enables extra block + ## Constructor for the `Chain` descriptor object. + ## The argument `extraValidation` enables extra block ## chain validation if set `true`. new result - result.initChain(com, com.newClique, extraValidation) + result.initChain(com, extraValidation) proc newChain*(com: CommonRef): ChainRef {.gcsafe, raises: [Defect,CatchableError].} = @@ -98,19 +71,18 @@ proc newChain*(com: CommonRef): ChainRef ## * `enabled` for PoA networks (such as Goerli) ## * `disabled` for non-PaA networks new result - result.initChain(com, com.newClique, com.consensus == ConsensusType.POA) + result.initChain(com, com.consensus == ConsensusType.POA) # ------------------------------------------------------------------------------ # Public `Chain` getters # ------------------------------------------------------------------------------ - -proc clique*(c: ChainRef): var Clique = +proc clique*(c: ChainRef): Clique = ## Getter - c.poa + c.com.poa proc pow*(c: ChainRef): PowRef = ## Getter - c.pow + c.com.pow proc db*(c: ChainRef): ChainDBRef = ## Getter diff --git a/nimbus/core/chain/persist_blocks.nim b/nimbus/core/chain/persist_blocks.nim index 0cc84c653..9c2501e29 100644 --- a/nimbus/core/chain/persist_blocks.nim +++ b/nimbus/core/chain/persist_blocks.nim @@ -11,6 +11,7 @@ import ../../vm_state, ../../vm_types, + ../clique/clique_verify, ../clique, ../executor, ../validate, @@ -96,7 +97,7 @@ proc persistBlocksImpl(c: ChainRef; headers: openArray[BlockHeader]; if c.com.consensus == ConsensusType.POA: var parent = if 0 < i: @[headers[i-1]] else: @[] - let rc = c.clique.cliqueVerify(header,parent) + let rc = c.clique.cliqueVerify(c.com, header,parent) if rc.isOk: # mark it off so it would not auto-restore previous state c.clique.cliqueDispose(cliqueState) diff --git a/nimbus/core/clique.nim b/nimbus/core/clique.nim index dee5a90e0..6ebb67fdf 100644 --- a/nimbus/core/clique.nim +++ b/nimbus/core/clique.nim @@ -19,8 +19,8 @@ ## import - std/[sequtils, times], - ./clique/[clique_cfg, clique_defs, clique_desc, clique_verify], + std/[times], + ./clique/[clique_cfg, clique_defs, clique_desc], ./clique/snapshot/[ballot, snapshot_desc], stew/results @@ -44,7 +44,7 @@ type # Public # ------------------------------------------------------------------------------ -proc newClique*(com: CommonRef): Clique = +proc newClique*(db: ChainDBRef, cliquePeriod, cliqueEpoch: int): Clique = ## Constructor for a new Clique proof-of-authority consensus engine. The ## initial state of the engine is `empty`, there are no authorised signers. ## @@ -52,20 +52,20 @@ proc newClique*(com: CommonRef): Clique = ## will be taken from chain_config. Otherwise, default value in `newCliqueCfg` ## will be used - let cfg = com.newCliqueCfg - if com.cliquePeriod > 0: - cfg.period = initDuration(seconds = com.cliquePeriod) - if com.cliqueEpoch > 0: - cfg.epoch = com.cliqueEpoch + let cfg = db.newCliqueCfg + if cliquePeriod > 0: + cfg.period = initDuration(seconds = cliquePeriod) + if cliqueEpoch > 0: + cfg.epoch = cliqueEpoch cfg.newClique -proc cliqueSave*(c: var Clique): CliqueState = +proc cliqueSave*(c: Clique): CliqueState = ## Save current `Clique` state. This state snapshot saves the internal ## data that make up the list of authorised signers (see `cliqueSigners()` ## below.) ok(c.snapshot) -proc cliqueRestore*(c: var Clique; state: var CliqueState) = +proc cliqueRestore*(c: Clique; state: var CliqueState) = ## Restore current `Clique` state from a saved snapshot. ## ## For the particular `state` argument this fuction is disabled with @@ -74,7 +74,7 @@ proc cliqueRestore*(c: var Clique; state: var CliqueState) = if state.isOk: c.snapshot = state.value -proc cliqueDispose*(c: var Clique; state: var CliqueState) = +proc cliqueDispose*(c: Clique; state: var CliqueState) = ## Disable the function `cliqueDispose()` for the particular `state` ## argument. ## @@ -82,59 +82,6 @@ proc cliqueDispose*(c: var Clique; state: var CliqueState) = ## `cliqueRestore()` was wrapped in a `defer:` statement. state = err(CliqueState) - -proc cliqueVerify*(c: Clique; header: BlockHeader; - parents: openArray[BlockHeader]): CliqueOkResult - {.gcsafe, raises: [Defect,CatchableError].} = - ## Check whether a header conforms to the consensus rules. The caller may - ## optionally pass on a batch of parents (ascending order) to avoid looking - ## those up from the database. This function updates the list of authorised - ## signers (see `cliqueSigners()` below.) - ## - ## On success, the latest authorised signers list is available via the - ## fucntion `c.cliqueSigners()`. Otherwise, the latest error is also stored - ## in the `Clique` descriptor and is accessible as `c.failed`. - ## - ## This function is not transaction-save, that is the internal state of - ## the authorised signers list has the state of the last update after a - ## successful header verification. The hash of the failing header together - ## with the error message is then accessible as `c.failed`. - ## - ## Use the directives `cliqueSave()`, `cliqueDispose()`, and/or - ## `cliqueRestore()` for transaction. - var list = toSeq(parents) - c.cliqueVerifySeq(header, list) - -# clique/clique.go(217): func (c *Clique) VerifyHeader(chain [..] -proc cliqueVerify*(c: Clique; header: BlockHeader): CliqueOkResult - {.gcsafe, raises: [Defect,CatchableError].} = - ## Consensus rules verifier without optional parents list. - var blind: seq[BlockHeader] - c.cliqueVerifySeq(header, blind) - -proc cliqueVerify*(c: Clique; - headers: openArray[BlockHeader]): CliqueOkResult - {.gcsafe, raises: [Defect,CatchableError].} = - ## This function verifies a batch of headers checking each header for - ## consensus rules conformance (see also the other `cliqueVerify()` function - ## instance.) The `headers` list is supposed to contain a chain of headers, - ## i.e. `headers[i]` is parent to `headers[i+1]`. - ## - ## On success, the latest authorised signers list is available via the - ## fucntion `c.cliqueSigners()`. Otherwise, the latest error is also stored - ## in the `Clique` descriptor and is accessible as `c.failed`. - ## - ## This function is not transaction-save, that is the internal state of - ## the authorised signers list has the state of the last update after a - ## successful header verification. The hash of the failing header together - ## with the error message is then accessible as `c.failed`. - ## - ## Use the directives `cliqueSave()`, `cliqueDispose()`, and/or - ## `cliqueRestore()` for transaction. - var list = toSeq(headers) - c.cliqueVerifySeq(list) - - proc cliqueSigners*(c: Clique): seq[EthAddress] {.inline.} = ## Retrieve the sorted list of authorized signers for the current state ## of the `Clique` descriptor. diff --git a/nimbus/core/clique/clique_cfg.nim b/nimbus/core/clique/clique_cfg.nim index fded5530f..1be790f3a 100644 --- a/nimbus/core/clique/clique_cfg.nim +++ b/nimbus/core/clique/clique_cfg.nim @@ -22,20 +22,20 @@ import std/[random, times], ethash, stew/results, - ../../common/common, + ../../db/db_chain, ../../utils/ec_recover, ./clique_defs export - common + db_chain const prngSeed = 42 type CliqueCfg* = ref object of RootRef - com*: CommonRef ##\ - ## Configuration, database. + db*: ChainDBRef ##\ + ## All purpose (incl. blockchain) database. nSnaps*: uint64 ##\ ## Number of snapshots stored on disk (for logging troublesshoting) @@ -79,9 +79,9 @@ type # Public constructor # ------------------------------------------------------------------------------ -proc newCliqueCfg*(com: CommonRef): CliqueCfg = +proc newCliqueCfg*(db: ChainDBRef): CliqueCfg = result = CliqueCfg( - com: com, + db: db, epoch: EPOCH_LENGTH, period: BLOCK_PERIOD, ckpInterval: CHECKPOINT_INTERVAL, diff --git a/nimbus/core/clique/clique_desc.nim b/nimbus/core/clique/clique_desc.nim index c0d1b848c..6990faff1 100644 --- a/nimbus/core/clique/clique_desc.nim +++ b/nimbus/core/clique/clique_desc.nim @@ -159,9 +159,9 @@ proc cfg*(c: Clique): CliqueCfg = ## Getter c.cfg -proc com*(c: Clique): CommonRef = +proc db*(c: Clique): ChainDBRef = ## Getter - c.cfg.com + c.cfg.db proc applySnapsMinBacklog*(c: Clique): bool = ## Getter. @@ -180,9 +180,9 @@ proc applySnapsMinBacklog*(c: Clique): bool = # Public setters # ------------------------------------------------------------------------------ -proc `com=`*(c: Clique; com: CommonRef) = +proc `db=`*(c: Clique; db: ChainDBRef) = ## Setter, re-set database - c.cfg.com = com + c.cfg.db = db c.proposals = initTable[EthAddress,bool]() proc `snapshot=`*(c: Clique; snaps: Snapshot) = diff --git a/nimbus/core/clique/clique_genvote.nim b/nimbus/core/clique/clique_genvote.nim index d3c360b2a..e6e5265f3 100644 --- a/nimbus/core/clique/clique_genvote.nim +++ b/nimbus/core/clique/clique_genvote.nim @@ -198,7 +198,7 @@ proc cliqueGenvote*( ## [..] ## c.clique_genvote(voter, seal, - parent = c.cfg.com.db.getCanonicalHead, + parent = c.cfg.db.getCanonicalHead, elapsed = elapsed, voteInOk = voteInOk, outOfTurn = outOfTurn, diff --git a/nimbus/core/clique/clique_sealer.nim b/nimbus/core/clique/clique_sealer.nim index 7c6167559..bb6c44d4d 100644 --- a/nimbus/core/clique/clique_sealer.nim +++ b/nimbus/core/clique/clique_sealer.nim @@ -22,8 +22,9 @@ import std/[sequtils, times], chronicles, chronos, - eth/[common, keys, rlp], + eth/[keys, rlp], "../.."/[constants, utils/ec_recover], + ../../common/common, ./clique_cfg, ./clique_defs, ./clique_desc, @@ -53,18 +54,18 @@ template syncExceptionWrap(action: untyped) = # clique/clique.go(217): func (c *Clique) VerifyHeader(chain [..] -proc verifyHeader(c: Clique; header: BlockHeader): CliqueOkResult +proc verifyHeader(c: Clique; com: CommonRef; header: BlockHeader): CliqueOkResult {.gcsafe, raises: [Defect,CatchableError].} = ## See `clique.cliqueVerify()` var blind: seq[BlockHeader] - c.cliqueVerifySeq(header, blind) + c.cliqueVerifySeq(com, header, blind) -proc verifyHeader(c: Clique; header: BlockHeader; +proc verifyHeader(c: Clique; com: CommonRef; header: BlockHeader; parents: openArray[BlockHeader]): CliqueOkResult {.gcsafe, raises: [Defect,CatchableError].} = ## See `clique.cliqueVerify()` var list = toSeq(parents) - c.cliqueVerifySeq(header, list) + c.cliqueVerifySeq(com, header, list) proc isValidVote(s: Snapshot; a: EthAddress; authorize: bool): bool = @@ -118,7 +119,7 @@ proc author*(c: Clique; header: BlockHeader): Result[EthAddress,UtilsError] # clique/clique.go(224): func (c *Clique) VerifyHeader(chain [..] -proc verifyHeaders*(c: Clique; headers: openArray[BlockHeader]): +proc verifyHeaders*(c: Clique; com: CommonRef; headers: openArray[BlockHeader]): Future[seq[CliqueOkResult]] {.async,gcsafe.} = ## For the Consensus Engine, `verifyHeader()` s similar to VerifyHeader, but ## verifies a batch of headers concurrently. This method is accompanied @@ -136,7 +137,7 @@ proc verifyHeaders*(c: Clique; headers: openArray[BlockHeader]): if isStopRequest: result.add cliqueResultErr((errCliqueStopped,"")) break - result.add c.verifyHeader(headers[n], headers[0 ..< n]) + result.add c.verifyHeader(com, headers[n], headers[0 ..< n]) c.doExclusively: c.stopVHeaderReq = false diff --git a/nimbus/core/clique/clique_snapshot.nim b/nimbus/core/clique/clique_snapshot.nim index 352e72493..d467ea9ae 100644 --- a/nimbus/core/clique/clique_snapshot.nim +++ b/nimbus/core/clique/clique_snapshot.nim @@ -221,7 +221,7 @@ proc findSnapshot(d: var LocalSnaps): bool return false # No explicit parents (or no more parents left), reach out to the database - elif not d.c.cfg.com.db.getBlockHeader(hash, header): + elif not d.c.cfg.db.getBlockHeader(hash, header): d.trail.error = (errUnknownAncestor,"") return false @@ -377,7 +377,7 @@ proc cliqueSnapshotSeq*(c: Clique; hash: Hash256; return ok(rc.value) var header: BlockHeader - if not c.cfg.com.db.getBlockHeader(hash, header): + if not c.cfg.db.getBlockHeader(hash, header): return err((errUnknownHash,"")) # Avoid deep copy, sequence will not be changed by `updateSnapshot()` diff --git a/nimbus/core/clique/clique_verify.nim b/nimbus/core/clique/clique_verify.nim index c8ec37cc4..0f34192dc 100644 --- a/nimbus/core/clique/clique_verify.nim +++ b/nimbus/core/clique/clique_verify.nim @@ -21,8 +21,9 @@ ## import - std/[strformat, times], + std/[strformat, times, sequtils], ../../utils/utils, + ../../common/common, ../gaslimit, ./clique_cfg, ./clique_defs, @@ -43,17 +44,17 @@ logScope: # ------------------------------------------------------------------------------ # consensus/misc/forks.go(30): func VerifyForkHashes(config [..] -proc verifyForkHashes(c: Clique; header: BlockHeader): CliqueOkResult +proc verifyForkHashes(com: CommonRef; header: BlockHeader): CliqueOkResult {.gcsafe, raises: [Defect,ValueError].} = ## Verify that blocks conforming to network hard-forks do have the correct ## hashes, to avoid clients going off on different chains. - if c.com.eip150Block.isSome and - c.com.eip150Block.get == header.blockNumber: + if com.eip150Block.isSome and + com.eip150Block.get == header.blockNumber: # If the homestead reprice hash is set, validate it let - eip150 = c.com.eip150Hash + eip150 = com.eip150Hash hash = header.blockHash if eip150 != hash: @@ -138,7 +139,7 @@ proc verifySeal(c: Clique; header: BlockHeader): CliqueOkResult # clique/clique.go(314): func (c *Clique) verifyCascadingFields(chain [..] -proc verifyCascadingFields(c: Clique; header: BlockHeader; +proc verifyCascadingFields(c: Clique; com: CommonRef; header: BlockHeader; parents: var seq[BlockHeader]): CliqueOkResult {.gcsafe, raises: [Defect,CatchableError].} = ## Verify all the header fields that are not standalone, rather depend on a @@ -154,7 +155,7 @@ proc verifyCascadingFields(c: Clique; header: BlockHeader; var parent: BlockHeader if 0 < parents.len: parent = parents[^1] - elif not c.com.db.getBlockHeader(header.blockNumber-1, parent): + elif not c.db.getBlockHeader(header.blockNumber-1, parent): return err((errUnknownAncestor,"")) if parent.blockNumber != header.blockNumber-1 or @@ -177,7 +178,7 @@ proc verifyCascadingFields(c: Clique; header: BlockHeader; # EIP-1559/London fork. block: # clique/clique.go(337): if !chain.Config().IsLondon(header.Number) { - let rc = c.com.validateGasLimitOrBaseFee(header, parent) + let rc = com.validateGasLimitOrBaseFee(header, parent) if rc.isErr: return err((errCliqueGasLimitOrBaseFee, rc.error)) @@ -264,7 +265,7 @@ proc verifyHeaderFields(c: Clique; header: BlockHeader): CliqueOkResult # clique/clique.go(246): func (c *Clique) verifyHeader(chain [..] -proc cliqueVerifyImpl*(c: Clique; header: BlockHeader; +proc cliqueVerifyImpl(c: Clique; com: CommonRef; header: BlockHeader; parents: var seq[BlockHeader]): CliqueOkResult {.gcsafe, raises: [Defect,CatchableError].} = ## Check whether a header conforms to the consensus rules. The caller may @@ -282,21 +283,17 @@ proc cliqueVerifyImpl*(c: Clique; header: BlockHeader; block: # If all checks passed, validate any special fields for hard forks - let rc = c.verifyForkHashes(header) + let rc = com.verifyForkHashes(header) if rc.isErr: c.failed = (header.blockHash, rc.error) return err(rc.error) # All basic checks passed, verify cascading fields - result = c.verifyCascadingFields(header, parents) + result = c.verifyCascadingFields(com, header, parents) if result.isErr: c.failed = (header.blockHash, result.error) -# ------------------------------------------------------------------------------ -# Public function -# ------------------------------------------------------------------------------ - -proc cliqueVerifySeq*(c: Clique; header: BlockHeader; +proc cliqueVerifySeq*(c: Clique; com: CommonRef; header: BlockHeader; parents: var seq[BlockHeader]): CliqueOkResult {.gcsafe, raises: [Defect,CatchableError].} = ## Check whether a header conforms to the consensus rules. The caller may @@ -312,7 +309,7 @@ proc cliqueVerifySeq*(c: Clique; header: BlockHeader; ## descriptor and can be retrieved via `c.failed` along with the hash/ID of ## the failed block header. block: - let rc = c.cliqueVerifyImpl(header, parents) + let rc = c.cliqueVerifyImpl(com, header, parents) if rc.isErr: return rc @@ -325,8 +322,7 @@ proc cliqueVerifySeq*(c: Clique; header: BlockHeader; ok() - -proc cliqueVerifySeq*(c: Clique; +proc cliqueVerifySeq(c: Clique; com: CommonRef; headers: var seq[BlockHeader]): CliqueOkResult {.gcsafe, raises: [Defect,CatchableError].} = ## This function verifies a batch of headers checking each header for @@ -348,13 +344,13 @@ proc cliqueVerifySeq*(c: Clique; block: var blind: seq[BlockHeader] - let rc = c.cliqueVerifyImpl(headers[0],blind) + let rc = c.cliqueVerifyImpl(com, headers[0],blind) if rc.isErr: return rc for n in 1 ..< headers.len: var parent = headers[n-1 .. n-1] # is actually a single item squence - let rc = c.cliqueVerifyImpl(headers[n],parent) + let rc = c.cliqueVerifyImpl(com, headers[n],parent) if rc.isErr: return rc @@ -367,6 +363,61 @@ proc cliqueVerifySeq*(c: Clique; ok() +# ------------------------------------------------------------------------------ +# Public functions +# ------------------------------------------------------------------------------ + +proc cliqueVerify*(c: Clique; com: CommonRef; header: BlockHeader; + parents: openArray[BlockHeader]): CliqueOkResult + {.gcsafe, raises: [Defect,CatchableError].} = + ## Check whether a header conforms to the consensus rules. The caller may + ## optionally pass on a batch of parents (ascending order) to avoid looking + ## those up from the database. This function updates the list of authorised + ## signers (see `cliqueSigners()` below.) + ## + ## On success, the latest authorised signers list is available via the + ## fucntion `c.cliqueSigners()`. Otherwise, the latest error is also stored + ## in the `Clique` descriptor and is accessible as `c.failed`. + ## + ## This function is not transaction-save, that is the internal state of + ## the authorised signers list has the state of the last update after a + ## successful header verification. The hash of the failing header together + ## with the error message is then accessible as `c.failed`. + ## + ## Use the directives `cliqueSave()`, `cliqueDispose()`, and/or + ## `cliqueRestore()` for transaction. + var list = toSeq(parents) + c.cliqueVerifySeq(com, header, list) + +# clique/clique.go(217): func (c *Clique) VerifyHeader(chain [..] +proc cliqueVerify*(c: Clique; com: CommonRef; header: BlockHeader): CliqueOkResult + {.gcsafe, raises: [Defect,CatchableError].} = + ## Consensus rules verifier without optional parents list. + var blind: seq[BlockHeader] + c.cliqueVerifySeq(com, header, blind) + +proc cliqueVerify*(c: Clique; com: CommonRef; + headers: openArray[BlockHeader]): CliqueOkResult + {.gcsafe, raises: [Defect,CatchableError].} = + ## This function verifies a batch of headers checking each header for + ## consensus rules conformance (see also the other `cliqueVerify()` function + ## instance.) The `headers` list is supposed to contain a chain of headers, + ## i.e. `headers[i]` is parent to `headers[i+1]`. + ## + ## On success, the latest authorised signers list is available via the + ## fucntion `c.cliqueSigners()`. Otherwise, the latest error is also stored + ## in the `Clique` descriptor and is accessible as `c.failed`. + ## + ## This function is not transaction-save, that is the internal state of + ## the authorised signers list has the state of the last update after a + ## successful header verification. The hash of the failing header together + ## with the error message is then accessible as `c.failed`. + ## + ## Use the directives `cliqueSave()`, `cliqueDispose()`, and/or + ## `cliqueRestore()` for transaction. + var list = toSeq(headers) + c.cliqueVerifySeq(com, list) + # ------------------------------------------------------------------------------ # End # ------------------------------------------------------------------------------ diff --git a/nimbus/core/clique/snapshot/snapshot_desc.nim b/nimbus/core/clique/snapshot/snapshot_desc.nim index ff53753ed..a7f852ef1 100644 --- a/nimbus/core/clique/snapshot/snapshot_desc.nim +++ b/nimbus/core/clique/snapshot/snapshot_desc.nim @@ -144,7 +144,7 @@ proc loadSnapshot*(cfg: CliqueCfg; hash: Hash256): ## Load an existing snapshot from the database. var s = Snapshot(cfg: cfg) try: - let db = s.cfg.com.db.db + let db = s.cfg.db.db let rlpData = db.get(hash.cliqueSnapshotKey.toOpenArray) # The following check is only needed for Github/CI for 64bit Windows (not @@ -168,7 +168,7 @@ proc storeSnapshot*(cfg: CliqueCfg; s: Snapshot): CliqueOkResult = let key = s.data.blockHash.cliqueSnapshotKey val = rlp.encode(s.data) - db = s.cfg.com.db.db + db = s.cfg.db.db db.put(key.toOpenArray, val) cfg.nSnaps.inc diff --git a/nimbus/core/tx_pool/tx_chain.nim b/nimbus/core/tx_pool/tx_chain.nim index 9d1a23940..5a71edb3b 100644 --- a/nimbus/core/tx_pool/tx_chain.nim +++ b/nimbus/core/tx_pool/tx_chain.nim @@ -80,6 +80,10 @@ proc resetTxEnv(dh: TxChainRef; parent: BlockHeader; fee: Option[UInt256]) {.gcsafe,raises: [Defect,CatchableError].} = dh.txEnv.reset + # do hardfork transition before + # BaseVMState querying any hardfork/consensus from CommonRef + dh.com.hardForkTransition(parent.blockHash, parent.blockNumber+1) + let timestamp = getTime().utc.toTime # we don't consider PoS difficulty here # because that is handled in vmState @@ -95,7 +99,6 @@ proc resetTxEnv(dh: TxChainRef; parent: BlockHeader; fee: Option[UInt256]) dh.txEnv.txRoot = EMPTY_ROOT_HASH dh.txEnv.stateRoot = dh.txEnv.vmState.parent.stateRoot - dh.com.hardForkTransition(parent.blockHash, parent.blockNumber+1) proc update(dh: TxChainRef; parent: BlockHeader) {.gcsafe,raises: [Defect,CatchableError].} = diff --git a/tests/test_clique/pool.nim b/tests/test_clique/pool.nim index 167d04b09..7d504f697 100644 --- a/tests/test_clique/pool.nim +++ b/tests/test_clique/pool.nim @@ -59,11 +59,11 @@ type proc getBlockHeader(ap: TesterPool; number: BlockNumber): BlockHeader = ## Shortcut => db/db_chain.getBlockHeader() - doAssert ap.chain.clique.com.db.getBlockHeader(number, result) + doAssert ap.chain.clique.db.getBlockHeader(number, result) proc getBlockHeader(ap: TesterPool; hash: Hash256): BlockHeader = ## Shortcut => db/db_chain.getBlockHeader() - doAssert ap.chain.clique.com.db.getBlockHeader(hash, result) + doAssert ap.chain.clique.db.getBlockHeader(hash, result) proc isZero(a: openArray[byte]): bool = result = true @@ -306,7 +306,7 @@ proc clique*(ap: TesterPool): Clique = proc db*(ap: TesterPool): ChainDBRef = ## Getter - ap.clique.com.db + ap.clique.db proc cliqueSigners*(ap: TesterPool): seq[EthAddress] = ## Getter @@ -443,7 +443,7 @@ proc commitVoterChain*(ap: TesterPool; postProcessOk = false; # Realign rest of transaction to existing block chain if reChainOk: - var parent = ap.chain.clique.com.db.getCanonicalHead + var parent = ap.chain.clique.db.getCanonicalHead for i in 0 ..< headers.len: headers[i].parentHash = parent.blockHash headers[i].blockNumber = parent.blockNumber + 1 diff --git a/tests/test_txpool.nim b/tests/test_txpool.nim index 64c7be370..c3c54b27b 100644 --- a/tests/test_txpool.nim +++ b/tests/test_txpool.nim @@ -818,7 +818,7 @@ proc runTxPackerTests(noisy = true) = " size=", mostlySize + blk.txs[n].gasLimit - blk.header.gasUsed let - poa = bcCom.newClique + poa = bcCom.poa bdy = BlockBody(transactions: blk.txs) hdr = block: var rc = blk.header