mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-21 00:08:28 +00:00
* Renamed source file clique_utils => clique_helpers why: New name is more in line with other modules where local libraries are named similarly. * re-implemented PoA verification module as clique_verify.nim details: The verification code was ported from the go sources and provisionally stored in the clique_misc.nim source file. todo: Bring it to life. * re-design Snapshot descriptor as: ref object why: Avoids some copying descriptor objects details: The snapshot management in clique_snapshot.nim has been cleaned up. todo: There is a lot of unnecessary copying & sub-list manipulation of seq[BlockHeader] lists which needs to be simplified by managing index intervals. * optimised sequence handling for Clique/PoA why: To much ado about nothing details: * Working with shallow sequences inside PoA processing avoids unnecessary copying. * Using degenerate lists in the cliqueVerify() batch where only the parent (and no other ancestor) is needed. todo: Expose only functions that are needed, shallow sequences should be handles with care. * fix var-parameter function argument * Activate PoA engine -- currently proof of concept details: PoA engine is activated with newChain(extraValidation = true) applied to a PoA network. status and todo: The extraValidation flag on the Chain object can be set at a later state which allows to pre-load parts of the block chain without verification. Setting it later will only go back the block chain to the latest epoch checkpoint. This is inherent to the Clique protocol, needs testing though. PoA engine works in fine weather mode on Goerli replay. With the canonical eip-225 tests, there are quite a few fringe conditions that fail. These can easily fudged over to make things work but need some more work to understand and correct properly. * Make the last offending verification header available why: Makes some fringe case tests work. details: Within a failed transaction comprising several blocks, this feature help to identify the offending block if there was a PoA verification error. * Make PoA header verifier store the final snapshot why: The last snapshot needed by the verifier is the one of the parent but the list of authorised signer is derived from the current snapshot. So updating to the latest snapshot provides the latest signers list. details: Also, PoA processing has been implemented as transaction in persistBlocks() with Clique state rollback. Clique tests succeed now. * Avoiding double yields in iterator => replaced by template why: Tanks to Andri who observed it (see #762) * Calibrate logging interval and fix logging event detection why: Logging interval as copied from Go implementation was too large and needed re-calibration. Elapsed time calculation was bonkers, negative the wrong way round.
280 lines
9.5 KiB
Nim
280 lines
9.5 KiB
Nim
# Nimbus
|
|
# Copyright (c) 2018 Status Research & Development GmbH
|
|
# Licensed under either of
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
|
# http://www.apache.org/licenses/LICENSE-2.0)
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
|
# http://opensource.org/licenses/MIT)
|
|
# at your option. This file may not be copied, modified, or distributed except
|
|
# according to those terms.
|
|
|
|
##
|
|
## Clique PoA Constants & Types
|
|
## ============================
|
|
##
|
|
## Constants used by Clique proof-of-authority consensus protocol, see
|
|
## `EIP-225 <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-225.md>`_
|
|
## and
|
|
## `go-ethereum <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-225.md>`_
|
|
##
|
|
|
|
import
|
|
std/[times],
|
|
eth/common,
|
|
stew/results,
|
|
stint
|
|
|
|
{.push raises: [].}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Constants copied from eip-225 specs & implementation
|
|
# ------------------------------------------------------------------------------
|
|
|
|
const
|
|
# clique/clique.go(48): const ( [..]
|
|
CHECKPOINT_INTERVAL* = ##\
|
|
## Number of blocks after which to save the vote snapshot to the database
|
|
1024
|
|
|
|
INMEMORY_SNAPSHOTS* = ##\
|
|
## Number of recent vote snapshots to keep in memory.
|
|
128
|
|
|
|
INMEMORY_SIGNATURES* = ##\
|
|
## Number of recent block signatures to keep in memory
|
|
4096
|
|
|
|
WIGGLE_TIME* = ##\
|
|
## PoA mining only (currently unsupported).
|
|
##
|
|
## Random delay (per signer) to allow concurrent signers
|
|
initDuration(seconds = 0, milliseconds = 500)
|
|
|
|
# clique/clique.go(57): var ( [..]
|
|
BLOCK_PERIOD* = ##\
|
|
## Minimum difference in seconds between two consecutive block timestamps.
|
|
## Suggested time is 15s for the `testnet` to remain analogous to the
|
|
## `mainnet` ethash target.
|
|
initDuration(seconds = 15)
|
|
|
|
EXTRA_VANITY* = ##\
|
|
## Fixed number of extra-data prefix bytes reserved for signer vanity.
|
|
## Suggested 32 bytes to retain the current extra-data allowance and/or use.
|
|
32
|
|
|
|
EXTRA_SEAL* = ##\
|
|
## Fixed number of extra-data suffix bytes reserved for signer seal.
|
|
## 65 bytes fixed as signatures are based on the standard secp256k1 curve.
|
|
65
|
|
|
|
NONCE_AUTH* = ##\
|
|
## Magic nonce number 0xffffffffffffffff to vote on adding a new signer.
|
|
0xffffffffffffffffu64.toBlockNonce
|
|
|
|
NONCE_DROP* = ##\
|
|
## Magic nonce number 0x0000000000000000 to vote on removing a signer.
|
|
0x0000000000000000u64.toBlockNonce
|
|
|
|
DIFF_NOTURN* = ##\
|
|
## Block score (difficulty) for blocks containing out-of-turn signatures.
|
|
## Suggested 1 since it just needs to be an arbitrary baseline constant.
|
|
1.u256
|
|
|
|
DIFF_INTURN* = ##\
|
|
## Block score (difficulty) for blocks containing in-turn signatures.
|
|
## Suggested 2 to show a slight preference over out-of-turn signatures.
|
|
2.u256
|
|
|
|
# params/network_params.go(60): FullImmutabilityThreshold = 90000
|
|
FULL_IMMUTABILITY_THRESHOLD* = ##\
|
|
## Number of blocks after which a chain segment is considered immutable (ie.
|
|
## soft finality). It is used by the downloader as a hard limit against
|
|
## deep ancestors, by the blockchain against deep reorgs, by the freezer as
|
|
## the cutoff threshold and by clique as the snapshot trust limit.
|
|
90000
|
|
|
|
# Other
|
|
SNAPS_LOG_INTERVAL_MICSECS* = ##\
|
|
## Time interval after which the `snapshotApply()` function main loop
|
|
## produces logging entries. The original value from the Go reference
|
|
## implementation has 8 seconds (which seems a bit long.) For the first
|
|
## 300k blocks in the Goerli chain, typical execution time in tests was
|
|
## mostly below 300 micro secs.
|
|
initDuration(microSeconds = 200)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Error tokens
|
|
# ------------------------------------------------------------------------------
|
|
|
|
type
|
|
# clique/clique.go(76): var ( [..]
|
|
CliqueErrorType* = enum
|
|
resetCliqueError = ##\
|
|
## Default/reset value (use `cliqueNoError` below rather than this valie)
|
|
(0, "no error")
|
|
|
|
errUnknownBlock = ##\
|
|
## is returned when the list of signers is requested for a block that is
|
|
## not part of the local blockchain.
|
|
"unknown block"
|
|
|
|
errInvalidCheckpointBeneficiary = ##\
|
|
## is returned if a checkpoint/epoch transition block has a beneficiary
|
|
## set to non-zeroes.
|
|
"beneficiary in checkpoint block non-zero"
|
|
|
|
errInvalidVote = ##\
|
|
## is returned if a nonce value is something else that the two allowed
|
|
## constants of 0x00..0 or 0xff..f.
|
|
"vote nonce not 0x00..0 or 0xff..f"
|
|
|
|
errInvalidCheckpointVote = ##\
|
|
## is returned if a checkpoint/epoch transition block has a vote nonce
|
|
## set to non-zeroes.
|
|
"vote nonce in checkpoint block non-zero"
|
|
|
|
errMissingVanity = ##\
|
|
## is returned if a block's extra-data section is shorter than 32 bytes,
|
|
## which is required to store the signer vanity.
|
|
"extra-data 32 byte vanity prefix missing"
|
|
|
|
errMissingSignature = ##\
|
|
## is returned if a block's extra-data section doesn't seem to contain a
|
|
## 65 byte secp256k1 signature.
|
|
"extra-data 65 byte signature suffix missing"
|
|
|
|
errExtraSigners = ##\
|
|
## is returned if non-checkpoint block contain signer data in their
|
|
## extra-data fields.
|
|
"non-checkpoint block contains extra signer list"
|
|
|
|
errInvalidCheckpointSigners = ##\
|
|
## is returned if a checkpoint block contains an invalid list of signers
|
|
## (i.e. non divisible by 20 bytes).
|
|
"invalid signer list on checkpoint block"
|
|
|
|
errMismatchingCheckpointSigners = ##\
|
|
## is returned if a checkpoint block contains a list of signers different
|
|
## than the one the local node calculated.
|
|
"mismatching signer list on checkpoint block"
|
|
|
|
errInvalidMixDigest = ##\
|
|
## is returned if a block's mix digest is non-zero.
|
|
"non-zero mix digest"
|
|
|
|
errInvalidUncleHash = ##\
|
|
## is returned if a block contains an non-empty uncle list.
|
|
"non empty uncle hash"
|
|
|
|
errInvalidDifficulty = ##\
|
|
## is returned if the difficulty of a block neither 1 or 2.
|
|
"invalid difficulty"
|
|
|
|
errWrongDifficulty = ##\
|
|
## is returned if the difficulty of a block doesn't match the turn of
|
|
## the signer.
|
|
"wrong difficulty"
|
|
|
|
errInvalidTimestamp = ##\
|
|
## is returned if the timestamp of a block is lower than the previous
|
|
## block's timestamp + the minimum block period.
|
|
"invalid timestamp"
|
|
|
|
errInvalidVotingChain = ##\
|
|
## is returned if an authorization list is attempted to be modified via
|
|
## out-of-range or non-contiguous headers.
|
|
"invalid voting chain"
|
|
|
|
errUnauthorizedSigner = ##\
|
|
## is returned if a header is signed by a non-authorized entity.
|
|
"unauthorized signer"
|
|
|
|
errRecentlySigned = ##\
|
|
## is returned if a header is signed by an authorized entity that
|
|
## already signed a header recently, thus is temporarily not allowed to.
|
|
"recently signed"
|
|
|
|
|
|
# additional errors sources elsewhere
|
|
# -----------------------------------
|
|
|
|
errPublicKeyToShort = ##\
|
|
## Cannot retrieve public key
|
|
"cannot retrieve public key: too short"
|
|
|
|
# imported from consensus/errors.go
|
|
errUnknownAncestor = ##\
|
|
## is returned when validating a block requires an ancestor that is
|
|
## unknown.
|
|
"unknown ancestor"
|
|
|
|
# errPrunedAncestor = ##\
|
|
# ## is returned when validating a block requires an ancestor that is
|
|
# ## known, but the state of which is not available.
|
|
# "pruned ancestor"
|
|
|
|
errFutureBlock = ##\
|
|
## is returned when a block's timestamp is in the future according to
|
|
## the current node.
|
|
"block in the future"
|
|
|
|
# errInvalidNumber = ##\
|
|
# ## is returned if a block's number doesn't equal its parent's plus one.
|
|
# "invalid block number"
|
|
|
|
|
|
# additional/bespoke errors, manually added
|
|
# -----------------------------------------
|
|
|
|
errUnknownHash = "No header found for hash value"
|
|
errEmptyLruCache = "No snapshot available"
|
|
|
|
errNotInitialised = ##\
|
|
## Initalisation value for `Result` entries
|
|
"Not initialised"
|
|
|
|
errSetLruSnaps = ##\
|
|
## Attempt to assign a value to a non-existing slot
|
|
"Missing LRU slot for snapshot"
|
|
|
|
errSkSigResult ## eth/keys subsytem error: signature
|
|
errSkPubKeyResult ## eth/keys subsytem error: public key
|
|
|
|
errSnapshotLoad ## DB subsytem error
|
|
errSnapshotStore ## ..
|
|
errSnapshotClone
|
|
|
|
errCliqueGasLimitOrBaseFee
|
|
errCliqueExceedsGasLimit
|
|
errCliqueGasRepriceFork
|
|
errCliqueSealSigFn
|
|
|
|
errCliqueStopped = "process was interrupted"
|
|
errCliqueUnclesNotAllowed = "uncles not allowed"
|
|
|
|
# not really an error
|
|
nilCliqueSealNoBlockYet = "Sealing paused, waiting for transactions"
|
|
nilCliqueSealSignedRecently = "Signed recently, must wait for others"
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# More types and constants
|
|
# ------------------------------------------------------------------------------
|
|
|
|
type
|
|
CliqueError* = ##\
|
|
## Error message, tinned component + explanatory text (if any)
|
|
(CliqueErrorType,string)
|
|
|
|
CliqueOkResult* = ##\
|
|
## Standard ok/error result type for `Clique` functions
|
|
Result[void,CliqueError]
|
|
|
|
const
|
|
cliqueNoError* = ##\
|
|
## No-error constant
|
|
(resetCliqueError, "")
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# End
|
|
# ------------------------------------------------------------------------------
|