From c00528139112dfca3fbea8f1aa5230e06cc35d8a Mon Sep 17 00:00:00 2001 From: jangko Date: Thu, 19 Oct 2023 07:50:07 +0700 Subject: [PATCH] processBeaconBlockRoot in TxPool(EIP-4788) --- nimbus/beacon/beacon_engine.nim | 8 ++++---- nimbus/beacon/web3_eth_conv.nim | 8 +++++++- nimbus/constants.nim | 8 ++++---- nimbus/core/casper.nim | 19 +++++++++++++------ nimbus/core/eip4844.nim | 6 +++--- nimbus/core/executor/process_transaction.nim | 4 ++-- nimbus/core/tx_pool.nim | 10 ++++------ nimbus/core/tx_pool/tx_chain.nim | 10 +--------- nimbus/core/tx_pool/tx_tasks/tx_packer.nim | 9 +++++++-- nimbus/db/accounts_cache.nim | 2 +- nimbus/db/ledger/accounts_cache.nim | 2 +- nimbus/db/ledger/accounts_ledger.nim | 2 +- nimbus/utils/debug.nim | 2 ++ 13 files changed, 50 insertions(+), 40 deletions(-) diff --git a/nimbus/beacon/beacon_engine.nim b/nimbus/beacon/beacon_engine.nim index b9f4ca04c..cedd09855 100644 --- a/nimbus/beacon/beacon_engine.nim +++ b/nimbus/beacon/beacon_engine.nim @@ -34,12 +34,12 @@ type # Private helpers # ------------------------------------------------------------------------------ -proc setWithdrawals(xp: TxPoolRef, attrs: PayloadAttributes) = +proc setWithdrawals(ctx: CasperRef, attrs: PayloadAttributes) = case attrs.version of Version.V2, Version.V3: - xp.withdrawals = ethWithdrawals attrs.withdrawals.get + ctx.withdrawals = ethWithdrawals attrs.withdrawals.get else: - xp.withdrawals = @[] + ctx.withdrawals = @[] template wrapException(body: untyped): auto = try: @@ -159,7 +159,7 @@ proc generatePayload*(ben: BeaconEngineRef, if attrs.parentBeaconBlockRoot.isSome: pos.parentBeaconBlockRoot = ethHash attrs.parentBeaconBlockRoot.get - xp.setWithdrawals(attrs) + pos.setWithdrawals(attrs) if headBlock.blockHash != xp.head.blockHash: # reorg diff --git a/nimbus/beacon/web3_eth_conv.nim b/nimbus/beacon/web3_eth_conv.nim index 944d42fbc..04223cd86 100644 --- a/nimbus/beacon/web3_eth_conv.nim +++ b/nimbus/beacon/web3_eth_conv.nim @@ -86,7 +86,7 @@ func u256*(x: Web3Quantity): UInt256 = u256(x.uint64) func ethTime*(x: Web3Quantity): common.EthTime = - common.EthTime(x.unsafeQuantityToInt64) + common.EthTime(x) func ethHash*(x: Web3PrevRandao): common.Hash256 = common.Hash256(data: distinctBase x) @@ -171,6 +171,12 @@ func w3Qty*(x: common.EthTime, y: int): Web3Quantity = func w3Qty*(x: Web3Quantity, y: int): Web3Quantity = Web3Quantity(x.uint64 + y.uint64) +func w3Qty*(x: Web3Quantity, y: EthTime): Web3Quantity = + Web3Quantity(x.uint64 + y.uint64) + +func w3Qty*(x: Web3Quantity, y: uint64): Web3Quantity = + Web3Quantity(x.uint64 + y) + func w3Qty*(x: Option[uint64]): Option[Web3Quantity] = if x.isNone: none(Web3Quantity) else: some(Web3Quantity x.get) diff --git a/nimbus/constants.nim b/nimbus/constants.nim index 62c2fdfb7..2a774d310 100644 --- a/nimbus/constants.nim +++ b/nimbus/constants.nim @@ -87,10 +87,10 @@ const MAX_ALLOWED_BLOB* = MAX_BLOB_GAS_PER_BLOCK div GAS_PER_BLOB # EIP-4788 addresses - # BeaconRootsStorageAddress is the address where historical beacon roots are stored as per EIP-4788 - BeaconRootsStorageAddress* = hexToByteArray[20]("0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02") - # SystemAddress is where the system-transaction is sent from as per EIP-4788 - SystemAddress* = hexToByteArray[20]("0xfffffffffffffffffffffffffffffffffffffffe") + # BEACON_ROOTS_ADDRESS is the address where historical beacon roots are stored as per EIP-4788 + BEACON_ROOTS_ADDRESS* = hexToByteArray[20]("0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02") + # SYSTEM_ADDRESS is where the system-transaction is sent from as per EIP-4788 + SYSTEM_ADDRESS* = hexToByteArray[20]("0xfffffffffffffffffffffffffffffffffffffffe") RIPEMD_ADDR* = block: proc initAddress(x: int): EthAddress {.compileTime.} = diff --git a/nimbus/core/casper.nim b/nimbus/core/casper.nim index fe8df6d01..2d87e6b7f 100644 --- a/nimbus/core/casper.nim +++ b/nimbus/core/casper.nim @@ -11,10 +11,11 @@ import type CasperRef* = ref object - feeRecipient : EthAddress - timestamp : EthTime - prevRandao : Hash256 - parentBeaconBlockRoot: Hash256 + feeRecipient: EthAddress + timestamp : EthTime + prevRandao : Hash256 + withdrawals : seq[Withdrawal] ## EIP-4895 + beaconRoot : Hash256 ## EIP-4788 proc prepare*(ctx: CasperRef, header: var BlockHeader) = header.coinbase = ctx.feeRecipient @@ -41,8 +42,11 @@ func timestamp*(ctx: CasperRef): EthTime = func prevRandao*(ctx: CasperRef): Hash256 = ctx.prevRandao +proc withdrawals*(ctx: CasperRef): seq[Withdrawal] = + ctx.withdrawals + func parentBeaconBlockRoot*(ctx: CasperRef): Hash256 = - ctx.parentBeaconBlockRoot + ctx.beaconRoot # ------------------------------------------------------------------------------ # Setters @@ -57,5 +61,8 @@ proc `timestamp=`*(ctx: CasperRef, val: EthTime) = proc `prevRandao=`*(ctx: CasperRef, val: Hash256) = ctx.prevRandao = val +proc `withdrawals=`*(ctx: CasperRef, val: sink seq[Withdrawal]) = + ctx.withdrawals = system.move(val) + proc `parentBeaconBlockRoot=`*(ctx: CasperRef, val: Hash256) = - ctx.parentBeaconBlockRoot = val + ctx.beaconRoot = val diff --git a/nimbus/core/eip4844.nim b/nimbus/core/eip4844.nim index fc4315dcc..625d19db4 100644 --- a/nimbus/core/eip4844.nim +++ b/nimbus/core/eip4844.nim @@ -26,12 +26,12 @@ type const BLS_MODULUS_STR = "52435875175126190479447740508185965837690552500527637822603658699938581184513" - BLS_MODULUS = parse(BLS_MODULUS_STR, UInt256, 10) + BLS_MODULUS* = parse(BLS_MODULUS_STR, UInt256, 10).toBytesBE PrecompileInputLength = 192 proc pointEvaluationResult(): Bytes64 {.compileTime.} = result[0..<32] = FIELD_ELEMENTS_PER_BLOB.u256.toBytesBE[0..^1] - result[32..^1] = BLS_MODULUS.toBytesBE[0..^1] + result[32..^1] = BLS_MODULUS[0..^1] const PointEvaluationResult* = pointEvaluationResult() @@ -39,7 +39,7 @@ const # kzgToVersionedHash implements kzg_to_versioned_hash from EIP-4844 -proc kzgToVersionedHash(kzg: kzg.KZGCommitment): VersionedHash = +proc kzgToVersionedHash*(kzg: kzg.KZGCommitment): VersionedHash = result = sha256.digest(kzg) result.data[0] = VERSIONED_HASH_VERSION_KZG diff --git a/nimbus/core/executor/process_transaction.nim b/nimbus/core/executor/process_transaction.nim index e36289d71..0edcf184b 100644 --- a/nimbus/core/executor/process_transaction.nim +++ b/nimbus/core/executor/process_transaction.nim @@ -141,10 +141,10 @@ proc processBeaconBlockRoot*(vmState: BaseVMState, beaconRoot: Hash256): statedb = vmState.stateDB call = CallParams( vmState : vmState, - sender : SystemAddress, + sender : SYSTEM_ADDRESS, gasLimit : 30_000_000.GasInt, gasPrice : 0.GasInt, - to : BeaconRootsStorageAddress, + to : BEACON_ROOTS_ADDRESS, input : @(beaconRoot.data), # It's a systemCall, no need for other knicks knacks diff --git a/nimbus/core/tx_pool.nim b/nimbus/core/tx_pool.nim index 7dae8278b..4290b95c1 100644 --- a/nimbus/core/tx_pool.nim +++ b/nimbus/core/tx_pool.nim @@ -436,7 +436,8 @@ import chronicles, eth/keys, stew/[keyed_queue, results], - ../common/common + ../common/common, + ./casper export TxItemRef, @@ -627,12 +628,12 @@ proc ethBlock*(xp: TxPoolRef, someBaseFee: bool = false): EthBlock let com = xp.chain.com if com.forkGTE(Shanghai): - result.withdrawals = some(xp.chain.withdrawals) + result.withdrawals = some(com.pos.withdrawals) if someBaseFee: # make sure baseFee always has something result.header.fee = some(result.header.fee.get(0.u256)) - + proc gasCumulative*(xp: TxPoolRef): GasInt = ## Getter, retrieves the gas that will be burned in the block after ## retrieving it via `ethBlock`. @@ -778,9 +779,6 @@ proc `minTipPrice=`*(xp: TxPoolRef; val: GasPrice) = xp.pMinTipPrice = val xp.pDirtyBuckets = true -proc `withdrawals=`*(xp: TxPoolRef, val: sink seq[Withdrawal]) = - xp.chain.withdrawals = system.move(val) - # ------------------------------------------------------------------------------ # Public functions, per-tx-item operations # ------------------------------------------------------------------------------ diff --git a/nimbus/core/tx_pool/tx_chain.nim b/nimbus/core/tx_pool/tx_chain.nim index a4ef2fbe2..c5a05ecd6 100644 --- a/nimbus/core/tx_pool/tx_chain.nim +++ b/nimbus/core/tx_pool/tx_chain.nim @@ -70,7 +70,6 @@ type limits: TxChainGasLimits ## Gas limits for packer and next header txEnv: TxChainPackerEnv ## Assorted parameters, tx packer environment prepHeader: BlockHeader ## Prepared Header from Consensus Engine - withdrawals: seq[Withdrawal] ## EIP-4895 # ------------------------------------------------------------------------------ # Private functions @@ -232,7 +231,7 @@ proc getHeader*(dh: TxChainRef): BlockHeader excessBlobGas: dh.txEnv.excessBlobGas) if dh.com.forkGTE(Shanghai): - result.withdrawalsRoot = some(calcWithdrawalsRoot(dh.withdrawals)) + result.withdrawalsRoot = some(calcWithdrawalsRoot(dh.com.pos.withdrawals)) if dh.com.forkGTE(Cancun): result.parentBeaconBlockRoot = some(dh.com.pos.parentBeaconBlockRoot) @@ -321,10 +320,6 @@ proc vmState*(dh: TxChainRef): BaseVMState = ## Getter, `BaseVmState` descriptor based on the current insertion point. dh.txEnv.vmState -proc withdrawals*(dh: TxChainRef): seq[Withdrawal] = - ## Getter, `BaseVmState` descriptor based on the current insertion point. - dh.withdrawals - # ------------------------------------------------------------------------------ # Public functions, setters # ------------------------------------------------------------------------------ @@ -387,9 +382,6 @@ proc `txRoot=`*(dh: TxChainRef; val: Hash256) = ## Setter dh.txEnv.txRoot = val -proc `withdrawals=`*(dh: TxChainRef, val: sink seq[Withdrawal]) = - dh.withdrawals = system.move(val) - proc `excessBlobGas=`*(dh: TxChainRef; val: Option[uint64]) = ## Setter dh.txEnv.excessBlobGas = val diff --git a/nimbus/core/tx_pool/tx_tasks/tx_packer.nim b/nimbus/core/tx_pool/tx_tasks/tx_packer.nim index abae2e8f9..101ec8047 100644 --- a/nimbus/core/tx_pool/tx_tasks/tx_packer.nim +++ b/nimbus/core/tx_pool/tx_tasks/tx_packer.nim @@ -21,7 +21,7 @@ import ../../../db/[accounts_cache, core_db], ../../../common/common, ../../../utils/utils, - "../.."/[dao, executor, validate, eip4844], + "../.."/[dao, executor, validate, eip4844, casper], ../../../transaction/call_evm, ../../../transaction, ../../../vm_state, @@ -164,6 +164,11 @@ proc vmExecInit(xp: TxPoolRef): TxPackerStateRef xp.chain.vmState.mutateStateDB: db.applyDAOHardFork() + # EIP-4788 + if xp.chain.nextFork >= FkCancun: + let beaconRoot = xp.chain.com.pos.parentBeaconBlockRoot + discard xp.chain.vmState.processBeaconBlockRoot(beaconRoot) + TxPackerStateRef( # return value xp: xp, tr: newCoreDbRef(LegacyDbMemory).mptPrune, @@ -225,7 +230,7 @@ proc vmExecCommit(pst: TxPackerStateRef) # EIP-4895 if xp.chain.nextFork >= FkShanghai: - for withdrawal in xp.chain.withdrawals: + for withdrawal in xp.chain.com.pos.withdrawals: vmState.stateDB.addBalance(withdrawal.address, withdrawal.weiAmount) # EIP-3675: no reward for miner in POA/POS diff --git a/nimbus/db/accounts_cache.nim b/nimbus/db/accounts_cache.nim index 653cb68b9..221cd559d 100644 --- a/nimbus/db/accounts_cache.nim +++ b/nimbus/db/accounts_cache.nim @@ -455,7 +455,7 @@ proc subBalance*(ac: AccountsCache, address: EthAddress, delta: UInt256) {.inlin # This zero delta early exit is important as shown in EIP-4788. # If the account is created, it will change the state. # But early exit will prevent the account creation. - # In this case, the SystemAddress + # In this case, the SYSTEM_ADDRESS return ac.setBalance(address, ac.getBalance(address) - delta) diff --git a/nimbus/db/ledger/accounts_cache.nim b/nimbus/db/ledger/accounts_cache.nim index f44b2979a..b022d39d1 100644 --- a/nimbus/db/ledger/accounts_cache.nim +++ b/nimbus/db/ledger/accounts_cache.nim @@ -455,7 +455,7 @@ proc subBalance*(ac: AccountsCache, address: EthAddress, delta: UInt256) {.inlin # This zero delta early exit is important as shown in EIP-4788. # If the account is created, it will change the state. # But early exit will prevent the account creation. - # In this case, the SystemAddress + # In this case, the SYSTEM_ADDRESS return ac.setBalance(address, ac.getBalance(address) - delta) diff --git a/nimbus/db/ledger/accounts_ledger.nim b/nimbus/db/ledger/accounts_ledger.nim index 7d335d3ae..fe3f27469 100644 --- a/nimbus/db/ledger/accounts_ledger.nim +++ b/nimbus/db/ledger/accounts_ledger.nim @@ -442,7 +442,7 @@ proc subBalance*(ac: AccountsLedgerRef, address: EthAddress, delta: UInt256) = # This zero delta early exit is important as shown in EIP-4788. # If the account is created, it will change the state. # But early exit will prevent the account creation. - # In this case, the SystemAddress + # In this case, the SYSTEM_ADDRESS return ac.setBalance(address, ac.getBalance(address) - delta) diff --git a/nimbus/utils/debug.nim b/nimbus/utils/debug.nim index ddbdb9878..b0dcbea37 100644 --- a/nimbus/utils/debug.nim +++ b/nimbus/utils/debug.nim @@ -56,6 +56,8 @@ proc debug*(h: BlockHeader): string = result.add "blobGasUsed : " & $h.blobGasUsed.get() & "\n" if h.excessBlobGas.isSome: result.add "excessBlobGas : " & $h.excessBlobGas.get() & "\n" + if h.parentBeaconBlockRoot.isSome: + result.add "beaconRoot : " & $h.parentBeaconBlockRoot.get() & "\n" result.add "blockHash : " & $blockHash(h) & "\n" proc dumpAccount(stateDB: AccountsCache, address: EthAddress): JsonNode =