mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-05 08:45:27 +00:00
Integrate PoS payload attributes into txPool (#2998)
* Integrate PoS payload attributes into txPool * Fix test_txpool
This commit is contained in:
parent
6e83a48969
commit
288ee28077
@ -1,5 +1,5 @@
|
||||
# Nimbus
|
||||
# Copyright (c) 2023-2024 Status Research & Development GmbH
|
||||
# Copyright (c) 2023-2025 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||
@ -16,7 +16,7 @@ import
|
||||
./payload_conv,
|
||||
./payload_queue,
|
||||
./api_handler/api_utils,
|
||||
../core/[tx_pool, casper, chain]
|
||||
../core/[tx_pool, chain]
|
||||
|
||||
export
|
||||
chain,
|
||||
@ -68,12 +68,12 @@ const
|
||||
# Private helpers
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
func setWithdrawals(ctx: CasperRef, attrs: PayloadAttributes) =
|
||||
func setWithdrawals(xp: TxPoolRef, attrs: PayloadAttributes) =
|
||||
case attrs.version
|
||||
of Version.V2, Version.V3:
|
||||
ctx.withdrawals = ethWithdrawals attrs.withdrawals.get
|
||||
xp.withdrawals = ethWithdrawals attrs.withdrawals.get
|
||||
else:
|
||||
ctx.withdrawals = @[]
|
||||
xp.withdrawals = @[]
|
||||
|
||||
template wrapException(body: untyped): auto =
|
||||
try:
|
||||
@ -146,19 +146,18 @@ proc generateExecutionBundle*(ben: BeaconEngineRef,
|
||||
wrapException:
|
||||
let
|
||||
xp = ben.txPool
|
||||
pos = xp.com.pos
|
||||
headBlock = ben.chain.latestHeader
|
||||
|
||||
pos.prevRandao = attrs.prevRandao
|
||||
pos.timestamp = ethTime attrs.timestamp
|
||||
pos.feeRecipient = attrs.suggestedFeeRecipient
|
||||
xp.prevRandao = attrs.prevRandao
|
||||
xp.timestamp = ethTime attrs.timestamp
|
||||
xp.feeRecipient = attrs.suggestedFeeRecipient
|
||||
|
||||
if attrs.parentBeaconBlockRoot.isSome:
|
||||
pos.parentBeaconBlockRoot = attrs.parentBeaconBlockRoot.get
|
||||
xp.parentBeaconBlockRoot = attrs.parentBeaconBlockRoot.get
|
||||
|
||||
pos.setWithdrawals(attrs)
|
||||
xp.setWithdrawals(attrs)
|
||||
|
||||
if pos.timestamp <= headBlock.timestamp:
|
||||
if xp.timestamp <= headBlock.timestamp:
|
||||
return err "timestamp must be strictly later than parent"
|
||||
|
||||
# someBaseFee = true: make sure bundle.blk.header
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Nimbus
|
||||
# Copyright (c) 2022-2024 Status Research & Development GmbH
|
||||
# Copyright (c) 2022-2025 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||
@ -11,7 +11,6 @@
|
||||
|
||||
import
|
||||
chronicles,
|
||||
../core/casper,
|
||||
../db/[core_db, ledger, storage_types],
|
||||
../utils/[utils],
|
||||
".."/[constants, errors, version],
|
||||
@ -90,9 +89,6 @@ type
|
||||
## installing a snapshot pivot. The default value for this field is
|
||||
## `GENESIS_PARENT_HASH` to start at the very beginning.
|
||||
|
||||
pos: CasperRef
|
||||
## Proof Of Stake descriptor
|
||||
|
||||
pruneHistory: bool
|
||||
## Must not not set for a full node, might go away some time
|
||||
|
||||
@ -181,7 +177,6 @@ proc init(com : CommonRef,
|
||||
com.syncProgress= SyncProgress()
|
||||
com.syncState = Waiting
|
||||
com.pruneHistory= pruneHistory
|
||||
com.pos = CasperRef.new
|
||||
com.extraData = ShortClientId
|
||||
com.taskpool = taskpool
|
||||
com.gasLimit = DEFAULT_GAS_LIMIT
|
||||
@ -202,7 +197,6 @@ proc init(com : CommonRef,
|
||||
toGenesisHeader(genesis, fork, com.db)
|
||||
|
||||
com.setForkId(com.genesisHeader)
|
||||
com.pos.timestamp = genesis.timestamp
|
||||
|
||||
# By default, history begins at genesis.
|
||||
com.startOfHistory = GENESIS_PARENT_HASH
|
||||
@ -276,7 +270,6 @@ func clone*(com: CommonRef, db: CoreDbRef): CommonRef =
|
||||
genesisHeader: com.genesisHeader,
|
||||
syncProgress : com.syncProgress,
|
||||
networkId : com.networkId,
|
||||
pos : com.pos,
|
||||
pruneHistory : com.pruneHistory)
|
||||
|
||||
func clone*(com: CommonRef): CommonRef =
|
||||
@ -363,10 +356,6 @@ func startOfHistory*(com: CommonRef): Hash32 =
|
||||
## Getter
|
||||
com.startOfHistory
|
||||
|
||||
func pos*(com: CommonRef): CasperRef =
|
||||
## Getter
|
||||
com.pos
|
||||
|
||||
func db*(com: CommonRef): CoreDbRef =
|
||||
com.db
|
||||
|
||||
|
@ -1,56 +0,0 @@
|
||||
# Nimbus
|
||||
# Copyright (c) 2022-2024 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/blocks
|
||||
|
||||
type
|
||||
CasperRef* = ref object
|
||||
feeRecipient: Address
|
||||
timestamp : EthTime
|
||||
prevRandao : Bytes32
|
||||
withdrawals : seq[Withdrawal] ## EIP-4895
|
||||
beaconRoot : Hash32 ## EIP-4788
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Getters
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
func feeRecipient*(ctx: CasperRef): Address =
|
||||
ctx.feeRecipient
|
||||
|
||||
func timestamp*(ctx: CasperRef): EthTime =
|
||||
ctx.timestamp
|
||||
|
||||
func prevRandao*(ctx: CasperRef): Bytes32 =
|
||||
ctx.prevRandao
|
||||
|
||||
proc withdrawals*(ctx: CasperRef): seq[Withdrawal] =
|
||||
ctx.withdrawals
|
||||
|
||||
func parentBeaconBlockRoot*(ctx: CasperRef): Hash32 =
|
||||
ctx.beaconRoot
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Setters
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc `feeRecipient=`*(ctx: CasperRef, val: Address) =
|
||||
ctx.feeRecipient = val
|
||||
|
||||
proc `timestamp=`*(ctx: CasperRef, val: EthTime) =
|
||||
ctx.timestamp = val
|
||||
|
||||
proc `prevRandao=`*(ctx: CasperRef, val: Bytes32) =
|
||||
ctx.prevRandao = val
|
||||
|
||||
proc `withdrawals=`*(ctx: CasperRef, val: sink seq[Withdrawal]) =
|
||||
ctx.withdrawals = system.move(val)
|
||||
|
||||
proc `parentBeaconBlockRoot=`*(ctx: CasperRef, val: Hash32) =
|
||||
ctx.beaconRoot = val
|
@ -1,5 +1,5 @@
|
||||
# Nimbus
|
||||
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
||||
# Copyright (c) 2018-2025 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)
|
||||
@ -42,8 +42,7 @@ import
|
||||
./tx_pool/tx_item,
|
||||
./tx_pool/tx_desc,
|
||||
./tx_pool/tx_packer,
|
||||
./chain/forked_chain,
|
||||
./casper
|
||||
./chain/forked_chain
|
||||
|
||||
from eth/common/eth_types_rlp import rlpHash
|
||||
|
||||
@ -143,7 +142,7 @@ proc assembleBlock*(
|
||||
return err(error)
|
||||
|
||||
var blk = EthBlock(
|
||||
header: pst.assembleHeader
|
||||
header: pst.assembleHeader(xp)
|
||||
)
|
||||
var blobsBundle: BlobsBundle
|
||||
for item in pst.packedTxs:
|
||||
@ -160,7 +159,7 @@ proc assembleBlock*(
|
||||
|
||||
let com = xp.vmState.com
|
||||
if com.isShanghaiOrLater(blk.header.timestamp):
|
||||
blk.withdrawals = Opt.some(com.pos.withdrawals)
|
||||
blk.withdrawals = Opt.some(xp.withdrawals)
|
||||
|
||||
if not com.isCancunOrLater(blk.header.timestamp) and blobsBundle.commitments.len > 0:
|
||||
return err("PooledTransaction contains blobs prior to Cancun")
|
||||
@ -187,3 +186,37 @@ proc assembleBlock*(
|
||||
blobsBundle: blobsBundleOpt,
|
||||
blockValue: pst.blockValue,
|
||||
executionRequests: executionRequestsOpt)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# PoS payload attributes getters
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
export
|
||||
feeRecipient,
|
||||
timestamp,
|
||||
prevRandao,
|
||||
withdrawals,
|
||||
parentBeaconBlockRoot
|
||||
|
||||
# feeRecipient(xp: TxPoolRef): Address
|
||||
# timestamp(xp: TxPoolRef): EthTime
|
||||
# prevRandao(xp: TxPoolRef): Bytes32
|
||||
# withdrawals(xp: TxPoolRef): seq[Withdrawal]
|
||||
# parentBeaconBlockRoot(xp: TxPoolRef): Hash32
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# PoS payload attributes setters
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
export
|
||||
`feeRecipient=`,
|
||||
`timestamp=`,
|
||||
`prevRandao=`,
|
||||
`withdrawals=`,
|
||||
`parentBeaconBlockRoot=`
|
||||
|
||||
# `feeRecipient=`(xp: TxPoolRef, val: Address)
|
||||
# `timestamp=`(xp: TxPoolRef, val: EthTime)
|
||||
# `prevRandao=`(xp: TxPoolRef, val: Bytes32)
|
||||
# `withdrawals=`(xp: TxPoolRef, val: sink seq[Withdrawal])
|
||||
# `parentBeaconBlockRoot=`(xp: TxPoolRef, val: Hash32)
|
||||
|
@ -25,7 +25,6 @@ import
|
||||
../chain/forked_chain,
|
||||
../pow/header,
|
||||
../eip4844,
|
||||
../casper,
|
||||
../validate,
|
||||
./tx_tabs,
|
||||
./tx_item
|
||||
@ -36,12 +35,20 @@ logScope:
|
||||
topics = "txpool"
|
||||
|
||||
type
|
||||
PosPayloadAttr = object
|
||||
feeRecipient: Address
|
||||
timestamp : EthTime
|
||||
prevRandao : Bytes32
|
||||
withdrawals : seq[Withdrawal] ## EIP-4895
|
||||
beaconRoot : Hash32 ## EIP-4788
|
||||
|
||||
TxPoolRef* = ref object
|
||||
vmState : BaseVMState
|
||||
chain : ForkedChainRef
|
||||
senderTab: TxSenderTab
|
||||
idTab : TxIdTab
|
||||
rmHash : Hash32
|
||||
pos : PosPayloadAttr
|
||||
|
||||
const
|
||||
MAX_POOL_SIZE = 5000
|
||||
@ -65,9 +72,11 @@ func getGasLimit(com: CommonRef; parent: Header): GasInt =
|
||||
## Post Merge rule
|
||||
calcGasLimit1559(parent.gasLimit, desiredLimit = com.gasLimit)
|
||||
|
||||
proc setupVMState(com: CommonRef; parent: Header, parentHash: Hash32): BaseVMState =
|
||||
proc setupVMState(com: CommonRef;
|
||||
parent: Header,
|
||||
parentHash: Hash32,
|
||||
pos: PosPayloadAttr): BaseVMState =
|
||||
let
|
||||
pos = com.pos
|
||||
electra = com.isPragueOrLater(pos.timestamp)
|
||||
|
||||
BaseVMState.new(
|
||||
@ -158,8 +167,8 @@ proc classifyValid(xp: TxPoolRef; tx: Transaction, sender: Address): bool =
|
||||
return false
|
||||
|
||||
if tx.gasLimit > xp.gasLimit:
|
||||
debug "Invalid transaction: Gas limit too high",
|
||||
txGasLimit = tx.gasLimit,
|
||||
debug "Invalid transaction: Gas limit too high",
|
||||
txGasLimit = tx.gasLimit,
|
||||
gasLimit = xp.gasLimit
|
||||
return false
|
||||
|
||||
@ -167,8 +176,8 @@ proc classifyValid(xp: TxPoolRef; tx: Transaction, sender: Address): bool =
|
||||
# And to at least pay the current data gasprice
|
||||
if tx.txType >= TxEip1559:
|
||||
if tx.maxFeePerGas < xp.baseFee:
|
||||
debug "Invalid transaction: maxFeePerGas lower than baseFee",
|
||||
maxFeePerGas = tx.maxFeePerGas,
|
||||
debug "Invalid transaction: maxFeePerGas lower than baseFee",
|
||||
maxFeePerGas = tx.maxFeePerGas,
|
||||
baseFee = xp.baseFee
|
||||
return false
|
||||
|
||||
@ -178,8 +187,8 @@ proc classifyValid(xp: TxPoolRef; tx: Transaction, sender: Address): bool =
|
||||
electra = xp.vmState.fork >= FkPrague
|
||||
blobGasPrice = getBlobBaseFee(excessBlobGas, electra)
|
||||
if tx.maxFeePerBlobGas < blobGasPrice:
|
||||
debug "Invalid transaction: maxFeePerBlobGas lower than blobGasPrice",
|
||||
maxFeePerBlobGas = tx.maxFeePerBlobGas,
|
||||
debug "Invalid transaction: maxFeePerBlobGas lower than blobGasPrice",
|
||||
maxFeePerBlobGas = tx.maxFeePerBlobGas,
|
||||
blobGasPrice = blobGasPrice
|
||||
return false
|
||||
|
||||
@ -188,14 +197,14 @@ proc classifyValid(xp: TxPoolRef; tx: Transaction, sender: Address): bool =
|
||||
balance = xp.getBalance(sender)
|
||||
gasCost = tx.gasCost
|
||||
if balance < gasCost:
|
||||
debug "Invalid transaction: Insufficient balance for gas cost",
|
||||
balance = balance,
|
||||
debug "Invalid transaction: Insufficient balance for gas cost",
|
||||
balance = balance,
|
||||
gasCost = gasCost
|
||||
return false
|
||||
let balanceOffGasCost = balance - gasCost
|
||||
if balanceOffGasCost < tx.value:
|
||||
debug "Invalid transaction: Insufficient balance for tx value",
|
||||
balanceOffGasCost = balanceOffGasCost,
|
||||
debug "Invalid transaction: Insufficient balance for tx value",
|
||||
balanceOffGasCost = balanceOffGasCost,
|
||||
txValue = tx.value
|
||||
return false
|
||||
|
||||
@ -203,7 +212,7 @@ proc classifyValid(xp: TxPoolRef; tx: Transaction, sender: Address): bool =
|
||||
# high enough. These checks are optional.
|
||||
if tx.txType < TxEip1559:
|
||||
if tx.gasPrice < 0:
|
||||
debug "Invalid transaction: Legacy transaction with invalid gas price",
|
||||
debug "Invalid transaction: Legacy transaction with invalid gas price",
|
||||
gasPrice = tx.gasPrice
|
||||
return false
|
||||
|
||||
@ -220,12 +229,12 @@ proc classifyValid(xp: TxPoolRef; tx: Transaction, sender: Address): bool =
|
||||
if tx.maxFeePerGas < 1.GasInt:
|
||||
debug "Invalid transaction: EIP-1559 transaction with maxFeePerGas lower than 1"
|
||||
return false
|
||||
|
||||
|
||||
debug "Valid transaction",
|
||||
txType = tx.txType,
|
||||
txType = tx.txType,
|
||||
sender = sender,
|
||||
gasLimit = tx.gasLimit,
|
||||
gasPrice = tx.gasPrice,
|
||||
gasLimit = tx.gasLimit,
|
||||
gasPrice = tx.gasPrice,
|
||||
value = tx.value
|
||||
true
|
||||
|
||||
@ -235,8 +244,9 @@ proc classifyValid(xp: TxPoolRef; tx: Transaction, sender: Address): bool =
|
||||
|
||||
proc init*(xp: TxPoolRef; chain: ForkedChainRef) =
|
||||
## Constructor, returns new tx-pool descriptor.
|
||||
xp.pos.timestamp = chain.latestHeader.timestamp
|
||||
xp.vmState = setupVMState(chain.com,
|
||||
chain.latestHeader, chain.latestHash)
|
||||
chain.latestHeader, chain.latestHash, xp.pos)
|
||||
xp.chain = chain
|
||||
xp.rmHash = chain.latestHash
|
||||
|
||||
@ -272,7 +282,7 @@ func `rmHash=`*(xp: TxPoolRef, val: Hash32) =
|
||||
proc updateVmState*(xp: TxPoolRef) =
|
||||
## Reset transaction environment, e.g. before packing a new block
|
||||
xp.vmState = setupVMState(xp.chain.com,
|
||||
xp.chain.latestHeader, xp.chain.latestHash)
|
||||
xp.chain.latestHeader, xp.chain.latestHash, xp.pos)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public functions
|
||||
@ -303,16 +313,16 @@ proc removeExpiredTxs*(xp: TxPoolRef, lifeTime: Duration = TX_ITEM_LIFETIME) =
|
||||
|
||||
proc addTx*(xp: TxPoolRef, ptx: PooledTransaction): Result[void, TxError] =
|
||||
if not ptx.tx.validateChainId(xp.chain.com.chainId):
|
||||
debug "Transaction chain id mismatch",
|
||||
txChainId = ptx.tx.chainId,
|
||||
debug "Transaction chain id mismatch",
|
||||
txChainId = ptx.tx.chainId,
|
||||
chainId = xp.chain.com.chainId
|
||||
return err(txErrorChainIdMismatch)
|
||||
|
||||
|
||||
let id = ptx.rlpHash
|
||||
|
||||
if ptx.tx.txType == TxEip4844:
|
||||
ptx.validateBlobTransactionWrapper().isOkOr:
|
||||
debug "Invalid transaction: Blob transaction wrapper validation failed",
|
||||
debug "Invalid transaction: Blob transaction wrapper validation failed",
|
||||
tx = ptx.tx,
|
||||
error = error
|
||||
return err(txErrorInvalidBlob)
|
||||
@ -325,7 +335,7 @@ proc addTx*(xp: TxPoolRef, ptx: PooledTransaction): Result[void, TxError] =
|
||||
ptx.tx,
|
||||
xp.nextFork,
|
||||
validateFork = true).isOkOr:
|
||||
debug "Invalid transaction: Basic validation failed",
|
||||
debug "Invalid transaction: Basic validation failed",
|
||||
txHash = id,
|
||||
error = error
|
||||
return err(txErrorBasicValidation)
|
||||
@ -349,8 +359,8 @@ proc addTx*(xp: TxPoolRef, ptx: PooledTransaction): Result[void, TxError] =
|
||||
# xp.updateVmState()
|
||||
# maybe can solve the accuracy but it is quite expensive.
|
||||
if ptx.tx.nonce < nonce:
|
||||
debug "Transaction rejected: Nonce too small",
|
||||
txNonce = ptx.tx.nonce,
|
||||
debug "Transaction rejected: Nonce too small",
|
||||
txNonce = ptx.tx.nonce,
|
||||
nonce = nonce,
|
||||
sender = sender
|
||||
return err(txErrorNonceTooSmall)
|
||||
@ -369,7 +379,7 @@ proc addTx*(xp: TxPoolRef, ptx: PooledTransaction): Result[void, TxError] =
|
||||
?xp.insertToSenderTab(item)
|
||||
xp.idTab[item.id] = item
|
||||
|
||||
debug "Transaction added to txpool",
|
||||
debug "Transaction added to txpool",
|
||||
txHash = id,
|
||||
sender = sender,
|
||||
recipient = ptx.tx.getRecipient(sender),
|
||||
@ -386,3 +396,41 @@ iterator byPriceAndNonce*(xp: TxPoolRef): TxItemRef =
|
||||
for item in byPriceAndNonce(xp.senderTab, xp.idTab,
|
||||
xp.vmState.ledger, xp.baseFee):
|
||||
yield item
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# PoS payload attributes getters
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
func feeRecipient*(xp: TxPoolRef): Address =
|
||||
xp.pos.feeRecipient
|
||||
|
||||
func timestamp*(xp: TxPoolRef): EthTime =
|
||||
xp.pos.timestamp
|
||||
|
||||
func prevRandao*(xp: TxPoolRef): Bytes32 =
|
||||
xp.pos.prevRandao
|
||||
|
||||
proc withdrawals*(xp: TxPoolRef): seq[Withdrawal] =
|
||||
xp.pos.withdrawals
|
||||
|
||||
func parentBeaconBlockRoot*(xp: TxPoolRef): Hash32 =
|
||||
xp.pos.beaconRoot
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# PoS payload attributes setters
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc `feeRecipient=`*(xp: TxPoolRef, val: Address) =
|
||||
xp.pos.feeRecipient = val
|
||||
|
||||
proc `timestamp=`*(xp: TxPoolRef, val: EthTime) =
|
||||
xp.pos.timestamp = val
|
||||
|
||||
proc `prevRandao=`*(xp: TxPoolRef, val: Bytes32) =
|
||||
xp.pos.prevRandao = val
|
||||
|
||||
proc `withdrawals=`*(xp: TxPoolRef, val: sink seq[Withdrawal]) =
|
||||
xp.pos.withdrawals = system.move(val)
|
||||
|
||||
proc `parentBeaconBlockRoot=`*(xp: TxPoolRef, val: Hash32) =
|
||||
xp.pos.beaconRoot = val
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Nimbus
|
||||
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
||||
# Copyright (c) 2018-2025 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)
|
||||
@ -27,7 +27,6 @@ import
|
||||
../../evm/types,
|
||||
../executor,
|
||||
../validate,
|
||||
../casper,
|
||||
../eip4844,
|
||||
../eip6110,
|
||||
../eip7691,
|
||||
@ -101,9 +100,6 @@ func baseFee(pst: TxPacker): GasInt =
|
||||
else:
|
||||
0.GasInt
|
||||
|
||||
func feeRecipient(pst: TxPacker): Address =
|
||||
pst.vmState.com.pos.feeRecipient
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Private functions
|
||||
# ------------------------------------------------------------------------------
|
||||
@ -115,7 +111,7 @@ proc runTx(pst: var TxPacker; item: TxItemRef): GasInt =
|
||||
doAssert 0 <= gasUsed
|
||||
gasUsed
|
||||
|
||||
proc runTxCommit(pst: var TxPacker; item: TxItemRef; gasBurned: GasInt) =
|
||||
proc runTxCommit(pst: var TxPacker; item: TxItemRef; gasBurned: GasInt, xp: TxPoolRef) =
|
||||
## Book keeping after executing argument `item` transaction in the VM. The
|
||||
## function returns the next number of items `nItems+1`.
|
||||
let
|
||||
@ -124,7 +120,7 @@ proc runTxCommit(pst: var TxPacker; item: TxItemRef; gasBurned: GasInt) =
|
||||
gasTip = item.tx.tip(pst.baseFee)
|
||||
|
||||
let reward = gasBurned.u256 * gasTip.u256
|
||||
vmState.ledger.addBalance(pst.feeRecipient, reward)
|
||||
vmState.ledger.addBalance(xp.feeRecipient, reward)
|
||||
pst.blockValue += reward
|
||||
|
||||
# Update receipts sequence
|
||||
@ -154,7 +150,7 @@ proc vmExecInit(xp: TxPoolRef): Result[TxPacker, string] =
|
||||
|
||||
# EIP-4788
|
||||
if xp.nextFork >= FkCancun:
|
||||
let beaconRoot = xp.vmState.com.pos.parentBeaconBlockRoot
|
||||
let beaconRoot = xp.parentBeaconBlockRoot
|
||||
xp.vmState.processBeaconBlockRoot(beaconRoot).isOkOr:
|
||||
return err(error)
|
||||
|
||||
@ -165,7 +161,7 @@ proc vmExecInit(xp: TxPoolRef): Result[TxPacker, string] =
|
||||
|
||||
ok(packer)
|
||||
|
||||
proc vmExecGrabItem(pst: var TxPacker; item: TxItemRef): bool =
|
||||
proc vmExecGrabItem(pst: var TxPacker; item: TxItemRef, xp: TxPoolRef): bool =
|
||||
## Greedily collect & compact items as long as the accumulated `gasLimit`
|
||||
## values are below the maximum block size.
|
||||
let
|
||||
@ -215,7 +211,7 @@ proc vmExecGrabItem(pst: var TxPacker; item: TxItemRef): bool =
|
||||
vmState.ledger.persist(clearEmptyAccount = vmState.fork >= FkSpurious)
|
||||
|
||||
# Finish book-keeping
|
||||
pst.runTxCommit(item, gasUsed)
|
||||
pst.runTxCommit(item, gasUsed, xp)
|
||||
|
||||
pst.numBlobPerBlock += item.tx.versionedHashes.len
|
||||
vmState.blobGasUsed += blobGasUsed
|
||||
@ -223,14 +219,14 @@ proc vmExecGrabItem(pst: var TxPacker; item: TxItemRef): bool =
|
||||
|
||||
ContinueWithNextAccount
|
||||
|
||||
proc vmExecCommit(pst: var TxPacker): Result[void, string] =
|
||||
proc vmExecCommit(pst: var TxPacker, xp: TxPoolRef): Result[void, string] =
|
||||
let
|
||||
vmState = pst.vmState
|
||||
ledger = vmState.ledger
|
||||
|
||||
# EIP-4895
|
||||
if vmState.fork >= FkShanghai:
|
||||
for withdrawal in vmState.com.pos.withdrawals:
|
||||
for withdrawal in xp.withdrawals:
|
||||
ledger.addBalance(withdrawal.address, withdrawal.weiAmount)
|
||||
|
||||
# EIP-6110, EIP-7002, EIP-7251
|
||||
@ -264,11 +260,11 @@ proc packerVmExec*(xp: TxPoolRef): Result[TxPacker, string] =
|
||||
return err(error)
|
||||
|
||||
for item in xp.byPriceAndNonce:
|
||||
let rc = pst.vmExecGrabItem(item)
|
||||
let rc = pst.vmExecGrabItem(item, xp)
|
||||
if rc == StopCollecting:
|
||||
break
|
||||
|
||||
?pst.vmExecCommit()
|
||||
?pst.vmExecCommit(xp)
|
||||
ok(pst)
|
||||
|
||||
func getExtraData(com: CommonRef): seq[byte] =
|
||||
@ -277,17 +273,16 @@ func getExtraData(com: CommonRef): seq[byte] =
|
||||
else:
|
||||
com.extraData.toBytes
|
||||
|
||||
proc assembleHeader*(pst: TxPacker): Header =
|
||||
proc assembleHeader*(pst: TxPacker, xp: TxPoolRef): Header =
|
||||
## Generate a new header, a child of the cached `head`
|
||||
let
|
||||
vmState = pst.vmState
|
||||
com = vmState.com
|
||||
pos = com.pos
|
||||
|
||||
result = Header(
|
||||
parentHash: vmState.blockCtx.parentHash,
|
||||
ommersHash: EMPTY_UNCLE_HASH,
|
||||
coinbase: pos.feeRecipient,
|
||||
coinbase: xp.feeRecipient,
|
||||
stateRoot: pst.stateRoot,
|
||||
receiptsRoot: pst.receiptsRoot,
|
||||
logsBloom: pst.logsBloom,
|
||||
@ -295,22 +290,22 @@ proc assembleHeader*(pst: TxPacker): Header =
|
||||
number: vmState.blockNumber,
|
||||
gasLimit: vmState.blockCtx.gasLimit,
|
||||
gasUsed: vmState.cumulativeGasUsed,
|
||||
timestamp: pos.timestamp,
|
||||
timestamp: xp.timestamp,
|
||||
extraData: getExtraData(com),
|
||||
mixHash: pos.prevRandao,
|
||||
mixHash: xp.prevRandao,
|
||||
nonce: default(Bytes8),
|
||||
baseFeePerGas: vmState.blockCtx.baseFeePerGas,
|
||||
)
|
||||
|
||||
if com.isShanghaiOrLater(pos.timestamp):
|
||||
result.withdrawalsRoot = Opt.some(calcWithdrawalsRoot(pos.withdrawals))
|
||||
if com.isShanghaiOrLater(xp.timestamp):
|
||||
result.withdrawalsRoot = Opt.some(calcWithdrawalsRoot(xp.withdrawals))
|
||||
|
||||
if com.isCancunOrLater(pos.timestamp):
|
||||
result.parentBeaconBlockRoot = Opt.some(pos.parentBeaconBlockRoot)
|
||||
if com.isCancunOrLater(xp.timestamp):
|
||||
result.parentBeaconBlockRoot = Opt.some(xp.parentBeaconBlockRoot)
|
||||
result.blobGasUsed = Opt.some vmState.blobGasUsed
|
||||
result.excessBlobGas = Opt.some vmState.blockCtx.excessBlobGas
|
||||
|
||||
if com.isPragueOrLater(pos.timestamp):
|
||||
if com.isPragueOrLater(xp.timestamp):
|
||||
let requestsHash = calcRequestsHash([
|
||||
(DEPOSIT_REQUEST_TYPE, pst.depositReqs),
|
||||
(WITHDRAWAL_REQUEST_TYPE, pst.withdrawalReqs),
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Nimbus
|
||||
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
||||
# Copyright (c) 2018-2025 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)
|
||||
@ -18,7 +18,6 @@ import
|
||||
../nimbus/common/common,
|
||||
../nimbus/core/chain,
|
||||
../nimbus/core/tx_pool,
|
||||
../nimbus/core/casper,
|
||||
../nimbus/transaction,
|
||||
../nimbus/constants,
|
||||
../nimbus/db/ledger {.all.}, # import all private symbols
|
||||
@ -312,13 +311,13 @@ proc runLedgerTransactionTests(noisy = true) =
|
||||
for _ in 0..<NumTransactions:
|
||||
let recipient = initAddr(recipientSeed)
|
||||
let tx = env.makeTx(recipient, 1.u256)
|
||||
check env.xp.addTx(tx).isOk
|
||||
check env.xp.addTx(tx).isOk
|
||||
inc recipientSeed
|
||||
|
||||
check env.xp.len == NumTransactions
|
||||
env.com.pos.prevRandao = prevRandao
|
||||
env.com.pos.feeRecipient = feeRecipient
|
||||
env.com.pos.timestamp = blockTime
|
||||
env.xp.prevRandao = prevRandao
|
||||
env.xp.feeRecipient = feeRecipient
|
||||
env.xp.timestamp = blockTime
|
||||
|
||||
blockTime = EthTime(blockTime.uint64 + 1'u64)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Nimbus
|
||||
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
||||
# Copyright (c) 2018-2025 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)
|
||||
@ -18,7 +18,7 @@ import
|
||||
../nimbus/[constants, transaction, config, version],
|
||||
../nimbus/db/[ledger, storage_types],
|
||||
../nimbus/sync/protocol,
|
||||
../nimbus/core/[tx_pool, chain, pow/difficulty, casper],
|
||||
../nimbus/core/[tx_pool, chain, pow/difficulty],
|
||||
../nimbus/utils/utils,
|
||||
../nimbus/[common, rpc],
|
||||
../nimbus/rpc/rpc_types,
|
||||
@ -236,9 +236,9 @@ proc generateBlock(env: var TestEnv) =
|
||||
doAssert(xp.len == 2)
|
||||
|
||||
# generate block
|
||||
com.pos.prevRandao = prevRandao
|
||||
com.pos.feeRecipient = feeRecipient
|
||||
com.pos.timestamp = EthTime.now()
|
||||
xp.prevRandao = prevRandao
|
||||
xp.feeRecipient = feeRecipient
|
||||
xp.timestamp = EthTime.now()
|
||||
|
||||
let bundle = xp.assembleBlock().valueOr:
|
||||
debugEcho error
|
||||
|
@ -21,7 +21,6 @@ import
|
||||
../nimbus/[config, transaction, constants],
|
||||
../nimbus/core/tx_pool,
|
||||
../nimbus/core/tx_pool/tx_desc,
|
||||
../nimbus/core/casper,
|
||||
../nimbus/common/common,
|
||||
../nimbus/utils/utils,
|
||||
./macro_assembler
|
||||
@ -111,7 +110,7 @@ template checkAddTxSupersede(xp, tx) =
|
||||
check xp.len == prevCount
|
||||
|
||||
template checkAssembleBlock(xp, expCount): auto =
|
||||
xp.com.pos.timestamp = xp.com.pos.timestamp + 1
|
||||
xp.timestamp = xp.timestamp + 1
|
||||
let rc = xp.assembleBlock()
|
||||
check rc.isOk == true
|
||||
if rc.isErr:
|
||||
@ -186,9 +185,9 @@ proc txPoolMain*() =
|
||||
chain = env.chain
|
||||
com = env.com
|
||||
|
||||
com.pos.prevRandao = prevRandao
|
||||
com.pos.feeRecipient = feeRecipient
|
||||
com.pos.timestamp = EthTime.now()
|
||||
xp.prevRandao = prevRandao
|
||||
xp.feeRecipient = feeRecipient
|
||||
xp.timestamp = EthTime.now()
|
||||
|
||||
test "Bad blob tx":
|
||||
let acc = mx.getAccount(7)
|
||||
@ -334,7 +333,7 @@ proc txPoolMain*() =
|
||||
|
||||
var numTxsPacked = 0
|
||||
while numTxsPacked < MAX_TXS_GENERATED:
|
||||
com.pos.timestamp = com.pos.timestamp + 1
|
||||
xp.timestamp = xp.timestamp + 1
|
||||
let bundle = xp.assembleBlock().valueOr:
|
||||
debugEcho error
|
||||
check false
|
||||
@ -370,6 +369,8 @@ proc txPoolMain*() =
|
||||
xp.checkAddTx(ptx2)
|
||||
|
||||
xp2.checkImportBlock(2, 0)
|
||||
|
||||
xp.timestamp = xp2.timestamp + 1
|
||||
xp.checkImportBlock(1, 0)
|
||||
|
||||
test "mixed type of transactions":
|
||||
|
Loading…
x
Reference in New Issue
Block a user