mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-12 21:34:33 +00:00
TxPool refactoring: Simplify TxChainRef and remove gauges (#2506)
This is one of the txPool refactoring series to make it ready for integration with the new ForkedChainRef
This commit is contained in:
parent
57b36dc4ee
commit
6d03acec30
@ -598,7 +598,7 @@ func com*(xp: TxPoolRef): CommonRef =
|
||||
## Getter
|
||||
xp.chain.com
|
||||
|
||||
func baseFee*(xp: TxPoolRef): GasPrice =
|
||||
func baseFee*(xp: TxPoolRef): GasInt =
|
||||
## Getter, this parameter modifies/determines the expected gain when packing
|
||||
xp.chain.baseFee
|
||||
|
||||
@ -669,11 +669,6 @@ proc assembleBlock*(
|
||||
blk: blk,
|
||||
blobsBundle: blobsBundleOpt)
|
||||
|
||||
func gasCumulative*(xp: TxPoolRef): GasInt =
|
||||
## Getter, retrieves the gas that will be burned in the block after
|
||||
## retrieving it via `ethBlock`.
|
||||
xp.chain.gasUsed
|
||||
|
||||
func gasTotals*(xp: TxPoolRef): TxTabsGasTotals =
|
||||
## Getter, retrieves the current gas limit totals per bucket.
|
||||
xp.txDB.gasTotals
|
||||
@ -716,22 +711,11 @@ func nItems*(xp: TxPoolRef): TxTabsItemsCount =
|
||||
## some totals.
|
||||
xp.txDB.nItems
|
||||
|
||||
func profitability*(xp: TxPoolRef): GasPrice =
|
||||
## Getter, a calculation of the average *price* per gas to be rewarded after
|
||||
## packing the last block (see `ethBlock`). This *price* is only based on
|
||||
## execution transaction in the VM without *PoW* specific rewards. The net
|
||||
## profit (as opposed to the *PoW/PoA* specifc *reward*) can be calculated
|
||||
## as `gasCumulative * profitability`.
|
||||
if 0 < xp.chain.gasUsed:
|
||||
(xp.chain.profit div xp.chain.gasUsed.u256).truncate(uint64).GasPrice
|
||||
else:
|
||||
0.GasPrice
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public functions, setters
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
func `baseFee=`*(xp: TxPoolRef; val: GasPrice) {.raises: [KeyError].} =
|
||||
func `baseFee=`*(xp: TxPoolRef; val: GasInt) {.raises: [KeyError].} =
|
||||
## Setter, sets `baseFee` explicitely witout triggering a packer update.
|
||||
## Stil a database update might take place when updating account ranks.
|
||||
##
|
||||
@ -739,7 +723,6 @@ func `baseFee=`*(xp: TxPoolRef; val: GasPrice) {.raises: [KeyError].} =
|
||||
## update would be employed to do the job figuring out the proper value
|
||||
## for the `baseFee`.
|
||||
xp.txDB.baseFee = val
|
||||
xp.chain.baseFee = val
|
||||
|
||||
func `flags=`*(xp: TxPoolRef; val: set[TxPoolFlags]) =
|
||||
## Setter, strategy symbols for how to process items and buckets.
|
||||
|
@ -22,84 +22,101 @@ import
|
||||
../../utils/utils,
|
||||
../../evm/state,
|
||||
../../evm/types,
|
||||
../pow/header,
|
||||
../eip4844,
|
||||
../pow/difficulty,
|
||||
../executor,
|
||||
../casper,
|
||||
./tx_chain/[tx_basefee, tx_gaslimits],
|
||||
./tx_item
|
||||
eth/eip1559
|
||||
|
||||
type
|
||||
TxChainPackerEnv = tuple
|
||||
vmState: BaseVMState ## current tx/packer environment
|
||||
receipts: seq[Receipt] ## `vmState.receipts` after packing
|
||||
reward: UInt256 ## Miner balance difference after packing
|
||||
profit: UInt256 ## Net reward (w/o PoW specific block rewards)
|
||||
txRoot: Hash256 ## `rootHash` after packing
|
||||
stateRoot: Hash256 ## `stateRoot` after packing
|
||||
blobGasUsed:
|
||||
Opt[uint64] ## EIP-4844 block blobGasUsed
|
||||
excessBlobGas:
|
||||
Opt[uint64] ## EIP-4844 block excessBlobGas
|
||||
|
||||
TxChainRef* = ref object ##\
|
||||
## State cache of the transaction environment for creating a new\
|
||||
## block. This state is typically synchrionised with the canonical\
|
||||
## block chain head when updated.
|
||||
com: CommonRef ## Block chain config
|
||||
roAcc: ReadOnlyStateDB ## Accounts cache fixed on current sync header
|
||||
gasLimit*: GasInt
|
||||
txEnv: TxChainPackerEnv ## Assorted parameters, tx packer environment
|
||||
prepHeader: BlockHeader ## Prepared Header from Consensus Engine
|
||||
|
||||
vmState: BaseVMState ## current tx/packer environment
|
||||
receiptsRoot: Hash256
|
||||
logsBloom: BloomFilter
|
||||
txRoot: Hash256 ## `rootHash` after packing
|
||||
stateRoot: Hash256 ## `stateRoot` after packing
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Private functions
|
||||
# ------------------------------------------------------------------------------
|
||||
func prepareHeader(dh: TxChainRef; parent: BlockHeader, timestamp: EthTime)
|
||||
{.raises: [].} =
|
||||
proc baseFeeGet(com: CommonRef; parent: BlockHeader): Opt[UInt256] =
|
||||
## Calculates the `baseFee` of the head assuming this is the parent of a
|
||||
## new block header to generate.
|
||||
|
||||
# Note that the baseFee is calculated for the next header
|
||||
if not com.isLondonOrLater(parent.number+1):
|
||||
return Opt.none(UInt256)
|
||||
|
||||
# If the new block is the first EIP-1559 block, return initial base fee.
|
||||
if not com.isLondonOrLater(parent.number):
|
||||
return Opt.some(EIP1559_INITIAL_BASE_FEE)
|
||||
|
||||
Opt.some calcEip1599BaseFee(
|
||||
parent.gasLimit,
|
||||
parent.gasUsed,
|
||||
parent.baseFeePerGas.get(0.u256))
|
||||
|
||||
proc gasLimitsGet(com: CommonRef; parent: BlockHeader): GasInt =
|
||||
if com.isLondonOrLater(parent.number+1):
|
||||
var parentGasLimit = parent.gasLimit
|
||||
if not com.isLondonOrLater(parent.number):
|
||||
# Bump by 2x
|
||||
parentGasLimit = parent.gasLimit * EIP1559_ELASTICITY_MULTIPLIER
|
||||
calcGasLimit1559(parentGasLimit, desiredLimit = DEFAULT_GAS_LIMIT)
|
||||
else:
|
||||
computeGasLimit(
|
||||
parent.gasUsed,
|
||||
parent.gasLimit,
|
||||
gasFloor = DEFAULT_GAS_LIMIT,
|
||||
gasCeil = DEFAULT_GAS_LIMIT)
|
||||
|
||||
func prepareHeader(dh: TxChainRef) =
|
||||
dh.com.pos.prepare(dh.prepHeader)
|
||||
|
||||
func prepareForSeal(dh: TxChainRef; header: var BlockHeader) {.raises: [].} =
|
||||
func prepareForSeal(dh: TxChainRef; header: var BlockHeader) =
|
||||
dh.com.pos.prepareForSeal(header)
|
||||
|
||||
func getTimestamp(dh: TxChainRef, parent: BlockHeader): EthTime =
|
||||
func getTimestamp(dh: TxChainRef): EthTime =
|
||||
dh.com.pos.timestamp
|
||||
|
||||
func feeRecipient*(dh: TxChainRef): EthAddress
|
||||
|
||||
proc resetTxEnv(dh: TxChainRef; parent: BlockHeader; baseFeePerGas: Opt[UInt256])
|
||||
{.gcsafe,raises: [].} =
|
||||
dh.txEnv.reset
|
||||
func feeRecipient*(dh: TxChainRef): EthAddress =
|
||||
## Getter
|
||||
dh.com.pos.feeRecipient
|
||||
|
||||
proc resetTxEnv(dh: TxChainRef; parent: BlockHeader) =
|
||||
# do hardfork transition before
|
||||
# BaseVMState querying any hardfork/consensus from CommonRef
|
||||
|
||||
let timestamp = dh.getTimestamp(parent)
|
||||
let timestamp = dh.getTimestamp()
|
||||
dh.com.hardForkTransition(
|
||||
parent.blockHash, parent.number+1, Opt.some(timestamp))
|
||||
dh.prepareHeader(parent, timestamp)
|
||||
dh.prepareHeader()
|
||||
|
||||
# we don't consider PoS difficulty here
|
||||
# because that is handled in vmState
|
||||
let blockCtx = BlockContext(
|
||||
timestamp : dh.prepHeader.timestamp,
|
||||
gasLimit : dh.gasLimit,
|
||||
baseFeePerGas: baseFeePerGas,
|
||||
gasLimit : gasLimitsGet(dh.com, parent),
|
||||
baseFeePerGas: baseFeeGet(dh.com, parent),
|
||||
prevRandao : dh.prepHeader.prevRandao,
|
||||
difficulty : dh.prepHeader.difficulty,
|
||||
coinbase : dh.feeRecipient,
|
||||
excessBlobGas: calcExcessBlobGas(parent),
|
||||
)
|
||||
|
||||
dh.txEnv.vmState = BaseVMState.new(
|
||||
dh.vmState = BaseVMState.new(
|
||||
parent = parent,
|
||||
blockCtx = blockCtx,
|
||||
com = dh.com)
|
||||
|
||||
dh.txEnv.txRoot = EMPTY_ROOT_HASH
|
||||
dh.txEnv.stateRoot = dh.txEnv.vmState.parent.stateRoot
|
||||
dh.txEnv.blobGasUsed = Opt.none(uint64)
|
||||
dh.txEnv.excessBlobGas = Opt.none(uint64)
|
||||
dh.txRoot = EMPTY_ROOT_HASH
|
||||
dh.stateRoot = dh.vmState.parent.stateRoot
|
||||
|
||||
proc update(dh: TxChainRef; parent: BlockHeader)
|
||||
{.gcsafe,raises: [].} =
|
||||
@ -107,13 +124,10 @@ proc update(dh: TxChainRef; parent: BlockHeader)
|
||||
let
|
||||
db = dh.com.db
|
||||
acc = LedgerRef.init(db, parent.stateRoot)
|
||||
fee = baseFeeGet(dh.com, parent)
|
||||
|
||||
# Keep a separate accounts descriptor positioned at the sync point
|
||||
dh.roAcc = ReadOnlyStateDB(acc)
|
||||
|
||||
dh.gasLimit = dh.com.gasLimitsGet(parent)
|
||||
dh.resetTxEnv(parent, fee)
|
||||
dh.resetTxEnv(parent)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public functions, constructor
|
||||
@ -146,44 +160,61 @@ proc getNonce*(dh: TxChainRef; account: EthAddress): AccountNonce =
|
||||
## relative to what has been accumulated by the current packing procedure.
|
||||
dh.roAcc.getNonce(account)
|
||||
|
||||
func baseFee*(dh: TxChainRef): GasInt =
|
||||
## Getter, baseFee for the next bock header. This value is auto-generated
|
||||
## when a new insertion point is set via `head=`.
|
||||
if dh.vmState.blockCtx.baseFeePerGas.isSome:
|
||||
dh.vmState.blockCtx.baseFeePerGas.get.truncate(GasInt)
|
||||
else:
|
||||
0.GasInt
|
||||
|
||||
func excessBlobGas*(dh: TxChainRef): uint64 =
|
||||
## Getter, baseFee for the next bock header. This value is auto-generated
|
||||
## when a new insertion point is set via `head=`.
|
||||
dh.vmState.blockCtx.excessBlobGas
|
||||
|
||||
func blobGasUsed*(dh: TxChainRef): uint64 =
|
||||
dh.vmState.blobGasUsed
|
||||
|
||||
func gasLimit*(dh: TxChainRef): GasInt =
|
||||
dh.vmState.blockCtx.gasLimit
|
||||
|
||||
proc getHeader*(dh: TxChainRef): BlockHeader
|
||||
{.gcsafe,raises: [].} =
|
||||
## Generate a new header, a child of the cached `head`
|
||||
let gasUsed = if dh.txEnv.receipts.len == 0: 0.GasInt
|
||||
else: dh.txEnv.receipts[^1].cumulativeGasUsed
|
||||
|
||||
result = BlockHeader(
|
||||
parentHash: dh.txEnv.vmState.parent.blockHash,
|
||||
parentHash: dh.vmState.parent.blockHash,
|
||||
ommersHash: EMPTY_UNCLE_HASH,
|
||||
coinbase: dh.prepHeader.coinbase,
|
||||
stateRoot: dh.txEnv.stateRoot,
|
||||
txRoot: dh.txEnv.txRoot,
|
||||
receiptsRoot: dh.txEnv.receipts.calcReceiptsRoot,
|
||||
logsBloom: dh.txEnv.receipts.createBloom,
|
||||
stateRoot: dh.stateRoot,
|
||||
txRoot: dh.txRoot,
|
||||
receiptsRoot: dh.receiptsRoot,
|
||||
logsBloom: dh.logsBloom,
|
||||
difficulty: dh.prepHeader.difficulty,
|
||||
number: dh.txEnv.vmState.blockNumber,
|
||||
gasLimit: dh.txEnv.vmState.blockCtx.gasLimit,
|
||||
gasUsed: gasUsed,
|
||||
number: dh.vmState.blockNumber,
|
||||
gasLimit: dh.gasLimit,
|
||||
gasUsed: dh.vmState.cumulativeGasUsed,
|
||||
timestamp: dh.prepHeader.timestamp,
|
||||
# extraData: Blob # signing data
|
||||
# mixHash: Hash256 # mining hash for given difficulty
|
||||
# nonce: BlockNonce # mining free vaiable
|
||||
baseFeePerGas: dh.txEnv.vmState.blockCtx.baseFeePerGas,
|
||||
blobGasUsed: dh.txEnv.blobGasUsed,
|
||||
excessBlobGas: dh.txEnv.excessBlobGas)
|
||||
baseFeePerGas: dh.vmState.blockCtx.baseFeePerGas,
|
||||
)
|
||||
|
||||
if dh.com.isShanghaiOrLater(result.timestamp):
|
||||
result.withdrawalsRoot = Opt.some(calcWithdrawalsRoot(dh.com.pos.withdrawals))
|
||||
|
||||
if dh.com.isCancunOrLater(result.timestamp):
|
||||
result.parentBeaconBlockRoot = Opt.some(dh.com.pos.parentBeaconBlockRoot)
|
||||
result.blobGasUsed = Opt.some dh.blobGasUsed
|
||||
result.excessBlobGas = Opt.some dh.excessBlobGas
|
||||
|
||||
dh.prepareForSeal(result)
|
||||
|
||||
proc clearAccounts*(dh: TxChainRef)
|
||||
{.gcsafe,raises: [].} =
|
||||
## Reset transaction environment, e.g. before packing a new block
|
||||
dh.resetTxEnv(dh.txEnv.vmState.parent, dh.txEnv.vmState.blockCtx.baseFeePerGas)
|
||||
dh.resetTxEnv(dh.vmState.parent)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public functions, getters
|
||||
@ -195,104 +226,41 @@ func com*(dh: TxChainRef): CommonRef =
|
||||
|
||||
func head*(dh: TxChainRef): BlockHeader =
|
||||
## Getter
|
||||
dh.txEnv.vmState.parent
|
||||
|
||||
func feeRecipient*(dh: TxChainRef): EthAddress =
|
||||
## Getter
|
||||
dh.com.pos.feeRecipient
|
||||
|
||||
func baseFee*(dh: TxChainRef): GasPrice =
|
||||
## Getter, baseFee for the next bock header. This value is auto-generated
|
||||
## when a new insertion point is set via `head=`.
|
||||
if dh.txEnv.vmState.blockCtx.baseFeePerGas.isSome:
|
||||
dh.txEnv.vmState.blockCtx.baseFeePerGas.get.truncate(uint64).GasPrice
|
||||
else:
|
||||
0.GasPrice
|
||||
|
||||
func excessBlobGas*(dh: TxChainRef): uint64 =
|
||||
## Getter, baseFee for the next bock header. This value is auto-generated
|
||||
## when a new insertion point is set via `head=`.
|
||||
dh.txEnv.excessBlobGas.get(0'u64)
|
||||
dh.vmState.parent
|
||||
|
||||
func nextFork*(dh: TxChainRef): EVMFork =
|
||||
## Getter, fork of next block
|
||||
dh.txEnv.vmState.fork
|
||||
|
||||
func gasUsed*(dh: TxChainRef): GasInt =
|
||||
## Getter, accumulated gas burned for collected blocks
|
||||
if 0 < dh.txEnv.receipts.len:
|
||||
return dh.txEnv.receipts[^1].cumulativeGasUsed
|
||||
|
||||
func profit*(dh: TxChainRef): UInt256 =
|
||||
## Getter
|
||||
dh.txEnv.profit
|
||||
|
||||
func receipts*(dh: TxChainRef): seq[Receipt] =
|
||||
## Getter, receipts for collected blocks
|
||||
dh.txEnv.receipts
|
||||
|
||||
func reward*(dh: TxChainRef): UInt256 =
|
||||
## Getter, reward for collected blocks
|
||||
dh.txEnv.reward
|
||||
|
||||
func stateRoot*(dh: TxChainRef): Hash256 =
|
||||
## Getter, accounting DB state root hash for the next block header
|
||||
dh.txEnv.stateRoot
|
||||
|
||||
func txRoot*(dh: TxChainRef): Hash256 =
|
||||
## Getter, transaction state root hash for the next block header
|
||||
dh.txEnv.txRoot
|
||||
dh.vmState.fork
|
||||
|
||||
func vmState*(dh: TxChainRef): BaseVMState =
|
||||
## Getter, `BaseVmState` descriptor based on the current insertion point.
|
||||
dh.txEnv.vmState
|
||||
dh.vmState
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public functions, setters
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
func `baseFee=`*(dh: TxChainRef; val: GasPrice) =
|
||||
## Setter, temorarily overwrites parameter until next `head=` update. This
|
||||
## function would be called in exceptional cases only as this parameter is
|
||||
## determined by the `head=` update.
|
||||
if 0 < val or dh.com.isLondonOrLater(dh.txEnv.vmState.blockNumber):
|
||||
dh.txEnv.vmState.blockCtx.baseFeePerGas = Opt.some(val.uint64.u256)
|
||||
else:
|
||||
dh.txEnv.vmState.blockCtx.baseFeePerGas = Opt.none UInt256
|
||||
|
||||
proc `head=`*(dh: TxChainRef; val: BlockHeader)
|
||||
{.gcsafe,raises: [].} =
|
||||
## Setter, updates descriptor. This setter re-positions the `vmState` and
|
||||
## account caches to a new insertion point on the block chain database.
|
||||
dh.update(val)
|
||||
|
||||
func `profit=`*(dh: TxChainRef; val: UInt256) =
|
||||
## Setter
|
||||
dh.txEnv.profit = val
|
||||
|
||||
func `receipts=`*(dh: TxChainRef; val: seq[Receipt]) =
|
||||
func `receiptsRoot=`*(dh: TxChainRef; val: Hash256) =
|
||||
## Setter, implies `gasUsed`
|
||||
dh.txEnv.receipts = val
|
||||
dh.receiptsRoot = val
|
||||
|
||||
func `reward=`*(dh: TxChainRef; val: UInt256) =
|
||||
## Getter
|
||||
dh.txEnv.reward = val
|
||||
func `logsBloom=`*(dh: TxChainRef; val: BloomFilter) =
|
||||
## Setter, implies `gasUsed`
|
||||
dh.logsBloom = val
|
||||
|
||||
func `stateRoot=`*(dh: TxChainRef; val: Hash256) =
|
||||
## Setter
|
||||
dh.txEnv.stateRoot = val
|
||||
dh.stateRoot = val
|
||||
|
||||
func `txRoot=`*(dh: TxChainRef; val: Hash256) =
|
||||
## Setter
|
||||
dh.txEnv.txRoot = val
|
||||
|
||||
func `excessBlobGas=`*(dh: TxChainRef; val: Opt[uint64]) =
|
||||
## Setter
|
||||
dh.txEnv.excessBlobGas = val
|
||||
|
||||
func `blobGasUsed=`*(dh: TxChainRef; val: Opt[uint64]) =
|
||||
## Setter
|
||||
dh.txEnv.blobGasUsed = val
|
||||
dh.txRoot = val
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# End
|
||||
|
@ -1,46 +0,0 @@
|
||||
# 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.
|
||||
|
||||
## Block Chain Helper: Calculate Base Fee
|
||||
## =======================================
|
||||
##
|
||||
|
||||
import
|
||||
../../../common/common,
|
||||
../../../constants,
|
||||
eth/eip1559
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public functions
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc baseFeeGet*(com: CommonRef;
|
||||
parent: BlockHeader): Opt[UInt256] =
|
||||
## Calculates the `baseFee` of the head assuming this is the parent of a
|
||||
## new block header to generate.
|
||||
|
||||
# Note that the baseFee is calculated for the next header
|
||||
if not com.isLondonOrLater(parent.number+1):
|
||||
return Opt.none(UInt256)
|
||||
|
||||
# If the new block is the first EIP-1559 block, return initial base fee.
|
||||
if not com.isLondonOrLater(parent.number):
|
||||
return Opt.some(EIP1559_INITIAL_BASE_FEE)
|
||||
|
||||
Opt.some calcEip1599BaseFee(
|
||||
parent.gasLimit,
|
||||
parent.gasUsed,
|
||||
parent.baseFeePerGas.get(0.u256))
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# End
|
||||
# ------------------------------------------------------------------------------
|
@ -1,45 +0,0 @@
|
||||
# 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.
|
||||
|
||||
## Block Chain Helper: Gas Limits
|
||||
## ==============================
|
||||
##
|
||||
|
||||
import
|
||||
../../../common/common,
|
||||
../../../constants,
|
||||
../../pow/header,
|
||||
eth/[eip1559]
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public functions
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc gasLimitsGet*(com: CommonRef;
|
||||
parent: BlockHeader): GasInt =
|
||||
|
||||
if com.isLondonOrLater(parent.number+1):
|
||||
var parentGasLimit = parent.gasLimit
|
||||
if not com.isLondonOrLater(parent.number):
|
||||
# Bump by 2x
|
||||
parentGasLimit = parent.gasLimit * EIP1559_ELASTICITY_MULTIPLIER
|
||||
calcGasLimit1559(parentGasLimit, desiredLimit = DEFAULT_GAS_LIMIT)
|
||||
else:
|
||||
computeGasLimit(
|
||||
parent.gasUsed,
|
||||
parent.gasLimit,
|
||||
gasFloor = DEFAULT_GAS_LIMIT,
|
||||
gasCeil = DEFAULT_GAS_LIMIT)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# End
|
||||
# ------------------------------------------------------------------------------
|
@ -1,142 +0,0 @@
|
||||
# Nimbus
|
||||
# Copyright (c) 2018 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.
|
||||
|
||||
## Transaction Pool Meters
|
||||
## =======================
|
||||
##
|
||||
|
||||
import
|
||||
metrics
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
const
|
||||
# Provide some fall-back counters available for unit tests
|
||||
FallBackMetrics4Debugging = not defined(metrics)
|
||||
|
||||
when FallBackMetrics4Debugging:
|
||||
{.warning: "Debugging fall back mode for some gauges".}
|
||||
type
|
||||
DummyCounter* = ref object
|
||||
value: float64
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Private settings
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# Metrics for the pending pool
|
||||
|
||||
# core/tx_pool.go(97): pendingDiscardMeter = metrics.NewRegisteredMeter(..
|
||||
declareGauge pendingDiscard, "n/a"
|
||||
declareGauge pendingReplace, "n/a"
|
||||
declareGauge pendingRateLimit, "n/a" # Dropped due to rate limiting
|
||||
declareGauge pendingNofunds, "n/a" # Dropped due to out-of-funds
|
||||
|
||||
|
||||
# Metrics for the queued pool
|
||||
|
||||
# core/tx_pool.go(103): queuedDiscardMeter = metrics.NewRegisteredMeter(..
|
||||
declareGauge queuedDiscard, "n/a"
|
||||
declareGauge queuedReplace, "n/a"
|
||||
declareGauge queuedRateLimit, "n/a" # Dropped due to rate limiting
|
||||
declareGauge queuedNofunds, "n/a" # Dropped due to out-of-funds
|
||||
|
||||
declareGauge evictionGauge,
|
||||
"A transaction has been on the system for too long so it was removed"
|
||||
|
||||
declareGauge impliedEvictionGauge,
|
||||
"Implied disposal for greater nonces (same sender) when base tx was removed"
|
||||
|
||||
# General tx metrics
|
||||
|
||||
# core/tx_pool.go(110): knownTxMeter = metrics.NewRegisteredMeter(..
|
||||
declareGauge knownTransactions, "n/a"
|
||||
declareGauge validTransactions, "n/a"
|
||||
declareGauge invalidTransactions, "n/a"
|
||||
declareGauge underpricedTransactions, "n/a"
|
||||
declareGauge overflowedTransactions, "n/a"
|
||||
|
||||
# core/tx_pool.go(117): throttleTxMeter = metrics.NewRegisteredMeter(..
|
||||
declareGauge throttleTransactions,
|
||||
"Rejected transactions due to too-many-changes between txpool reorgs"
|
||||
|
||||
# core/tx_pool.go(119): reorgDurationTimer = metrics.NewRegisteredTimer(..
|
||||
declareGauge reorgDurationTimer, "Measures how long time a txpool reorg takes"
|
||||
|
||||
# core/tx_pool.go(122): dropBetweenReorgHistogram = metrics..
|
||||
declareGauge dropBetweenReorgHistogram,
|
||||
"Number of expected drops between two reorg runs. It is expected that "&
|
||||
"this number is pretty low, since txpool reorgs happen very frequently"
|
||||
|
||||
# core/tx_pool.go(124): pendingGauge = metrics.NewRegisteredGauge(..
|
||||
declareGauge pendingGauge, "n/a"
|
||||
declareGauge queuedGauge, "n/a"
|
||||
declareGauge localGauge, "n/a"
|
||||
declareGauge slotsGauge, "n/a"
|
||||
|
||||
# core/tx_pool.go(129): reheapTimer = metrics.NewRegisteredTimer(..
|
||||
# declareGauge reheapTimer, "n/a" -- notused
|
||||
|
||||
# ----------------------
|
||||
|
||||
declareGauge unspecifiedError,
|
||||
"Some error occured but was not specified in any way. This counter should "&
|
||||
"stay zero."
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Exports
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
when FallBackMetrics4Debugging:
|
||||
let
|
||||
evictionMeter* = DummyCounter()
|
||||
impliedEvictionMeter* = DummyCounter()
|
||||
|
||||
proc inc(w: DummyCounter; val: int64|float64 = 1,) =
|
||||
w.value = w.value + val.float64
|
||||
else:
|
||||
let
|
||||
evictionMeter* = evictionGauge
|
||||
impliedEvictionMeter* = impliedEvictionGauge
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Global functions -- deprecated
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc pendingDiscardMeter*(n = 1i64) = pendingDiscard.inc(n)
|
||||
proc pendingReplaceMeter*(n = 1i64) = pendingReplace.inc(n)
|
||||
proc pendingRateLimitMeter*(n = 1i64) = pendingRateLimit.inc(n)
|
||||
proc pendingNofundsMeter*(n = 1i64) = pendingNofunds.inc(n)
|
||||
|
||||
proc queuedDiscardMeter*(n = 1i64) = queuedDiscard.inc(n)
|
||||
proc queuedReplaceMeter*(n = 1i64) = queuedReplace.inc(n)
|
||||
proc queuedRateLimitMeter*(n = 1i64) = queuedRateLimit.inc(n)
|
||||
proc queuedNofundsMeter*(n = 1i64) = queuedNofunds.inc(n)
|
||||
|
||||
proc knownTxMeter*(n = 1i64) = knownTransactions.inc(n)
|
||||
proc invalidTxMeter*(n = 1i64) = invalidTransactions.inc(n)
|
||||
proc validTxMeter*(n = 1i64) = validTransactions.inc(n)
|
||||
proc underpricedTxMeter*(n = 1i64) = underpricedTransactions.inc(n)
|
||||
proc overflowedTxMeter*(n = 1i64) = overflowedTransactions.inc(n)
|
||||
proc throttleTxMeter*(n = 1i64) = throttleTransactions.inc(n)
|
||||
|
||||
proc unspecifiedErrorMeter*(n = 1i64) = unspecifiedError.inc(n)
|
||||
|
||||
proc reorgDurationTimerMeter*(n = 1i64) = reorgDurationTimer.inc(n)
|
||||
proc dropBetweenReorgHistogramMeter*(n = 1i64) =
|
||||
dropBetweenReorgHistogram.inc(n)
|
||||
proc pendingGaugeMeter*(n = 1i64) = pendingGauge.inc(n)
|
||||
proc queuedGaugeMeter*(n = 1i64) = queuedGauge.inc(n)
|
||||
proc localGaugeMeter*(n = 1i64) = localGauge.inc(n)
|
||||
proc slotsGaugeMeter*(n = 1i64) = slotsGauge.inc(n)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# End
|
||||
# ------------------------------------------------------------------------------
|
@ -161,18 +161,18 @@ proc cost*(tx: Transaction): UInt256 =
|
||||
|
||||
# core/types/transaction.go(332): .. *Transaction) EffectiveGasTip(baseFee ..
|
||||
# core/types/transaction.go(346): .. EffectiveGasTipValue(baseFee ..
|
||||
proc effectiveGasTip*(tx: Transaction; baseFee: GasPrice): GasPriceEx =
|
||||
proc effectiveGasTip*(tx: Transaction; baseFee: GasInt): GasPriceEx =
|
||||
## The effective miner gas tip for the globally argument `baseFee`. The
|
||||
## result (which is a price per gas) might well be negative.
|
||||
if tx.txType < TxEip1559:
|
||||
(tx.gasPrice - baseFee.GasInt).GasPriceEx
|
||||
(tx.gasPrice - baseFee).GasPriceEx
|
||||
else:
|
||||
# London, EIP1559
|
||||
min(tx.maxPriorityFeePerGas, tx.maxFeePerGas - baseFee.GasInt).GasPriceEx
|
||||
min(tx.maxPriorityFeePerGas, tx.maxFeePerGas - baseFee).GasPriceEx
|
||||
|
||||
proc effectiveGasTip*(tx: Transaction; baseFee: UInt256): GasPriceEx =
|
||||
## Variant of `effectiveGasTip()`
|
||||
tx.effectiveGasTip(baseFee.truncate(uint64).GasPrice)
|
||||
tx.effectiveGasTip(baseFee.truncate(GasInt))
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public functions, item getters
|
||||
|
@ -250,7 +250,7 @@ proc reject*(xp: TxTabsRef; tx: PooledTransaction;
|
||||
# Public getters
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc baseFee*(xp: TxTabsRef): GasPrice =
|
||||
proc baseFee*(xp: TxTabsRef): GasInt =
|
||||
## Getter
|
||||
xp.bySender.baseFee
|
||||
|
||||
@ -270,7 +270,7 @@ proc remote*(lc: TxTabsLocality): seq[EthAddress] =
|
||||
# Public functions, setters
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc `baseFee=`*(xp: TxTabsRef; val: GasPrice)
|
||||
proc `baseFee=`*(xp: TxTabsRef; val: GasInt)
|
||||
{.gcsafe,raises: [KeyError].} =
|
||||
## Setter, update may cause database re-org
|
||||
if xp.bySender.baseFee != val:
|
||||
|
@ -41,7 +41,7 @@ type
|
||||
## Per address table This is table provided as a keyed queue so deletion\
|
||||
## while traversing is supported and predictable.
|
||||
size: int ## Total number of items
|
||||
baseFee: GasPrice ## For aggregating `effectiveGasTip` => `gasTipSum`
|
||||
baseFee: GasInt ## For aggregating `effectiveGasTip` => `gasTipSum`
|
||||
addrList: KeyedQueue[EthAddress,TxSenderSchedRef]
|
||||
|
||||
TxSenderSchedule* = enum ##\
|
||||
@ -120,11 +120,11 @@ proc getRank(schedData: TxSenderSchedRef): int64 =
|
||||
|
||||
profit.int64
|
||||
|
||||
proc maxProfit(item: TxItemRef; baseFee: GasPrice): float64 =
|
||||
proc maxProfit(item: TxItemRef; baseFee: GasInt): float64 =
|
||||
## Profit calculator
|
||||
item.tx.gasLimit.float64 * item.tx.effectiveGasTip(baseFee).float64 + item.tx.getTotalBlobGas.float64
|
||||
|
||||
proc recalcProfit(nonceData: TxSenderNonceRef; baseFee: GasPrice) =
|
||||
proc recalcProfit(nonceData: TxSenderNonceRef; baseFee: GasInt) =
|
||||
## Re-calculate profit value depending on `baseFee`
|
||||
nonceData.profit = 0.0
|
||||
var rc = nonceData.nonceList.ge(AccountNonce.low)
|
||||
@ -367,7 +367,7 @@ proc verify*(gt: var TxSenderTab): Result[void,TxInfo]
|
||||
# Public getters
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc baseFee*(gt: var TxSenderTab): GasPrice =
|
||||
proc baseFee*(gt: var TxSenderTab): GasInt =
|
||||
## Getter
|
||||
gt.baseFee
|
||||
|
||||
@ -375,7 +375,7 @@ proc baseFee*(gt: var TxSenderTab): GasPrice =
|
||||
# Public functions, setters
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc `baseFee=`*(gt: var TxSenderTab; val: GasPrice) =
|
||||
proc `baseFee=`*(gt: var TxSenderTab; val: GasInt) =
|
||||
## Setter. When invoked, there is *always* a re-calculation of the profit
|
||||
## values stored with the sender address.
|
||||
gt.baseFee = val
|
||||
|
@ -15,7 +15,6 @@
|
||||
import
|
||||
std/[tables],
|
||||
../tx_desc,
|
||||
../tx_gauge,
|
||||
../tx_info,
|
||||
../tx_item,
|
||||
../tx_tabs,
|
||||
@ -137,7 +136,6 @@ proc addTx*(xp: TxPoolRef; item: TxItemRef): bool
|
||||
block:
|
||||
let rc = xp.txDB.insert(item)
|
||||
if rc.isOk:
|
||||
validTxMeter(1)
|
||||
return item.status == txItemStaged
|
||||
vetted = rc.error
|
||||
|
||||
@ -145,23 +143,12 @@ proc addTx*(xp: TxPoolRef; item: TxItemRef): bool
|
||||
if vetted == txInfoErrSenderNonceIndex:
|
||||
let rc = xp.supersede(item)
|
||||
if rc.isOk:
|
||||
validTxMeter(1)
|
||||
return
|
||||
vetted = rc.error
|
||||
|
||||
# Error processing => store in waste basket
|
||||
xp.txDB.reject(item, vetted)
|
||||
|
||||
# update gauge
|
||||
case vetted:
|
||||
of txInfoErrAlreadyKnown:
|
||||
knownTxMeter(1)
|
||||
of txInfoErrInvalidSender:
|
||||
invalidTxMeter(1)
|
||||
else:
|
||||
unspecifiedErrorMeter(1)
|
||||
|
||||
|
||||
# core/tx_pool.go(848): func (pool *TxPool) AddLocals(txs []..
|
||||
# core/tx_pool.go(854): func (pool *TxPool) AddLocals(txs []..
|
||||
# core/tx_pool.go(864): func (pool *TxPool) AddRemotes(txs []..
|
||||
@ -195,7 +182,6 @@ proc addTxs*(xp: TxPoolRef;
|
||||
# move item to waste basket
|
||||
reason = txInfoErrInvalidBlob
|
||||
xp.txDB.reject(tx, reason, txItemPending, res.error)
|
||||
invalidTxMeter(1)
|
||||
continue
|
||||
|
||||
# Create tx item wrapper, preferably recovered from waste basket
|
||||
@ -215,15 +201,6 @@ proc addTxs*(xp: TxPoolRef;
|
||||
# move item to waste basket
|
||||
xp.txDB.reject(tx, reason, txItemPending, info)
|
||||
|
||||
# update gauge
|
||||
case reason:
|
||||
of txInfoErrAlreadyKnown:
|
||||
knownTxMeter(1)
|
||||
of txInfoErrInvalidSender:
|
||||
invalidTxMeter(1)
|
||||
else:
|
||||
unspecifiedErrorMeter(1)
|
||||
|
||||
# Add sorted transaction items
|
||||
for itemList in accTab.mvalues:
|
||||
var
|
||||
|
@ -107,7 +107,7 @@ proc txFeesCovered(xp: TxPoolRef; item: TxItemRef): bool =
|
||||
## Ensure that the user was willing to at least pay the base fee
|
||||
## And to at least pay the current data gasprice
|
||||
if item.tx.txType >= TxEip1559:
|
||||
if item.tx.maxFeePerGas.GasPriceEx < xp.chain.baseFee:
|
||||
if item.tx.maxFeePerGas < xp.chain.baseFee:
|
||||
debug "invalid tx: maxFee is smaller than baseFee",
|
||||
maxFee = item.tx.maxFeePerGas,
|
||||
baseFee = xp.chain.baseFee
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Nimbus
|
||||
# Copyright (c) 2018 Status Research & Development GmbH
|
||||
# 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)
|
||||
@ -15,7 +15,6 @@
|
||||
import
|
||||
std/[times],
|
||||
../tx_desc,
|
||||
../tx_gauge,
|
||||
../tx_info,
|
||||
../tx_item,
|
||||
../tx_tabs,
|
||||
@ -50,7 +49,6 @@ proc deleteOtherNonces(xp: TxPoolRef; item: TxItemRef; newerThan: Time): bool
|
||||
# only delete non-expired items
|
||||
if newerThan < other.timeStamp:
|
||||
discard xp.txDB.dispose(other, txInfoErrTxExpiredImplied)
|
||||
impliedEvictionMeter.inc
|
||||
result = true
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
@ -82,7 +80,6 @@ proc disposeExpiredItems*(xp: TxPoolRef) {.gcsafe,raises: [KeyError].} =
|
||||
|
||||
# Note: it is ok to delete the current item
|
||||
discard xp.txDB.dispose(item, txInfoErrTxExpired)
|
||||
evictionMeter.inc
|
||||
|
||||
# Also delete all non-expired items with higher nonces.
|
||||
if xp.deleteOtherNonces(item, deadLine):
|
||||
|
@ -15,14 +15,13 @@
|
||||
{.push raises: [].}
|
||||
|
||||
import
|
||||
chronicles,
|
||||
eth/[keys, rlp],
|
||||
stew/sorted_set,
|
||||
../../../db/[ledger, core_db],
|
||||
../../../common/common,
|
||||
../../../utils/utils,
|
||||
../../../constants,
|
||||
"../.."/[dao, executor, validate, casper],
|
||||
"../.."/[executor, validate, casper],
|
||||
../../../transaction/call_evm,
|
||||
../../../transaction,
|
||||
../../../evm/state,
|
||||
@ -31,14 +30,10 @@ import
|
||||
"."/[tx_bucket, tx_classify]
|
||||
|
||||
type
|
||||
TxPackerError* = object of CatchableError
|
||||
## Catch and relay exception error
|
||||
|
||||
TxPackerStateRef = ref object
|
||||
xp: TxPoolRef
|
||||
tr: CoreDbMptRef
|
||||
cleanState: bool
|
||||
balance: UInt256
|
||||
numBlobPerBlock: int
|
||||
|
||||
const
|
||||
@ -46,25 +41,10 @@ const
|
||||
## Number of slots to extend the `receipts[]` at the same time.
|
||||
20
|
||||
|
||||
logScope:
|
||||
topics = "tx-pool packer"
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Private helpers
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
when false:
|
||||
template safeExecutor(info: string; code: untyped) =
|
||||
try:
|
||||
code
|
||||
except CatchableError as e:
|
||||
raise (ref CatchableError)(msg: e.msg)
|
||||
except Defect as e:
|
||||
raise (ref Defect)(msg: e.msg)
|
||||
except:
|
||||
let e = getCurrentException()
|
||||
raise newException(TxPackerError, info & "(): " & $e.name & " -- " & e.msg)
|
||||
|
||||
proc persist(pst: TxPackerStateRef)
|
||||
{.gcsafe,raises: [].} =
|
||||
## Smart wrapper
|
||||
@ -130,7 +110,7 @@ proc runTxCommit(pst: TxPackerStateRef; item: TxItemRef; gasBurned: GasInt)
|
||||
vmState.receipts[inx] = vmState.makeReceipt(item.tx.txType)
|
||||
|
||||
# Update txRoot
|
||||
pst.tr.merge(rlp.encode(inx), rlp.encode(item.tx)).isOkOr:
|
||||
pst.tr.merge(rlp.encode(inx.uint64), rlp.encode(item.tx)).isOkOr:
|
||||
raiseAssert "runTxCommit(): merge failed, " & $$error
|
||||
|
||||
# Add the item to the `packed` bucket. This implicitely increases the
|
||||
@ -150,11 +130,6 @@ proc vmExecInit(xp: TxPoolRef): Result[TxPackerStateRef, string]
|
||||
# reset blockValue before adding any tx
|
||||
xp.blockValue = 0.u256
|
||||
|
||||
if xp.chain.com.daoForkSupport and
|
||||
xp.chain.com.daoForkBlock.get == xp.chain.head.number + 1:
|
||||
xp.chain.vmState.mutateStateDB:
|
||||
db.applyDAOHardFork()
|
||||
|
||||
# EIP-4788
|
||||
if xp.chain.nextFork >= FkCancun:
|
||||
let beaconRoot = xp.chain.com.pos.parentBeaconBlockRoot
|
||||
@ -164,7 +139,6 @@ proc vmExecInit(xp: TxPoolRef): Result[TxPackerStateRef, string]
|
||||
let packer = TxPackerStateRef( # return value
|
||||
xp: xp,
|
||||
tr: AristoDbMemory.newCoreDbRef().ctx.getGeneric(clearData=true),
|
||||
balance: xp.chain.vmState.readOnlyStateDB.getBalance(xp.chain.feeRecipient),
|
||||
numBlobPerBlock: 0,
|
||||
)
|
||||
ok(packer)
|
||||
@ -246,23 +220,12 @@ proc vmExecCommit(pst: TxPackerStateRef)
|
||||
let nItems = xp.txDB.byStatus.eq(txItemPacked).nItems
|
||||
vmState.receipts.setLen(nItems)
|
||||
|
||||
xp.chain.receipts = vmState.receipts
|
||||
xp.chain.receiptsRoot = vmState.receipts.calcReceiptsRoot
|
||||
xp.chain.logsBloom = vmState.receipts.createBloom
|
||||
xp.chain.txRoot = pst.tr.state(updateOk=true).valueOr:
|
||||
raiseAssert "vmExecCommit(): state() failed " & $$error
|
||||
xp.chain.stateRoot = vmState.stateDB.rootHash
|
||||
|
||||
if xp.chain.nextFork >= FkCancun:
|
||||
# EIP-4844
|
||||
xp.chain.excessBlobGas = Opt.some(vmState.blockCtx.excessBlobGas)
|
||||
xp.chain.blobGasUsed = Opt.some(vmState.blobGasUsed)
|
||||
|
||||
proc balanceDelta: UInt256 =
|
||||
let postBalance = vmState.readOnlyStateDB.getBalance(xp.chain.feeRecipient)
|
||||
if pst.balance < postBalance:
|
||||
return postBalance - pst.balance
|
||||
|
||||
xp.chain.profit = balanceDelta()
|
||||
xp.chain.reward = balanceDelta()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public functions
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
import
|
||||
std/[os, strformat, sequtils, strutils, times],
|
||||
../../nimbus/core/tx_pool/[tx_chain, tx_desc, tx_gauge, tx_item, tx_tabs],
|
||||
../../nimbus/core/tx_pool/[tx_chain, tx_desc, tx_item, tx_tabs],
|
||||
../../nimbus/core/tx_pool/tx_tasks/[tx_packer, tx_recover],
|
||||
../replay/[pp, undump_blocks_gz],
|
||||
chronicles,
|
||||
@ -25,14 +25,10 @@ export
|
||||
tx_chain.clearAccounts,
|
||||
tx_chain.com,
|
||||
tx_chain.nextFork,
|
||||
tx_chain.profit,
|
||||
tx_chain.receipts,
|
||||
tx_chain.reward,
|
||||
tx_chain.vmState,
|
||||
tx_desc.chain,
|
||||
tx_desc.txDB,
|
||||
tx_desc.verify,
|
||||
tx_gauge,
|
||||
tx_packer.packerVmExec,
|
||||
tx_recover.recoverItem,
|
||||
tx_tabs.TxTabsRef,
|
||||
|
Loading…
x
Reference in New Issue
Block a user