164 lines
4.7 KiB
Nim
164 lines
4.7 KiB
Nim
# Nimbus
|
|
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
|
# Licensed under either of
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
|
# http://www.apache.org/licenses/LICENSE-2.0)
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
|
# http://opensource.org/licenses/MIT)
|
|
# at your option. This file may not be copied, modified, or distributed except
|
|
# according to those terms.
|
|
|
|
{.push raises: [].}
|
|
|
|
import
|
|
eth/common/blocks,
|
|
./tx_pool/tx_tabs,
|
|
./tx_pool/tx_item,
|
|
./tx_pool/tx_desc,
|
|
./tx_pool/tx_packer,
|
|
./chain/forked_chain,
|
|
./casper
|
|
|
|
from eth/common/eth_types_rlp import rlpHash
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# TxPoolRef public types
|
|
# ------------------------------------------------------------------------------
|
|
|
|
export
|
|
TxPoolRef,
|
|
TxError
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# TxItemRef public getters
|
|
# ------------------------------------------------------------------------------
|
|
|
|
export
|
|
tx, # : Transaction
|
|
pooledTx, # : PooledTransaction
|
|
id, # : Hash32
|
|
sender # : Address
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# TxPoolRef constructor
|
|
# ------------------------------------------------------------------------------
|
|
|
|
proc new*(T: type TxPoolRef; chain: ForkedChainRef): T =
|
|
## Constructor, returns a new tx-pool descriptor.
|
|
new result
|
|
result.init(chain)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# TxPoolRef public getters
|
|
# ------------------------------------------------------------------------------
|
|
|
|
export
|
|
chain,
|
|
com,
|
|
len
|
|
|
|
# chain(xp: TxPoolRef): ForkedChainRef
|
|
# com(xp: TxPoolRef): CommonRef
|
|
# len(xp: TxPoolRef): int
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# TxPoolRef public functions
|
|
# ------------------------------------------------------------------------------
|
|
|
|
export
|
|
addTx,
|
|
getItem,
|
|
removeTx,
|
|
removeExpiredTxs
|
|
|
|
# addTx(xp: TxPoolRef, ptx: PooledTransaction): Result[void, TxError]
|
|
# addTx(xp: TxPoolRef, tx: Transaction): Result[void, TxError]
|
|
# getItem(xp: TxPoolRef, id: Hash32): Result[TxItemRef, TxError]
|
|
# removeTx(xp: TxPoolRef, id: Hash32)
|
|
# removeExpiredTxs(xp: TxPoolRef, lifeTime: Duration)
|
|
|
|
proc removeNewBlockTxs*(xp: TxPoolRef, blk: Block, optHash = Opt.none(Hash32)) =
|
|
let fromHash = if optHash.isSome: optHash.get
|
|
else: blk.header.blockHash
|
|
|
|
# Up to date, no need for further actions
|
|
if fromHash == xp.rmHash:
|
|
return
|
|
|
|
# Remove only the latest block transactions
|
|
if blk.header.parentHash == xp.rmHash:
|
|
for tx in blk.transactions:
|
|
let txHash = rlpHash(tx)
|
|
xp.removeTx(txHash)
|
|
|
|
xp.rmHash = fromHash
|
|
return
|
|
|
|
# Also remove transactions from older blocks
|
|
for txHash in xp.chain.txHashInRange(fromHash, xp.rmHash):
|
|
xp.removeTx(txHash)
|
|
|
|
xp.rmHash = fromHash
|
|
|
|
type AssembledBlock* = object
|
|
blk*: EthBlock
|
|
blobsBundle*: Opt[BlobsBundle]
|
|
blockValue*: UInt256
|
|
executionRequests*: Opt[seq[seq[byte]]]
|
|
|
|
proc assembleBlock*(
|
|
xp: TxPoolRef,
|
|
someBaseFee: bool = false
|
|
): Result[AssembledBlock, string] =
|
|
xp.updateVmState()
|
|
|
|
# Run EVM with most profitable transactions
|
|
var pst = xp.packerVmExec().valueOr:
|
|
return err(error)
|
|
|
|
var blk = EthBlock(
|
|
header: pst.assembleHeader
|
|
)
|
|
var blobsBundle: BlobsBundle
|
|
for item in pst.packedTxs:
|
|
let tx = item.pooledTx
|
|
blk.txs.add tx.tx
|
|
if tx.networkPayload != nil:
|
|
for k in tx.networkPayload.commitments:
|
|
blobsBundle.commitments.add k
|
|
for p in tx.networkPayload.proofs:
|
|
blobsBundle.proofs.add p
|
|
for blob in tx.networkPayload.blobs:
|
|
blobsBundle.blobs.add blob
|
|
blk.header.transactionsRoot = calcTxRoot(blk.txs)
|
|
|
|
let com = xp.vmState.com
|
|
if com.isShanghaiOrLater(blk.header.timestamp):
|
|
blk.withdrawals = Opt.some(com.pos.withdrawals)
|
|
|
|
if not com.isCancunOrLater(blk.header.timestamp) and blobsBundle.commitments.len > 0:
|
|
return err("PooledTransaction contains blobs prior to Cancun")
|
|
let blobsBundleOpt =
|
|
if com.isCancunOrLater(blk.header.timestamp):
|
|
doAssert blobsBundle.commitments.len == blobsBundle.blobs.len
|
|
doAssert blobsBundle.proofs.len == blobsBundle.blobs.len
|
|
Opt.some blobsBundle
|
|
else:
|
|
Opt.none BlobsBundle
|
|
|
|
if someBaseFee:
|
|
# make sure baseFee always has something
|
|
blk.header.baseFeePerGas = Opt.some(blk.header.baseFeePerGas.get(0.u256))
|
|
|
|
let executionRequestsOpt =
|
|
if com.isPragueOrLater(blk.header.timestamp):
|
|
Opt.some(pst.executionRequests)
|
|
else:
|
|
Opt.none(seq[seq[byte]])
|
|
|
|
ok AssembledBlock(
|
|
blk: blk,
|
|
blobsBundle: blobsBundleOpt,
|
|
blockValue: pst.blockValue,
|
|
executionRequests: executionRequestsOpt)
|