From 8d1e21bbaeaca1a5e652b25c419f27db3e36770e Mon Sep 17 00:00:00 2001 From: andri lim Date: Wed, 17 Jul 2024 20:48:35 +0700 Subject: [PATCH] Simplify txPool gasLimit calculator (#2498) Our need is only a baseline tx pool gasLimit calculator. If need we can expand it in the future. But for now, a simple but understandable tx pool is more important. --- nimbus/core/tx_pool.nim | 39 -------- nimbus/core/tx_pool/tx_chain.nim | 58 +---------- nimbus/core/tx_pool/tx_chain/tx_gaslimits.nim | 98 ++----------------- nimbus/core/tx_pool/tx_tasks/tx_classify.nim | 16 +-- nimbus/core/tx_pool/tx_tasks/tx_packer.nim | 2 - tests/test_txpool/helpers.nim | 8 -- 6 files changed, 13 insertions(+), 208 deletions(-) diff --git a/nimbus/core/tx_pool.nim b/nimbus/core/tx_pool.nim index 05b2f20fc..7b4fd3f86 100644 --- a/nimbus/core/tx_pool.nim +++ b/nimbus/core/tx_pool.nim @@ -678,11 +678,6 @@ func gasTotals*(xp: TxPoolRef): TxTabsGasTotals = ## Getter, retrieves the current gas limit totals per bucket. xp.txDB.gasTotals -func lwmTrgPercent*(xp: TxPoolRef): int = - ## Getter, `trgGasLimit` percentage for `lwmGasLimit` which is - ## `max(minGasLimit, trgGasLimit * lwmTrgPercent / 100)` - xp.chain.lhwm.lwmTrg - func flags*(xp: TxPoolRef): set[TxPoolFlags] = ## Getter, retrieves strategy symbols for how to process items and buckets. xp.pFlags @@ -693,15 +688,6 @@ func head*(xp: TxPoolRef): BlockHeader = ## middle of a mining update.) xp.chain.head -func hwmMaxPercent*(xp: TxPoolRef): int = - ## Getter, `maxGasLimit` percentage for `hwmGasLimit` which is - ## `max(trgGasLimit, maxGasLimit * hwmMaxPercent / 100)` - xp.chain.lhwm.hwmMax - -func maxGasLimit*(xp: TxPoolRef): GasInt = - ## Getter, hard size limit when packing blocks (see also `trgGasLimit`.) - xp.chain.limits.maxLimit - # core/tx_pool.go(435): func (pool *TxPool) GasPrice() *big.Int { func minFeePrice*(xp: TxPoolRef): GasPrice = ## Getter, retrieves minimum for the current gas fee enforced by the @@ -741,11 +727,6 @@ func profitability*(xp: TxPoolRef): GasPrice = else: 0.GasPrice -func trgGasLimit*(xp: TxPoolRef): GasInt = - ## Getter, soft size limit when packing blocks (might be extended to - ## `maxGasLimit`) - xp.chain.limits.trgLimit - # ------------------------------------------------------------------------------ # Public functions, setters # ------------------------------------------------------------------------------ @@ -760,30 +741,10 @@ func `baseFee=`*(xp: TxPoolRef; val: GasPrice) {.raises: [KeyError].} = xp.txDB.baseFee = val xp.chain.baseFee = val -func `lwmTrgPercent=`*(xp: TxPoolRef; val: int) = - ## Setter, `val` arguments outside `0..100` are ignored - if 0 <= val and val <= 100: - xp.chain.lhwm = ( - lwmTrg: val, - hwmMax: xp.chain.lhwm.hwmMax, - gasFloor: xp.chain.lhwm.gasFloor, - gasCeil: xp.chain.lhwm.gasCeil - ) - func `flags=`*(xp: TxPoolRef; val: set[TxPoolFlags]) = ## Setter, strategy symbols for how to process items and buckets. xp.pFlags = val -func `hwmMaxPercent=`*(xp: TxPoolRef; val: int) = - ## Setter, `val` arguments outside `0..100` are ignored - if 0 <= val and val <= 100: - xp.chain.lhwm = ( - lwmTrg: xp.chain.lhwm.lwmTrg, - hwmMax: val, - gasFloor: xp.chain.lhwm.gasFloor, - gasCeil: xp.chain.lhwm.gasCeil - ) - func `maxRejects=`*(xp: TxPoolRef; val: int) = ## Setter, the size of the waste basket. This setting becomes effective with ## the next move of an item into the waste basket. diff --git a/nimbus/core/tx_pool/tx_chain.nim b/nimbus/core/tx_pool/tx_chain.nim index 2e8de49f9..09990930c 100644 --- a/nimbus/core/tx_pool/tx_chain.nim +++ b/nimbus/core/tx_pool/tx_chain.nim @@ -29,21 +29,6 @@ import ./tx_chain/[tx_basefee, tx_gaslimits], ./tx_item -export - TxChainGasLimits, - TxChainGasLimitsPc - -const - TRG_THRESHOLD_PER_CENT = ##\ - ## VM executor may stop if this per centage of `trgLimit` has - ## been reached. - 90 - - MAX_THRESHOLD_PER_CENT = ##\ - ## VM executor may stop if this per centage of `maxLimit` has - ## been reached. - 90 - type TxChainPackerEnv = tuple vmState: BaseVMState ## current tx/packer environment @@ -62,11 +47,8 @@ type ## block. This state is typically synchrionised with the canonical\ ## block chain head when updated. com: CommonRef ## Block chain config - lhwm: TxChainGasLimitsPc ## Hwm/lwm gas limit percentage - - maxMode: bool ## target or maximal limit for next block header roAcc: ReadOnlyStateDB ## Accounts cache fixed on current sync header - limits: TxChainGasLimits ## Gas limits for packer and next header + gasLimit*: GasInt txEnv: TxChainPackerEnv ## Assorted parameters, tx packer environment prepHeader: BlockHeader ## Prepared Header from Consensus Engine @@ -101,7 +83,7 @@ proc resetTxEnv(dh: TxChainRef; parent: BlockHeader; baseFeePerGas: Opt[UInt256] # because that is handled in vmState let blockCtx = BlockContext( timestamp : dh.prepHeader.timestamp, - gasLimit : (if dh.maxMode: dh.limits.maxLimit else: dh.limits.trgLimit), + gasLimit : dh.gasLimit, baseFeePerGas: baseFeePerGas, prevRandao : dh.prepHeader.prevRandao, difficulty : dh.prepHeader.difficulty, @@ -130,7 +112,7 @@ proc update(dh: TxChainRef; parent: BlockHeader) # Keep a separate accounts descriptor positioned at the sync point dh.roAcc = ReadOnlyStateDB(acc) - dh.limits = dh.com.gasLimitsGet(parent, dh.lhwm) + dh.gasLimit = dh.com.gasLimitsGet(parent) dh.resetTxEnv(parent, fee) # ------------------------------------------------------------------------------ @@ -143,10 +125,6 @@ proc new*(T: type TxChainRef; com: CommonRef): T new result result.com = com - result.lhwm.lwmTrg = TRG_THRESHOLD_PER_CENT - result.lhwm.hwmMax = MAX_THRESHOLD_PER_CENT - result.lhwm.gasFloor = DEFAULT_GAS_LIMIT - result.lhwm.gasCeil = DEFAULT_GAS_LIMIT result.update(com.db.getCanonicalHead) # ------------------------------------------------------------------------------ @@ -219,18 +197,6 @@ func head*(dh: TxChainRef): BlockHeader = ## Getter dh.txEnv.vmState.parent -func limits*(dh: TxChainRef): TxChainGasLimits = - ## Getter - dh.limits - -func lhwm*(dh: TxChainRef): TxChainGasLimitsPc = - ## Getter - dh.lhwm - -func maxMode*(dh: TxChainRef): bool = - ## Getter - dh.maxMode - func feeRecipient*(dh: TxChainRef): EthAddress = ## Getter dh.com.pos.feeRecipient @@ -300,24 +266,6 @@ proc `head=`*(dh: TxChainRef; val: BlockHeader) ## account caches to a new insertion point on the block chain database. dh.update(val) -func `lhwm=`*(dh: TxChainRef; val: TxChainGasLimitsPc) = - ## Setter, tuple `(lwmTrg,hwmMax)` will allow the packer to continue - ## up until the percentage level has been reached of the `trgLimit`, or - ## `maxLimit` depending on what has been activated. - if dh.lhwm != val: - dh.lhwm = val - let parent = dh.txEnv.vmState.parent - dh.limits = dh.com.gasLimitsGet(parent, dh.limits.gasLimit, dh.lhwm) - dh.txEnv.vmState.blockCtx.gasLimit = if dh.maxMode: dh.limits.maxLimit - else: dh.limits.trgLimit - -func `maxMode=`*(dh: TxChainRef; val: bool) = - ## Setter, the packing mode (maximal or target limit) for the next block - ## header - dh.maxMode = val - dh.txEnv.vmState.blockCtx.gasLimit = if dh.maxMode: dh.limits.maxLimit - else: dh.limits.trgLimit - func `profit=`*(dh: TxChainRef; val: UInt256) = ## Setter dh.txEnv.profit = val diff --git a/nimbus/core/tx_pool/tx_chain/tx_gaslimits.nim b/nimbus/core/tx_pool/tx_chain/tx_gaslimits.nim index e3ce6a9b3..e6c0952cd 100644 --- a/nimbus/core/tx_pool/tx_chain/tx_gaslimits.nim +++ b/nimbus/core/tx_pool/tx_chain/tx_gaslimits.nim @@ -13,7 +13,6 @@ ## import - std/[math], ../../../common/common, ../../../constants, ../../pow/header, @@ -21,110 +20,25 @@ import {.push raises: [].} -type - TxChainGasLimitsPc* = tuple - lwmTrg: int ##\ - ## VM executor may stop if this per centage of `trgLimit` has - ## been reached. - hwmMax: int ##\ - ## VM executor may stop if this per centage of `maxLimit` has - ## been reached. - gasFloor: GasInt - ## minimum desired gas limit - gasCeil: GasInt - ## maximum desired gas limit - - TxChainGasLimits* = tuple - gasLimit: GasInt ## Parent gas limit, used as a base for others - minLimit: GasInt ## Minimum `gasLimit` for the packer - lwmLimit: GasInt ## Low water mark for VM/exec packer - trgLimit: GasInt ## The `gasLimit` for the packer, soft limit - hwmLimit: GasInt ## High water mark for VM/exec packer - maxLimit: GasInt ## May increase the `gasLimit` a bit, hard limit - -const - PRE_LONDON_GAS_LIMIT_TRG = ##\ - ## https://ethereum.org/en/developers/docs/blocks/#block-size - 15_000_000.GasInt - - PRE_LONDON_GAS_LIMIT_MAX = ##\ - ## https://ethereum.org/en/developers/docs/blocks/#block-size - 30_000_000.GasInt - -# ------------------------------------------------------------------------------ -# Private functions -# ------------------------------------------------------------------------------ - -proc setPostLondonLimits(gl: var TxChainGasLimits) = - ## EIP-1559 conformant gas limit update - gl.trgLimit = max(gl.gasLimit, GAS_LIMIT_MINIMUM) - - # https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md - # find in box: block.gas_used - let delta = gl.trgLimit.floorDiv(GAS_LIMIT_ADJUSTMENT_FACTOR) - gl.minLimit = gl.trgLimit + delta - gl.maxLimit = gl.trgLimit - delta - - # Fringe case: use the middle between min/max - if gl.minLimit <= GAS_LIMIT_MINIMUM: - gl.minLimit = GAS_LIMIT_MINIMUM - gl.trgLimit = (gl.minLimit + gl.maxLimit) div 2 - - -proc setPreLondonLimits(gl: var TxChainGasLimits) = - ## Pre-EIP-1559 conformant gas limit update - gl.maxLimit = PRE_LONDON_GAS_LIMIT_MAX - - const delta = (PRE_LONDON_GAS_LIMIT_TRG - GAS_LIMIT_MINIMUM) div 2 - - # Just made up to be convenient for the packer - if gl.gasLimit <= GAS_LIMIT_MINIMUM + delta: - gl.minLimit = max(gl.gasLimit, GAS_LIMIT_MINIMUM) - gl.trgLimit = PRE_LONDON_GAS_LIMIT_TRG - else: - # This setting preserves the setting from the parent block - gl.minLimit = gl.gasLimit - delta - gl.trgLimit = gl.gasLimit - # ------------------------------------------------------------------------------ # Public functions # ------------------------------------------------------------------------------ -proc gasLimitsGet*(com: CommonRef; parent: BlockHeader; parentLimit: GasInt; - pc: TxChainGasLimitsPc): TxChainGasLimits = - ## Calculate gas limits for the next block header. - result.gasLimit = parentLimit +proc gasLimitsGet*(com: CommonRef; + parent: BlockHeader): GasInt = - if com.isLondonOrLater(parent.number+1): - result.setPostLondonLimits - else: - result.setPreLondonLimits - - # VM/exec low/high water marks, optionally provided for packer - result.lwmLimit = max( - result.minLimit, (result.trgLimit * pc.lwmTrg.GasInt + 50) div 100) - - result.hwmLimit = max( - result.trgLimit, (result.maxLimit * pc.hwmMax.GasInt + 50) div 100) - - # override trgLimit, see https://github.com/status-im/nimbus-eth1/issues/1032 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 - result.trgLimit = calcGasLimit1559(parentGasLimit, desiredLimit = pc.gasCeil) + calcGasLimit1559(parentGasLimit, desiredLimit = DEFAULT_GAS_LIMIT) else: - result.trgLimit = computeGasLimit( + computeGasLimit( parent.gasUsed, parent.gasLimit, - gasFloor = pc.gasFloor, - gasCeil = pc.gasCeil) - -proc gasLimitsGet*(com: CommonRef; parent: BlockHeader; - pc: TxChainGasLimitsPc): TxChainGasLimits = - ## Variant of `gasLimitsGet()` - com.gasLimitsGet(parent, parent.gasLimit, pc) + gasFloor = DEFAULT_GAS_LIMIT, + gasCeil = DEFAULT_GAS_LIMIT) # ------------------------------------------------------------------------------ # End diff --git a/nimbus/core/tx_pool/tx_tasks/tx_classify.nim b/nimbus/core/tx_pool/tx_tasks/tx_classify.nim index 5628075dc..869d65917 100644 --- a/nimbus/core/tx_pool/tx_tasks/tx_classify.nim +++ b/nimbus/core/tx_pool/tx_tasks/tx_classify.nim @@ -95,7 +95,7 @@ proc txNonceActive(xp: TxPoolRef; item: TxItemRef): bool proc txGasCovered(xp: TxPoolRef; item: TxItemRef): bool = ## Check whether the max gas consumption is within the gas limit (aka block ## size). - let trgLimit = xp.chain.limits.trgLimit + let trgLimit = xp.chain.gasLimit if trgLimit < item.tx.gasLimit: debug "invalid tx: gasLimit exceeded", maxLimit = trgLimit, @@ -227,10 +227,7 @@ proc classifyValidatePacked*(xp: TxPoolRef; roDB = vmState.readOnlyStateDB baseFee = xp.chain.baseFee.uint64.u256 fork = xp.chain.nextFork - gasLimit = if packItemsMaxGasLimit in xp.pFlags: - xp.chain.limits.maxLimit - else: - xp.chain.limits.trgLimit + gasLimit = xp.chain.gasLimit tx = item.tx.eip1559TxNormalization(xp.chain.baseFee.GasInt) excessBlobGas = calcExcessBlobGas(vmState.parent) @@ -242,10 +239,7 @@ proc classifyPacked*(xp: TxPoolRef; gasBurned, moreBurned: GasInt): bool = ## in the VM.) This function checks whether the sum of the arguments ## `gasBurned` and `moreGasBurned` is within acceptable constraints. let totalGasUsed = gasBurned + moreBurned - if packItemsMaxGasLimit in xp.pFlags: - totalGasUsed < xp.chain.limits.maxLimit - else: - totalGasUsed < xp.chain.limits.trgLimit + totalGasUsed < xp.chain.gasLimit proc classifyPackedNext*(xp: TxPoolRef; gasBurned, moreBurned: GasInt): bool = ## Classifier for *packing* (i.e. adding up `gasUsed` values after executing @@ -256,10 +250,8 @@ proc classifyPackedNext*(xp: TxPoolRef; gasBurned, moreBurned: GasInt): bool = ## `classifyPack()`. if packItemsTryHarder notin xp.pFlags: xp.classifyPacked(gasBurned, moreBurned) - elif packItemsMaxGasLimit in xp.pFlags: - gasBurned < xp.chain.limits.hwmLimit else: - gasBurned < xp.chain.limits.lwmLimit + gasBurned < xp.chain.gasLimit # ------------------------------------------------------------------------------ # Public functionss diff --git a/nimbus/core/tx_pool/tx_tasks/tx_packer.nim b/nimbus/core/tx_pool/tx_tasks/tx_packer.nim index c736e21f8..42226ef44 100644 --- a/nimbus/core/tx_pool/tx_tasks/tx_packer.nim +++ b/nimbus/core/tx_pool/tx_tasks/tx_packer.nim @@ -150,8 +150,6 @@ proc vmExecInit(xp: TxPoolRef): Result[TxPackerStateRef, string] # reset blockValue before adding any tx xp.blockValue = 0.u256 - xp.chain.maxMode = (packItemsMaxGasLimit in xp.pFlags) - if xp.chain.com.daoForkSupport and xp.chain.com.daoForkBlock.get == xp.chain.head.number + 1: xp.chain.vmState.mutateStateDB: diff --git a/tests/test_txpool/helpers.nim b/tests/test_txpool/helpers.nim index 60ea8cf8a..b0f76657f 100644 --- a/tests/test_txpool/helpers.nim +++ b/tests/test_txpool/helpers.nim @@ -22,11 +22,8 @@ import # to import `tx_pool/*` sup-modules export pp, - tx_chain.TxChainGasLimits, - tx_chain.`maxMode=`, tx_chain.clearAccounts, tx_chain.com, - tx_chain.limits, tx_chain.nextFork, tx_chain.profit, tx_chain.receipts, @@ -175,11 +172,6 @@ proc pp*(w: TxTabsItemsCount): string = proc pp*(w: TxTabsGasTotals): string = &"{w.pending}/{w.staged}/{w.packed}" -proc pp*(w: TxChainGasLimits): string = - &"min={w.minLimit}" & - &" trg={w.lwmLimit}:{w.trgLimit}" & - &" max={w.hwmLimit}:{w.maxLimit}" - # ------------------------------------------------------------------------------ # Public functions, other # ------------------------------------------------------------------------------