mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-12 13:24:21 +00:00
fix txpool: using consensus rule to prepare header
This commit is contained in:
parent
b81511fcfc
commit
a26a9f9ece
@ -17,7 +17,7 @@ import
|
|||||||
./genesis,
|
./genesis,
|
||||||
../utils/[utils, ec_recover],
|
../utils/[utils, ec_recover],
|
||||||
../db/[db_chain, storage_types],
|
../db/[db_chain, storage_types],
|
||||||
../core/[pow, clique]
|
../core/[pow, clique, casper]
|
||||||
|
|
||||||
export
|
export
|
||||||
chain_config,
|
chain_config,
|
||||||
@ -72,6 +72,9 @@ type
|
|||||||
poa: Clique ##\
|
poa: Clique ##\
|
||||||
## For non-PoA networks this descriptor is ignored.
|
## For non-PoA networks this descriptor is ignored.
|
||||||
|
|
||||||
|
pos: CasperRef
|
||||||
|
## Proof Of Stake descriptor
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Forward declarations
|
# Forward declarations
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@ -145,6 +148,7 @@ proc init(com : CommonRef,
|
|||||||
|
|
||||||
# Always initialise the PoW epoch cache even though it migh no be used
|
# Always initialise the PoW epoch cache even though it migh no be used
|
||||||
com.pow = PowRef.new
|
com.pow = PowRef.new
|
||||||
|
com.pos = CasperRef.new
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public constructors
|
# Public constructors
|
||||||
@ -197,7 +201,10 @@ proc clone*(com: CommonRef, db: TrieDatabaseRef): CommonRef =
|
|||||||
syncProgress : com.syncProgress,
|
syncProgress : com.syncProgress,
|
||||||
networkId : com.networkId,
|
networkId : com.networkId,
|
||||||
currentFork : com.currentFork,
|
currentFork : com.currentFork,
|
||||||
consensusType: com.consensusType
|
consensusType: com.consensusType,
|
||||||
|
pow : com.pow,
|
||||||
|
poa : com.poa,
|
||||||
|
pos : com.pos
|
||||||
)
|
)
|
||||||
|
|
||||||
proc clone*(com: CommonRef): CommonRef =
|
proc clone*(com: CommonRef): CommonRef =
|
||||||
@ -357,6 +364,10 @@ proc pow*(com: CommonRef): PowRef =
|
|||||||
## Getter
|
## Getter
|
||||||
com.pow
|
com.pow
|
||||||
|
|
||||||
|
proc pos*(com: CommonRef): CasperRef =
|
||||||
|
## Getter
|
||||||
|
com.pos
|
||||||
|
|
||||||
func db*(com: CommonRef): ChainDBRef =
|
func db*(com: CommonRef): ChainDBRef =
|
||||||
com.db
|
com.db
|
||||||
|
|
||||||
|
54
nimbus/core/casper.nim
Normal file
54
nimbus/core/casper.nim
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
# Nimbus
|
||||||
|
# Copyright (c) 2022 Status Research & Development GmbH
|
||||||
|
# Licensed under either of
|
||||||
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||||
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||||
|
# at your option.
|
||||||
|
# This file may not be copied, modified, or distributed except according to
|
||||||
|
# those terms.
|
||||||
|
import
|
||||||
|
eth/common
|
||||||
|
|
||||||
|
type
|
||||||
|
CasperRef* = ref object
|
||||||
|
feeRecipient : EthAddress
|
||||||
|
timestamp : EthTime
|
||||||
|
prevRandao : Hash256
|
||||||
|
|
||||||
|
proc prepare*(ctx: CasperRef, header: var BlockHeader) =
|
||||||
|
header.coinbase = ctx.feeRecipient
|
||||||
|
header.timestamp = ctx.timestamp
|
||||||
|
header.prevRandao = ctx.prevRandao
|
||||||
|
header.difficulty = DifficultyInt.zero
|
||||||
|
|
||||||
|
proc prepareForSeal*(ctx: CasperRef, header: var BlockHeader) =
|
||||||
|
header.nonce = default(BlockNonce)
|
||||||
|
header.extraData = @[] # TODO: probably this should be configurable by user?
|
||||||
|
# this repetition, assigning prevRandao is because how txpool works
|
||||||
|
header.prevRandao = ctx.prevRandao
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Getters
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
func feeRecipient*(ctx: CasperRef): EthAddress =
|
||||||
|
ctx.feeRecipient
|
||||||
|
|
||||||
|
func timestamp*(ctx: CasperRef): EthTime =
|
||||||
|
ctx.timestamp
|
||||||
|
|
||||||
|
func prevRandao*(ctx: CasperRef): Hash256 =
|
||||||
|
ctx.prevRandao
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Setters
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
proc `feeRecipient=`*(ctx: CasperRef, val: EthAddress) =
|
||||||
|
ctx.feeRecipient = val
|
||||||
|
|
||||||
|
proc `timestamp=`*(ctx: CasperRef, val: EthTime) =
|
||||||
|
ctx.timestamp = val
|
||||||
|
|
||||||
|
proc `prevRandao=`*(ctx: CasperRef, val: Hash256) =
|
||||||
|
ctx.prevRandao = val
|
@ -173,7 +173,7 @@ proc prepare*(c: Clique; parent: BlockHeader, header: var BlockHeader): CliqueOk
|
|||||||
## running the transactions on top.
|
## running the transactions on top.
|
||||||
|
|
||||||
# Assemble the voting snapshot to check which votes make sense
|
# Assemble the voting snapshot to check which votes make sense
|
||||||
let rc = c.cliqueSnapshot(header.parentHash, @[])
|
let rc = c.cliqueSnapshot(parent.blockHash, @[])
|
||||||
if rc.isErr:
|
if rc.isErr:
|
||||||
return err(rc.error)
|
return err(rc.error)
|
||||||
|
|
||||||
@ -184,7 +184,8 @@ proc prepare*(c: Clique; parent: BlockHeader, header: var BlockHeader): CliqueOk
|
|||||||
# signer list
|
# signer list
|
||||||
header.coinbase.reset
|
header.coinbase.reset
|
||||||
|
|
||||||
if (header.blockNumber mod c.cfg.epoch) != 0:
|
let modEpoch = (parent.blockNumber+1) mod c.cfg.epoch
|
||||||
|
if modEpoch != 0:
|
||||||
c.doExclusively:
|
c.doExclusively:
|
||||||
# Gather all the proposals that make sense voting on
|
# Gather all the proposals that make sense voting on
|
||||||
var addresses: seq[EthAddress]
|
var addresses: seq[EthAddress]
|
||||||
@ -203,7 +204,7 @@ proc prepare*(c: Clique; parent: BlockHeader, header: var BlockHeader): CliqueOk
|
|||||||
|
|
||||||
# Ensure the extra data has all its components
|
# Ensure the extra data has all its components
|
||||||
header.extraData.setLen(EXTRA_VANITY)
|
header.extraData.setLen(EXTRA_VANITY)
|
||||||
if (header.blockNumber mod c.cfg.epoch) == 0:
|
if modEpoch == 0:
|
||||||
header.extraData.add c.snapshot.ballot.authSigners.mapIt(toSeq(it)).concat
|
header.extraData.add c.snapshot.ballot.authSigners.mapIt(toSeq(it)).concat
|
||||||
header.extraData.add 0.byte.repeat(EXTRA_SEAL)
|
header.extraData.add 0.byte.repeat(EXTRA_SEAL)
|
||||||
|
|
||||||
@ -217,6 +218,12 @@ proc prepare*(c: Clique; parent: BlockHeader, header: var BlockHeader): CliqueOk
|
|||||||
|
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
|
proc prepareForSeal*(c: Clique; prepHeader: BlockHeader; header: var BlockHeader) =
|
||||||
|
# TODO: use system.move?
|
||||||
|
header.nonce = prepHeader.nonce
|
||||||
|
header.extraData = prepHeader.extraData
|
||||||
|
header.mixDigest = prepHeader.mixDigest
|
||||||
|
|
||||||
# clique/clique.go(589): func (c *Clique) Authorize(signer [..]
|
# clique/clique.go(589): func (c *Clique) Authorize(signer [..]
|
||||||
proc authorize*(c: Clique; signer: EthAddress; signFn: CliqueSignerFn) =
|
proc authorize*(c: Clique; signer: EthAddress; signFn: CliqueSignerFn) =
|
||||||
## Injects private key into the consensus engine to mint new blocks with.
|
## Injects private key into the consensus engine to mint new blocks with.
|
||||||
@ -313,7 +320,8 @@ proc seal*(c: Clique; ethBlock: var EthBlock):
|
|||||||
header.extraData.setLen(extraLen - EXTRA_SEAL)
|
header.extraData.setLen(extraLen - EXTRA_SEAL)
|
||||||
header.extraData.add signature.value
|
header.extraData.add signature.value
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
return err((errCliqueSealSigFn, "Error when signing block header"))
|
return err((errCliqueSealSigFn,
|
||||||
|
"Error when signing block header: " & exc.msg))
|
||||||
|
|
||||||
ethBlock = ethBlock.withHeader(header)
|
ethBlock = ethBlock.withHeader(header)
|
||||||
ok()
|
ok()
|
||||||
|
@ -20,6 +20,7 @@ import
|
|||||||
"."/[
|
"."/[
|
||||||
chain,
|
chain,
|
||||||
tx_pool,
|
tx_pool,
|
||||||
|
casper,
|
||||||
validate],
|
validate],
|
||||||
"."/clique/[clique_defs,
|
"."/clique/[clique_defs,
|
||||||
clique_desc,
|
clique_desc,
|
||||||
@ -70,47 +71,14 @@ proc validateSealer*(conf: NimbusConf, ctx: EthContext, chain: ChainRef): Result
|
|||||||
|
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
proc prepareBlock(engine: SealingEngineRef,
|
proc generateBlock(engine: SealingEngineRef,
|
||||||
parent: BlockHeader,
|
outBlock: var EthBlock): Result[void, string] =
|
||||||
time: Time,
|
|
||||||
prevRandao: Hash256): Result[EthBlock, string] =
|
|
||||||
let timestamp = if parent.timestamp >= time:
|
|
||||||
parent.timestamp + 1.seconds
|
|
||||||
else:
|
|
||||||
time
|
|
||||||
|
|
||||||
engine.txPool.prevRandao = prevRandao
|
outBlock = engine.txPool.ethBlock()
|
||||||
|
if engine.chain.com.consensus == ConsensusType.POS:
|
||||||
var blk = engine.txPool.ethBlock()
|
|
||||||
|
|
||||||
if engine.chain.com.isBlockAfterTtd(blk.header):
|
|
||||||
blk.header.difficulty = DifficultyInt.zero
|
|
||||||
blk.header.mixDigest = prevRandao
|
|
||||||
blk.header.nonce = default(BlockNonce)
|
|
||||||
blk.header.extraData = @[] # TODO: probably this should be configurable by user?
|
|
||||||
# Stop the block generator if we reach TTD
|
# Stop the block generator if we reach TTD
|
||||||
engine.state = EnginePostMerge
|
engine.state = EnginePostMerge
|
||||||
else:
|
|
||||||
let res = engine.chain.clique.prepare(parent, blk.header)
|
|
||||||
if res.isErr:
|
|
||||||
return err($res.error)
|
|
||||||
|
|
||||||
ok(blk)
|
|
||||||
|
|
||||||
proc generateBlock(engine: SealingEngineRef,
|
|
||||||
parentHeader: BlockHeader,
|
|
||||||
outBlock: var EthBlock,
|
|
||||||
timestamp = getTime(),
|
|
||||||
prevRandao = Hash256()): Result[void, string] =
|
|
||||||
# deviation from standard block generator
|
|
||||||
# - no DAO hard fork
|
|
||||||
# - no local and remote uncles inclusion
|
|
||||||
|
|
||||||
let res = prepareBlock(engine, parentHeader, timestamp, prevRandao)
|
|
||||||
if res.isErr:
|
|
||||||
return err("error prepare header")
|
|
||||||
|
|
||||||
outBlock = res.get()
|
|
||||||
if engine.state != EnginePostMerge:
|
if engine.state != EnginePostMerge:
|
||||||
# Post merge, Clique should not be executing
|
# Post merge, Clique should not be executing
|
||||||
let sealRes = engine.chain.clique.seal(outBlock)
|
let sealRes = engine.chain.clique.seal(outBlock)
|
||||||
@ -123,13 +91,6 @@ proc generateBlock(engine: SealingEngineRef,
|
|||||||
|
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
proc generateBlock(engine: SealingEngineRef,
|
|
||||||
outBlock: var EthBlock,
|
|
||||||
timestamp = getTime(),
|
|
||||||
prevRandao = Hash256()): Result[void, string] =
|
|
||||||
generateBlock(engine, engine.chain.currentBlock(),
|
|
||||||
outBlock, timestamp, prevRandao)
|
|
||||||
|
|
||||||
proc sealingLoop(engine: SealingEngineRef): Future[void] {.async.} =
|
proc sealingLoop(engine: SealingEngineRef): Future[void] {.async.} =
|
||||||
let clique = engine.chain.clique
|
let clique = engine.chain.clique
|
||||||
|
|
||||||
@ -145,20 +106,6 @@ proc sealingLoop(engine: SealingEngineRef): Future[void] {.async.} =
|
|||||||
|
|
||||||
clique.authorize(engine.signer, signerFunc)
|
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
|
# convert times.Duration to chronos.Duration
|
||||||
let period = chronos.seconds(clique.cfg.period.inSeconds)
|
let period = chronos.seconds(clique.cfg.period.inSeconds)
|
||||||
|
|
||||||
@ -198,32 +145,24 @@ proc generateExecutionPayload*(engine: SealingEngineRef,
|
|||||||
let
|
let
|
||||||
headBlock = try: engine.chain.db.getCanonicalHead()
|
headBlock = try: engine.chain.db.getCanonicalHead()
|
||||||
except CatchableError: return err "No head block in database"
|
except CatchableError: return err "No head block in database"
|
||||||
prevRandao = Hash256(data: distinctBase payloadAttrs.prevRandao)
|
pos = engine.chain.com.pos
|
||||||
timestamp = fromUnix(payloadAttrs.timestamp.unsafeQuantityToInt64)
|
|
||||||
coinbase = EthAddress payloadAttrs.suggestedFeeRecipient
|
pos.prevRandao = Hash256(data: distinctBase payloadAttrs.prevRandao)
|
||||||
|
pos.timestamp = fromUnix(payloadAttrs.timestamp.unsafeQuantityToInt64)
|
||||||
|
pos.feeRecipient = EthAddress payloadAttrs.suggestedFeeRecipient
|
||||||
|
|
||||||
if headBlock.blockHash != engine.txPool.head.blockHash:
|
if headBlock.blockHash != engine.txPool.head.blockHash:
|
||||||
# reorg
|
# reorg
|
||||||
discard engine.txPool.smartHead(headBlock)
|
discard engine.txPool.smartHead(headBlock)
|
||||||
|
|
||||||
var blk: EthBlock
|
var blk: EthBlock
|
||||||
engine.txPool.feeRecipient = coinbase
|
let res = engine.generateBlock(blk)
|
||||||
|
if res.isErr:
|
||||||
let blkRes = engine.generateBlock(
|
error "sealing engine generateBlock error", msg = res.error
|
||||||
headBlock,
|
return res
|
||||||
blk,
|
|
||||||
timestamp,
|
|
||||||
prevRandao)
|
|
||||||
|
|
||||||
if blkRes.isErr:
|
|
||||||
error "sealing engine generateBlock error", msg = blkRes.error
|
|
||||||
return blkRes
|
|
||||||
|
|
||||||
# make sure both generated block header and payloadRes(ExecutionPayloadV1)
|
# make sure both generated block header and payloadRes(ExecutionPayloadV1)
|
||||||
# produce the same blockHash
|
# produce the same blockHash
|
||||||
doAssert blk.header.coinbase == coinbase
|
|
||||||
blk.header.timestamp = timestamp
|
|
||||||
blk.header.prevRandao = prevRandao
|
|
||||||
blk.header.fee = some(blk.header.fee.get(UInt256.zero)) # force it with some(UInt256)
|
blk.header.fee = some(blk.header.fee.get(UInt256.zero)) # force it with some(UInt256)
|
||||||
|
|
||||||
let blockHash = rlpHash(blk.header)
|
let blockHash = rlpHash(blk.header)
|
||||||
|
@ -771,22 +771,6 @@ proc `minTipPrice=`*(xp: TxPoolRef; val: GasPrice) =
|
|||||||
xp.pMinTipPrice = val
|
xp.pMinTipPrice = val
|
||||||
xp.pDirtyBuckets = true
|
xp.pDirtyBuckets = true
|
||||||
|
|
||||||
proc `prevRandao=`*(xp: TxPoolRef; val: Hash256) =
|
|
||||||
## Setter, PoS block randomness
|
|
||||||
## Used by `prevRandao` op code in EVM after transition to PoS
|
|
||||||
## do nothing before transition
|
|
||||||
xp.chain.prevRandao = val
|
|
||||||
|
|
||||||
proc `feeRecipient=`*(xp: TxPoolRef; beneficiary: EthAddress) =
|
|
||||||
## Setter, PoS tx fee recipient
|
|
||||||
## 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
|
# Public functions, per-tx-item operations
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -17,11 +17,13 @@ import
|
|||||||
../../common/common,
|
../../common/common,
|
||||||
../../constants,
|
../../constants,
|
||||||
../../db/accounts_cache,
|
../../db/accounts_cache,
|
||||||
../../core/executor,
|
|
||||||
../../utils/utils,
|
../../utils/utils,
|
||||||
../../core/pow/difficulty,
|
|
||||||
../../vm_state,
|
../../vm_state,
|
||||||
../../vm_types,
|
../../vm_types,
|
||||||
|
../clique/clique_sealer,
|
||||||
|
../pow/difficulty,
|
||||||
|
../executor,
|
||||||
|
../casper,
|
||||||
./tx_chain/[tx_basefee, tx_gaslimits],
|
./tx_chain/[tx_basefee, tx_gaslimits],
|
||||||
./tx_item
|
./tx_item
|
||||||
|
|
||||||
@ -51,8 +53,6 @@ type
|
|||||||
txRoot: Hash256 ## `rootHash` after packing
|
txRoot: Hash256 ## `rootHash` after packing
|
||||||
stateRoot: Hash256 ## `stateRoot` after packing
|
stateRoot: Hash256 ## `stateRoot` after packing
|
||||||
|
|
||||||
DifficultyCalculator* = proc(timeStamp: EthTime, parent: BlockHeader): DifficultyInt {.gcsafe, raises:[].}
|
|
||||||
|
|
||||||
TxChainRef* = ref object ##\
|
TxChainRef* = ref object ##\
|
||||||
## State cache of the transaction environment for creating a new\
|
## State cache of the transaction environment for creating a new\
|
||||||
## block. This state is typically synchrionised with the canonical\
|
## block. This state is typically synchrionised with the canonical\
|
||||||
@ -65,16 +65,40 @@ type
|
|||||||
roAcc: ReadOnlyStateDB ## Accounts cache fixed on current sync header
|
roAcc: ReadOnlyStateDB ## Accounts cache fixed on current sync header
|
||||||
limits: TxChainGasLimits ## Gas limits for packer and next header
|
limits: TxChainGasLimits ## Gas limits for packer and next header
|
||||||
txEnv: TxChainPackerEnv ## Assorted parameters, tx packer environment
|
txEnv: TxChainPackerEnv ## Assorted parameters, tx packer environment
|
||||||
|
prepHeader: BlockHeader ## Prepared Header from Consensus Engine
|
||||||
# EIP-4399 and EIP-3675
|
|
||||||
prevRandao: Hash256 ## PoS block randomness
|
|
||||||
|
|
||||||
# overrideable difficulty calculator
|
|
||||||
calcDifficulty: DifficultyCalculator
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Private functions
|
# Private functions
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
proc prepareHeader(dh: TxChainRef; parent: BlockHeader)
|
||||||
|
{.gcsafe, raises: [Defect, CatchableError].} =
|
||||||
|
|
||||||
|
case dh.com.consensus
|
||||||
|
of ConsensusType.POW:
|
||||||
|
dh.prepHeader.timestamp = getTime().utc.toTime
|
||||||
|
dh.prepHeader.difficulty = dh.com.calcDifficulty(
|
||||||
|
dh.prepHeader.timestamp, parent)
|
||||||
|
dh.prepHeader.coinbase = dh.miner
|
||||||
|
dh.prepHeader.mixDigest.reset
|
||||||
|
of ConsensusType.POA:
|
||||||
|
discard dh.com.poa.prepare(parent, dh.prepHeader)
|
||||||
|
# beware POA header.coinbase != signerAddress
|
||||||
|
# but BaseVMState.minerAddress == signerAddress
|
||||||
|
# - minerAddress is extracted from header.extraData
|
||||||
|
# - header.coinbase is from clique engine
|
||||||
|
dh.prepHeader.coinbase = dh.miner
|
||||||
|
of ConsensusType.POS:
|
||||||
|
dh.com.pos.prepare(dh.prepHeader)
|
||||||
|
|
||||||
|
proc prepareForSeal(dh: TxChainRef; header: var BlockHeader) =
|
||||||
|
case dh.com.consensus
|
||||||
|
of ConsensusType.POW:
|
||||||
|
# do nothing, tx pool was designed with POW in mind
|
||||||
|
discard
|
||||||
|
of ConsensusType.POA:
|
||||||
|
dh.com.poa.prepareForSeal(dh.prepHeader, header)
|
||||||
|
of ConsensusType.POS:
|
||||||
|
dh.com.pos.prepareForSeal(header)
|
||||||
|
|
||||||
proc resetTxEnv(dh: TxChainRef; parent: BlockHeader; fee: Option[UInt256])
|
proc resetTxEnv(dh: TxChainRef; parent: BlockHeader; fee: Option[UInt256])
|
||||||
{.gcsafe,raises: [Defect,CatchableError].} =
|
{.gcsafe,raises: [Defect,CatchableError].} =
|
||||||
@ -83,18 +107,18 @@ proc resetTxEnv(dh: TxChainRef; parent: BlockHeader; fee: Option[UInt256])
|
|||||||
# do hardfork transition before
|
# do hardfork transition before
|
||||||
# BaseVMState querying any hardfork/consensus from CommonRef
|
# BaseVMState querying any hardfork/consensus from CommonRef
|
||||||
dh.com.hardForkTransition(parent.blockHash, parent.blockNumber+1)
|
dh.com.hardForkTransition(parent.blockHash, parent.blockNumber+1)
|
||||||
|
dh.prepareHeader(parent)
|
||||||
|
|
||||||
let timestamp = getTime().utc.toTime
|
|
||||||
# we don't consider PoS difficulty here
|
# we don't consider PoS difficulty here
|
||||||
# because that is handled in vmState
|
# because that is handled in vmState
|
||||||
dh.txEnv.vmState = BaseVMState.new(
|
dh.txEnv.vmState = BaseVMState.new(
|
||||||
parent = parent,
|
parent = parent,
|
||||||
timestamp = timestamp,
|
timestamp = dh.prepHeader.timestamp,
|
||||||
gasLimit = (if dh.maxMode: dh.limits.maxLimit else: dh.limits.trgLimit),
|
gasLimit = (if dh.maxMode: dh.limits.maxLimit else: dh.limits.trgLimit),
|
||||||
fee = fee,
|
fee = fee,
|
||||||
prevRandao= dh.prevRandao,
|
prevRandao= dh.prepHeader.prevRandao,
|
||||||
difficulty= dh.calcDifficulty(timestamp, parent),
|
difficulty= dh.prepHeader.difficulty,
|
||||||
miner = dh.miner,
|
miner = dh.prepHeader.coinbase,
|
||||||
com = dh.com)
|
com = dh.com)
|
||||||
|
|
||||||
dh.txEnv.txRoot = EMPTY_ROOT_HASH
|
dh.txEnv.txRoot = EMPTY_ROOT_HASH
|
||||||
@ -132,12 +156,6 @@ proc new*(T: type TxChainRef; com: CommonRef; miner: EthAddress): T
|
|||||||
result.lhwm.hwmMax = MAX_THRESHOLD_PER_CENT
|
result.lhwm.hwmMax = MAX_THRESHOLD_PER_CENT
|
||||||
result.lhwm.gasFloor = DEFAULT_GAS_LIMIT
|
result.lhwm.gasFloor = DEFAULT_GAS_LIMIT
|
||||||
result.lhwm.gasCeil = DEFAULT_GAS_LIMIT
|
result.lhwm.gasCeil = DEFAULT_GAS_LIMIT
|
||||||
result.calcDifficulty = proc(timeStamp: EthTime, parent: BlockHeader):
|
|
||||||
DifficultyInt {.gcsafe, raises:[].} =
|
|
||||||
try:
|
|
||||||
com.calcDifficulty(timestamp, parent)
|
|
||||||
except:
|
|
||||||
0.u256
|
|
||||||
result.update(com.db.getCanonicalHead)
|
result.update(com.db.getCanonicalHead)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@ -168,24 +186,25 @@ proc getHeader*(dh: TxChainRef): BlockHeader
|
|||||||
let gasUsed = if dh.txEnv.receipts.len == 0: 0.GasInt
|
let gasUsed = if dh.txEnv.receipts.len == 0: 0.GasInt
|
||||||
else: dh.txEnv.receipts[^1].cumulativeGasUsed
|
else: dh.txEnv.receipts[^1].cumulativeGasUsed
|
||||||
|
|
||||||
BlockHeader(
|
result = BlockHeader(
|
||||||
parentHash: dh.txEnv.vmState.parent.blockHash,
|
parentHash: dh.txEnv.vmState.parent.blockHash,
|
||||||
ommersHash: EMPTY_UNCLE_HASH,
|
ommersHash: EMPTY_UNCLE_HASH,
|
||||||
coinbase: dh.miner,
|
coinbase: dh.prepHeader.coinbase,
|
||||||
stateRoot: dh.txEnv.stateRoot,
|
stateRoot: dh.txEnv.stateRoot,
|
||||||
txRoot: dh.txEnv.txRoot,
|
txRoot: dh.txEnv.txRoot,
|
||||||
receiptRoot: dh.txEnv.receipts.calcReceiptRoot,
|
receiptRoot: dh.txEnv.receipts.calcReceiptRoot,
|
||||||
bloom: dh.txEnv.receipts.createBloom,
|
bloom: dh.txEnv.receipts.createBloom,
|
||||||
difficulty: dh.txEnv.vmState.difficulty,
|
difficulty: dh.prepHeader.difficulty,
|
||||||
blockNumber: dh.txEnv.vmState.blockNumber,
|
blockNumber: dh.txEnv.vmState.blockNumber,
|
||||||
gasLimit: dh.txEnv.vmState.gasLimit,
|
gasLimit: dh.txEnv.vmState.gasLimit,
|
||||||
gasUsed: gasUsed,
|
gasUsed: gasUsed,
|
||||||
timestamp: dh.txEnv.vmState.timestamp,
|
timestamp: dh.prepHeader.timestamp,
|
||||||
# extraData: Blob # signing data
|
# extraData: Blob # signing data
|
||||||
# mixDigest: Hash256 # mining hash for given difficulty
|
# mixDigest: Hash256 # mining hash for given difficulty
|
||||||
# nonce: BlockNonce # mining free vaiable
|
# nonce: BlockNonce # mining free vaiable
|
||||||
fee: dh.txEnv.vmState.fee)
|
fee: dh.txEnv.vmState.fee)
|
||||||
|
|
||||||
|
dh.prepareForSeal(result)
|
||||||
|
|
||||||
proc clearAccounts*(dh: TxChainRef)
|
proc clearAccounts*(dh: TxChainRef)
|
||||||
{.gcsafe,raises: [Defect,CatchableError].} =
|
{.gcsafe,raises: [Defect,CatchableError].} =
|
||||||
@ -216,9 +235,12 @@ proc maxMode*(dh: TxChainRef): bool =
|
|||||||
## Getter
|
## Getter
|
||||||
dh.maxMode
|
dh.maxMode
|
||||||
|
|
||||||
proc miner*(dh: TxChainRef): EthAddress =
|
proc feeRecipient*(dh: TxChainRef): EthAddress =
|
||||||
## Getter, shortcut for `dh.vmState.minerAddress`
|
## Getter
|
||||||
dh.miner
|
if dh.com.consensus == ConsensusType.POS:
|
||||||
|
dh.com.pos.feeRecipient
|
||||||
|
else:
|
||||||
|
dh.miner
|
||||||
|
|
||||||
proc baseFee*(dh: TxChainRef): GasPrice =
|
proc baseFee*(dh: TxChainRef): GasPrice =
|
||||||
## Getter, baseFee for the next bock header. This value is auto-generated
|
## Getter, baseFee for the next bock header. This value is auto-generated
|
||||||
@ -323,14 +345,6 @@ proc `txRoot=`*(dh: TxChainRef; val: Hash256) =
|
|||||||
## Setter
|
## Setter
|
||||||
dh.txEnv.txRoot = val
|
dh.txEnv.txRoot = val
|
||||||
|
|
||||||
proc `prevRandao=`*(dh: TxChainRef; val: Hash256) =
|
|
||||||
## Setter
|
|
||||||
dh.prevRandao = val
|
|
||||||
|
|
||||||
proc `calcDifficulty=`*(dh: TxChainRef; val: DifficultyCalculator) =
|
|
||||||
## Setter
|
|
||||||
dh.calcDifficulty = val
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# End
|
# End
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -109,7 +109,7 @@ proc runTxCommit(pst: TxPackerStateRef; item: TxItemRef; gasBurned: GasInt)
|
|||||||
# are vetted for profitability before entering that bucket.
|
# are vetted for profitability before entering that bucket.
|
||||||
assert 0 <= gasTip
|
assert 0 <= gasTip
|
||||||
let reward = gasBurned.u256 * gasTip.uint64.u256
|
let reward = gasBurned.u256 * gasTip.uint64.u256
|
||||||
vmState.stateDB.addBalance(xp.chain.miner, reward)
|
vmState.stateDB.addBalance(xp.chain.feeRecipient, reward)
|
||||||
|
|
||||||
# Update account database
|
# Update account database
|
||||||
vmState.mutateStateDB:
|
vmState.mutateStateDB:
|
||||||
@ -117,7 +117,7 @@ proc runTxCommit(pst: TxPackerStateRef; item: TxItemRef; gasBurned: GasInt)
|
|||||||
db.deleteAccount deletedAccount
|
db.deleteAccount deletedAccount
|
||||||
|
|
||||||
if FkSpurious <= xp.chain.nextFork:
|
if FkSpurious <= xp.chain.nextFork:
|
||||||
vmState.touchedAccounts.incl(xp.chain.miner)
|
vmState.touchedAccounts.incl(xp.chain.feeRecipient)
|
||||||
# EIP158/161 state clearing
|
# EIP158/161 state clearing
|
||||||
for account in vmState.touchedAccounts:
|
for account in vmState.touchedAccounts:
|
||||||
if db.accountExists(account) and db.isEmptyAccount(account):
|
if db.accountExists(account) and db.isEmptyAccount(account):
|
||||||
@ -169,7 +169,7 @@ proc vmExecInit(xp: TxPoolRef): TxPackerStateRef
|
|||||||
TxPackerStateRef( # return value
|
TxPackerStateRef( # return value
|
||||||
xp: xp,
|
xp: xp,
|
||||||
tr: newMemoryDB().initHexaryTrie,
|
tr: newMemoryDB().initHexaryTrie,
|
||||||
balance: xp.chain.vmState.readOnlyStateDB.getBalance(xp.chain.miner))
|
balance: xp.chain.vmState.readOnlyStateDB.getBalance(xp.chain.feeRecipient))
|
||||||
|
|
||||||
|
|
||||||
proc vmExecGrabItem(pst: TxPackerStateRef; item: TxItemRef): Result[bool,void]
|
proc vmExecGrabItem(pst: TxPackerStateRef; item: TxItemRef): Result[bool,void]
|
||||||
@ -218,7 +218,7 @@ proc vmExecCommit(pst: TxPackerStateRef)
|
|||||||
let
|
let
|
||||||
number = xp.chain.head.blockNumber + 1
|
number = xp.chain.head.blockNumber + 1
|
||||||
uncles: seq[BlockHeader] = @[] # no uncles yet
|
uncles: seq[BlockHeader] = @[] # no uncles yet
|
||||||
vmState.calculateReward(xp.chain.miner, number + 1, uncles)
|
vmState.calculateReward(xp.chain.feeRecipient, number + 1, uncles)
|
||||||
|
|
||||||
# Reward beneficiary
|
# Reward beneficiary
|
||||||
vmState.mutateStateDB:
|
vmState.mutateStateDB:
|
||||||
@ -236,7 +236,7 @@ proc vmExecCommit(pst: TxPackerStateRef)
|
|||||||
xp.chain.stateRoot = vmState.stateDB.rootHash
|
xp.chain.stateRoot = vmState.stateDB.rootHash
|
||||||
|
|
||||||
proc balanceDelta: UInt256 =
|
proc balanceDelta: UInt256 =
|
||||||
let postBalance = vmState.readOnlyStateDB.getBalance(xp.chain.miner)
|
let postBalance = vmState.readOnlyStateDB.getBalance(xp.chain.feeRecipient)
|
||||||
if pst.balance < postBalance:
|
if pst.balance < postBalance:
|
||||||
return postBalance - pst.balance
|
return postBalance - pst.balance
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
# according to those terms.
|
# according to those terms.
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[options, times, json, strutils],
|
std/[options, times, json, strutils, sets],
|
||||||
eth/common,
|
../common/common,
|
||||||
stew/byteutils,
|
stew/byteutils,
|
||||||
../vm_state,
|
../vm_state,
|
||||||
../vm_types,
|
../vm_types,
|
||||||
@ -84,3 +84,23 @@ proc debugAccounts*(vmState: BaseVMState): string =
|
|||||||
}
|
}
|
||||||
|
|
||||||
res.pretty
|
res.pretty
|
||||||
|
|
||||||
|
proc debug*(vms: BaseVMState): string =
|
||||||
|
result.add "com.consensus :" & $vms.com.consensus & "\n"
|
||||||
|
result.add "parent :" & $vms.parent.blockHash & "\n"
|
||||||
|
result.add "timestamp :" & $vms.timestamp.toUnix & "\n"
|
||||||
|
result.add "gasLimit :" & $vms.gasLimit & "\n"
|
||||||
|
result.add "fee :" & $vms.fee & "\n"
|
||||||
|
result.add "prevRandao :" & $vms.prevRandao & "\n"
|
||||||
|
result.add "blockDifficulty :" & $vms.blockDifficulty & "\n"
|
||||||
|
result.add "flags :" & $vms.flags & "\n"
|
||||||
|
result.add "logEntries.len :" & $vms.logEntries.len & "\n"
|
||||||
|
result.add "receipts.len :" & $vms.receipts.len & "\n"
|
||||||
|
result.add "stateDB.root :" & $vms.stateDB.rootHash & "\n"
|
||||||
|
result.add "cumulativeGasUsed:" & $vms.cumulativeGasUsed & "\n"
|
||||||
|
result.add "touchedAccs.len :" & $vms.touchedAccounts.len & "\n"
|
||||||
|
result.add "selfDestructs.len:" & $vms.selfDestructs.len & "\n"
|
||||||
|
result.add "txOrigin :" & $vms.txOrigin & "\n"
|
||||||
|
result.add "txGasPrice :" & $vms.txGasPrice & "\n"
|
||||||
|
result.add "fork :" & $vms.fork & "\n"
|
||||||
|
result.add "minerAddress :" & $vms.minerAddress & "\n"
|
||||||
|
@ -14,6 +14,7 @@ import
|
|||||||
../nimbus/core/[chain, clique, executor],
|
../nimbus/core/[chain, clique, executor],
|
||||||
../nimbus/core/[tx_pool, tx_pool/tx_item],
|
../nimbus/core/[tx_pool, tx_pool/tx_item],
|
||||||
../nimbus/common/common,
|
../nimbus/common/common,
|
||||||
|
../nimbus/core/clique/clique_sealer,
|
||||||
./test_txpool/[helpers, setup, sign_helper],
|
./test_txpool/[helpers, setup, sign_helper],
|
||||||
./test_txpool2,
|
./test_txpool2,
|
||||||
chronos,
|
chronos,
|
||||||
@ -217,7 +218,6 @@ proc runTxLoader(noisy = true; capture = loadSpecs) =
|
|||||||
check 0.GasPrice <= minGasPrice
|
check 0.GasPrice <= minGasPrice
|
||||||
check minGasPrice <= maxGasPrice
|
check minGasPrice <= maxGasPrice
|
||||||
|
|
||||||
|
|
||||||
proc runTxPoolTests(noisy = true) =
|
proc runTxPoolTests(noisy = true) =
|
||||||
let elapNoisy = false
|
let elapNoisy = false
|
||||||
|
|
||||||
@ -781,6 +781,10 @@ proc runTxPackerTests(noisy = true) =
|
|||||||
# if true: return
|
# if true: return
|
||||||
test "Store generated block in block chain database":
|
test "Store generated block in block chain database":
|
||||||
|
|
||||||
|
# authorized signer is needed to produce correct
|
||||||
|
# POA difficulty and blockheader fields
|
||||||
|
bcCom.poa.authorize(testAddress, signerFunc)
|
||||||
|
|
||||||
noisy.say "***", "locality",
|
noisy.say "***", "locality",
|
||||||
" locals=", xq.accountRanks.local.len,
|
" locals=", xq.accountRanks.local.len,
|
||||||
" remotes=", xq.accountRanks.remote.len
|
" remotes=", xq.accountRanks.remote.len
|
||||||
@ -830,17 +834,22 @@ proc runTxPackerTests(noisy = true) =
|
|||||||
# much less than permitted so this block will be accepted.
|
# much less than permitted so this block will be accepted.
|
||||||
check 0 < overlap
|
check 0 < overlap
|
||||||
|
|
||||||
#setTraceLevel()
|
setTraceLevel()
|
||||||
|
|
||||||
# Test low-level function for adding the new block to the database
|
# Test low-level function for adding the new block to the database
|
||||||
xq.chain.maxMode = (packItemsMaxGasLimit in xq.flags)
|
xq.chain.maxMode = (packItemsMaxGasLimit in xq.flags)
|
||||||
xq.chain.clearAccounts
|
xq.chain.clearAccounts
|
||||||
check xq.chain.vmState.processBlock(poa, hdr, bdy).isOK
|
check xq.chain.vmState.processBlock(poa, hdr, bdy).isOK
|
||||||
|
|
||||||
|
#debugEcho "VMSTATE 1: ", debugAccounts(xq.chain.vmState)
|
||||||
|
|
||||||
setErrorLevel()
|
setErrorLevel()
|
||||||
|
|
||||||
# Re-allocate using VM environment from `persistBlocks()`
|
# Re-allocate using VM environment from `persistBlocks()`
|
||||||
check BaseVMState.new(hdr, bcCom).processBlock(poa, hdr, bdy).isOK
|
let vmstate2 = BaseVMState.new(hdr, bcCom)
|
||||||
|
check vmstate2.processBlock(poa, hdr, bdy).isOK
|
||||||
|
|
||||||
|
#debugEcho "VMSTATE 2: ", debugAccounts(vmstate2)
|
||||||
|
|
||||||
# This should not have changed
|
# This should not have changed
|
||||||
check canonicalHead == xq.chain.com.db.getCanonicalHead
|
check canonicalHead == xq.chain.com.db.getCanonicalHead
|
||||||
@ -871,9 +880,9 @@ proc txPoolMain*(noisy = defined(debug)) =
|
|||||||
noisy.runTxLoader
|
noisy.runTxLoader
|
||||||
noisy.runTxPoolTests
|
noisy.runTxPoolTests
|
||||||
noisy.runTxPackerTests
|
noisy.runTxPackerTests
|
||||||
#runTxPoolCliqueTest()
|
runTxPoolCliqueTest()
|
||||||
#runTxPoolPosTest()
|
runTxPoolPosTest()
|
||||||
#noisy.runTxHeadDelta
|
noisy.runTxHeadDelta
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
const
|
const
|
||||||
@ -889,9 +898,9 @@ when isMainModule:
|
|||||||
noisy.runTxPoolTests
|
noisy.runTxPoolTests
|
||||||
noisy.runTxPackerTests
|
noisy.runTxPackerTests
|
||||||
|
|
||||||
runTxPoolCliqueTest()
|
#runTxPoolCliqueTest()
|
||||||
runTxPoolPosTest()
|
#runTxPoolPosTest()
|
||||||
noisy.runTxHeadDelta
|
#noisy.runTxHeadDelta
|
||||||
|
|
||||||
#noisy.runTxLoader(dir = ".")
|
#noisy.runTxLoader(dir = ".")
|
||||||
#noisy.runTxPoolTests
|
#noisy.runTxPoolTests
|
||||||
|
@ -12,6 +12,7 @@ import
|
|||||||
../../nimbus/constants,
|
../../nimbus/constants,
|
||||||
../../nimbus/utils/ec_recover,
|
../../nimbus/utils/ec_recover,
|
||||||
../../nimbus/core/tx_pool/tx_item,
|
../../nimbus/core/tx_pool/tx_item,
|
||||||
|
../../nimbus/core/clique/clique_desc,
|
||||||
eth/[common, common/transaction, keys],
|
eth/[common, common/transaction, keys],
|
||||||
stew/results,
|
stew/results,
|
||||||
stint
|
stint
|
||||||
@ -89,4 +90,13 @@ proc testKeySign*(header: BlockHeader): BlockHeader =
|
|||||||
## Sign the header and embed the signature in extra data
|
## Sign the header and embed the signature in extra data
|
||||||
header.sign(prvTestKey)
|
header.sign(prvTestKey)
|
||||||
|
|
||||||
|
proc signerFunc*(signer: EthAddress, msg: openArray[byte]):
|
||||||
|
Result[RawSignature, cstring] {.gcsafe.} =
|
||||||
|
doAssert(signer == testAddress)
|
||||||
|
let
|
||||||
|
data = keccakHash(msg)
|
||||||
|
rawSign = sign(prvTestKey, SkMessage(data.data)).toRaw
|
||||||
|
|
||||||
|
ok(rawSign)
|
||||||
|
|
||||||
# End
|
# End
|
||||||
|
@ -7,10 +7,15 @@ import
|
|||||||
../nimbus/core/clique/[clique_sealer, clique_desc],
|
../nimbus/core/clique/[clique_sealer, clique_desc],
|
||||||
../nimbus/[config, transaction, constants],
|
../nimbus/[config, transaction, constants],
|
||||||
../nimbus/core/tx_pool,
|
../nimbus/core/tx_pool,
|
||||||
|
../nimbus/core/casper,
|
||||||
|
../nimbus/core/executor,
|
||||||
../nimbus/common/common,
|
../nimbus/common/common,
|
||||||
|
../nimbus/[vm_state, vm_types],
|
||||||
./test_txpool/helpers,
|
./test_txpool/helpers,
|
||||||
./macro_assembler
|
./macro_assembler
|
||||||
|
|
||||||
|
import ../nimbus/utils/debug
|
||||||
|
|
||||||
const
|
const
|
||||||
baseDir = [".", "tests"]
|
baseDir = [".", "tests"]
|
||||||
repoDir = [".", "customgenesis"]
|
repoDir = [".", "customgenesis"]
|
||||||
@ -115,11 +120,11 @@ proc runTxPoolCliqueTest*() =
|
|||||||
tx = env.makeTx(recipient, amount)
|
tx = env.makeTx(recipient, amount)
|
||||||
xp = env.xp
|
xp = env.xp
|
||||||
conf = env.conf
|
conf = env.conf
|
||||||
com = env.com
|
|
||||||
chain = env.chain
|
chain = env.chain
|
||||||
clique = env.chain.clique
|
clique = env.chain.clique
|
||||||
body: BlockBody
|
body: BlockBody
|
||||||
blk: EthBlock
|
blk: EthBlock
|
||||||
|
com = env.chain.com
|
||||||
|
|
||||||
let signerKey = privKey(signerKeyHex)
|
let signerKey = privKey(signerKeyHex)
|
||||||
proc signerFunc(signer: EthAddress, msg: openArray[byte]):
|
proc signerFunc(signer: EthAddress, msg: openArray[byte]):
|
||||||
@ -130,6 +135,7 @@ proc runTxPoolCliqueTest*() =
|
|||||||
rawSign = sign(signerKey, SkMessage(data.data)).toRaw
|
rawSign = sign(signerKey, SkMessage(data.data)).toRaw
|
||||||
|
|
||||||
ok(rawSign)
|
ok(rawSign)
|
||||||
|
clique.authorize(conf.engineSigner, signerFunc)
|
||||||
|
|
||||||
suite "Test TxPool with Clique sealer":
|
suite "Test TxPool with Clique sealer":
|
||||||
test "TxPool addLocal":
|
test "TxPool addLocal":
|
||||||
@ -143,31 +149,27 @@ proc runTxPoolCliqueTest*() =
|
|||||||
check xp.nItems.total == 1
|
check xp.nItems.total == 1
|
||||||
|
|
||||||
test "TxPool ethBlock":
|
test "TxPool ethBlock":
|
||||||
xp.prevRandao = EMPTY_UNCLE_HASH
|
|
||||||
blk = xp.ethBlock()
|
blk = xp.ethBlock()
|
||||||
|
|
||||||
blk.header.prevRandao = EMPTY_UNCLE_HASH
|
|
||||||
body = BlockBody(
|
body = BlockBody(
|
||||||
transactions: blk.txs,
|
transactions: blk.txs,
|
||||||
uncles: blk.uncles
|
uncles: blk.uncles
|
||||||
)
|
)
|
||||||
check blk.txs.len == 1
|
check blk.txs.len == 1
|
||||||
|
|
||||||
test "Clique prepare and seal":
|
test "Clique seal":
|
||||||
clique.authorize(conf.engineSigner, signerFunc)
|
|
||||||
let parent = com.db.getBlockHeader(blk.header.parentHash)
|
|
||||||
let ry = chain.clique.prepare(parent, blk.header)
|
|
||||||
check ry.isOk
|
|
||||||
if ry.isErr:
|
|
||||||
debugEcho ry.error
|
|
||||||
return
|
|
||||||
|
|
||||||
let rx = clique.seal(blk)
|
let rx = clique.seal(blk)
|
||||||
check rx.isOk
|
check rx.isOk
|
||||||
if rx.isErr:
|
if rx.isErr:
|
||||||
debugEcho rx.error
|
debugEcho rx.error
|
||||||
return
|
return
|
||||||
|
|
||||||
|
test "Store generated block in block chain database":
|
||||||
|
xp.chain.clearAccounts
|
||||||
|
check xp.chain.vmState.processBlock(com.poa, blk.header, body).isOK
|
||||||
|
|
||||||
|
let vmstate2 = BaseVMState.new(blk.header, com)
|
||||||
|
check vmstate2.processBlock(com.poa, blk.header, body).isOK
|
||||||
|
|
||||||
test "Clique persistBlocks":
|
test "Clique persistBlocks":
|
||||||
let rr = chain.persistBlocks([blk.header], [body])
|
let rr = chain.persistBlocks([blk.header], [body])
|
||||||
check rr == ValidationResult.OK
|
check rr == ValidationResult.OK
|
||||||
@ -196,22 +198,20 @@ proc runTxPoolPosTest*() =
|
|||||||
check xp.nItems.total == 1
|
check xp.nItems.total == 1
|
||||||
|
|
||||||
test "TxPool ethBlock":
|
test "TxPool ethBlock":
|
||||||
xp.prevRandao = prevRandao
|
com.pos.prevRandao = prevRandao
|
||||||
xp.feeRecipient = feeRecipient
|
com.pos.feeRecipient = feeRecipient
|
||||||
|
com.pos.timestamp = getTime()
|
||||||
|
|
||||||
blk = xp.ethBlock()
|
blk = xp.ethBlock()
|
||||||
|
|
||||||
check com.isBlockAfterTtd(blk.header)
|
check com.isBlockAfterTtd(blk.header)
|
||||||
|
|
||||||
blk.header.difficulty = DifficultyInt.zero
|
|
||||||
blk.header.prevRandao = prevRandao
|
|
||||||
blk.header.nonce = default(BlockNonce)
|
|
||||||
blk.header.extraData = @[]
|
|
||||||
|
|
||||||
body = BlockBody(
|
body = BlockBody(
|
||||||
transactions: blk.txs,
|
transactions: blk.txs,
|
||||||
uncles: blk.uncles
|
uncles: blk.uncles
|
||||||
)
|
)
|
||||||
check blk.txs.len == 1
|
check blk.txs.len == 1
|
||||||
|
|
||||||
test "PoS persistBlocks":
|
test "PoS persistBlocks":
|
||||||
let rr = chain.persistBlocks([blk.header], [body])
|
let rr = chain.persistBlocks([blk.header], [body])
|
||||||
check rr == ValidationResult.OK
|
check rr == ValidationResult.OK
|
||||||
@ -262,17 +262,14 @@ proc runTxHeadDelta*(noisy = true) =
|
|||||||
# pending/staged/packed : total/disposed
|
# pending/staged/packed : total/disposed
|
||||||
&" stats={xp.nItems.pp}"
|
&" stats={xp.nItems.pp}"
|
||||||
|
|
||||||
xp.prevRandao = prevRandao
|
timestamp = timestamp + 1.seconds
|
||||||
|
com.pos.prevRandao = prevRandao
|
||||||
|
com.pos.timestamp = timestamp
|
||||||
|
com.pos.feeRecipient = feeRecipient
|
||||||
|
|
||||||
var blk = xp.ethBlock()
|
var blk = xp.ethBlock()
|
||||||
check com.isBlockAfterTtd(blk.header)
|
check com.isBlockAfterTtd(blk.header)
|
||||||
|
|
||||||
timestamp = timestamp + 1.seconds
|
|
||||||
blk.header.difficulty = DifficultyInt.zero
|
|
||||||
blk.header.prevRandao = prevRandao
|
|
||||||
blk.header.nonce = default(BlockNonce)
|
|
||||||
blk.header.extraData = @[]
|
|
||||||
blk.header.timestamp = timestamp
|
|
||||||
|
|
||||||
let body = BlockBody(
|
let body = BlockBody(
|
||||||
transactions: blk.txs,
|
transactions: blk.txs,
|
||||||
uncles: blk.uncles)
|
uncles: blk.uncles)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user