Skip to content

Commit

Permalink
handle PoA block difficulty during block creation
Browse files Browse the repository at this point in the history
- in vmState
- in txpool
- in sealing engine

fix #1105
  • Loading branch information
jangko committed Jun 15, 2022
1 parent 6325712 commit 77be2f6
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 22 deletions.
4 changes: 1 addition & 3 deletions nimbus/p2p/clique/clique_sealer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
## Mining Support for Clique PoA Consensus Protocol
## ================================================
##
## Note that mining in currently unsupported by `NIMBUS`
##
## For details see
## `EIP-225 <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-225.md>`_
## and
Expand Down Expand Up @@ -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
Expand Down
16 changes: 14 additions & 2 deletions nimbus/sealer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)

Expand Down
5 changes: 5 additions & 0 deletions nimbus/utils/tx_pool.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
# ------------------------------------------------------------------------------
Expand Down
22 changes: 21 additions & 1 deletion nimbus/utils/tx_pool/tx_chain.nim
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import
../../forks,
../../p2p/executor,
../../utils,
../../utils/difficulty,
../../vm_state,
../../vm_types,
./tx_chain/[tx_basefee, tx_gaslimits],
Expand Down Expand Up @@ -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\
Expand All @@ -69,6 +72,9 @@ type
# EIP-4399 and EIP-3675
prevRandao: Hash256 ## PoS block randomness

# overrideable difficulty calculator
calcDifficulty: DifficultyCalculator

# ------------------------------------------------------------------------------
# Private functions
# ------------------------------------------------------------------------------
Expand All @@ -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)

Expand Down Expand Up @@ -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)

# ------------------------------------------------------------------------------
Expand Down Expand Up @@ -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
# ------------------------------------------------------------------------------
18 changes: 11 additions & 7 deletions nimbus/vm/state.nim
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ proc init(
gasLimit: GasInt;
fee: Option[UInt256];
prevRandao: Hash256;
difficulty: UInt256;
miner: EthAddress;
chainDB: BaseChainDB;
ttdReached: bool;
Expand All @@ -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
Expand All @@ -96,6 +98,7 @@ proc init(
gasLimit: GasInt;
fee: Option[UInt256];
prevRandao: Hash256;
difficulty: UInt256;
miner: EthAddress;
chainDB: BaseChainDB;
tracerFlags: set[TracerFlags])
Expand All @@ -109,6 +112,7 @@ proc init(
gasLimit = gasLimit,
fee = fee,
prevRandao= prevRandao,
difficulty= difficulty,
miner = miner,
chainDB = chainDB,
ttdReached= chainDB.isTtdReached(parent.blockHash),
Expand All @@ -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] = {};
Expand All @@ -152,6 +157,7 @@ proc new*(
gasLimit = gasLimit,
fee = fee,
prevRandao = prevRandao,
difficulty = difficulty,
miner = miner,
chainDB = chainDB,
tracerFlags = tracerFlags)
Expand All @@ -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].} =
Expand All @@ -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),
Expand All @@ -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)

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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

Expand All @@ -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:
Expand Down
1 change: 1 addition & 0 deletions nimbus/vm/types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type
gasLimit* : GasInt
fee* : Option[UInt256]
prevRandao* : Hash256
blockDifficulty*: UInt256
ttdReached* : bool
name* : string
flags* : set[VMFlag]
Expand Down
19 changes: 11 additions & 8 deletions nimbus/vm2/state.nim
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ proc init(
gasLimit: GasInt;
fee: Option[UInt256];
prevRandao: Hash256;
difficulty: UInt256;
miner: EthAddress;
chainDB: BaseChainDB;
ttdReached: bool;
Expand All @@ -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
Expand All @@ -94,6 +96,7 @@ proc init(
gasLimit: GasInt;
fee: Option[UInt256];
prevRandao: Hash256;
difficulty: UInt256;
miner: EthAddress;
chainDB: BaseChainDB;
tracerFlags: set[TracerFlags])
Expand All @@ -107,6 +110,7 @@ proc init(
gasLimit = gasLimit,
fee = fee,
prevRandao= prevRandao,
difficulty= difficulty,
miner = miner,
chainDB = chainDB,
ttdReached= chainDB.isTtdReached(parent.blockHash),
Expand All @@ -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] = {};
Expand All @@ -150,6 +155,7 @@ proc new*(
gasLimit = gasLimit,
fee = fee,
prevRandao = prevRandao,
difficulty = difficulty,
miner = miner,
chainDB = chainDB,
tracerFlags = tracerFlags)
Expand All @@ -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].} =
Expand All @@ -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),
Expand All @@ -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)

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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

Expand All @@ -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:
Expand Down
1 change: 1 addition & 0 deletions nimbus/vm2/types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type
gasLimit* : GasInt
fee* : Option[UInt256]
prevRandao* : Hash256
blockDifficulty*: UInt256
ttdReached* : bool
name* : string
flags* : set[VMFlag]
Expand Down
1 change: 0 additions & 1 deletion nimbus/vm_state.nim
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export
vms.blockNumber,
vms.buildWitness,
vms.coinbase,
vms.consensusEnginePoA,
vms.difficulty,
vms.disableTracing,
vms.enableTracing,
Expand Down

0 comments on commit 77be2f6

Please sign in to comment.