{"version":3,"sources":["../src/TxPool.ts"],"names":["BlobEIP4844Transaction","equalsBytes","bytesToHex","EthjsAccount","bytesToUnprefixedHex","tx","Capability","isLegacyTx","isAccessListEIP2930Tx","isFeeMarketEIP1559Tx","isBlobEIP4844Tx","Heap","txs"],"mappings":"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","file":"index.cjs","sourcesContent":["// this file is adapted from https://github.com/ethereumjs/ethereumjs-monorepo/blob/master/packages/client/src/service/txpool.ts and thus carries the same license\n\nimport type { Block } from '@tevm/block'\nimport {\n\tBlobEIP4844Transaction,\n\tCapability,\n\ttype FeeMarketEIP1559Transaction,\n\ttype ImpersonatedTx,\n\tisAccessListEIP2930Tx,\n\tisBlobEIP4844Tx,\n\tisFeeMarketEIP1559Tx,\n\tisLegacyTx,\n\ttype LegacyTransaction,\n\ttype TypedTransaction,\n} from '@tevm/tx'\nimport { bytesToHex, bytesToUnprefixedHex, EthjsAccount, EthjsAddress, equalsBytes } from '@tevm/utils'\nimport type { Vm } from '@tevm/vm'\nimport type QHeap from 'qheap'\nimport Heap from 'qheap'\n\n// Configuration constants\nconst MIN_GAS_PRICE_BUMP_PERCENT = 10\nconst MIN_GAS_PRICE = BigInt(100000000) // .1 GWei\nconst TX_MAX_DATA_SIZE = 128 * 1024 // 128KB\nconst MAX_POOL_SIZE = 5000\nconst MAX_TXS_PER_ACCOUNT = 100\n\nexport interface TxPoolOptions {\n\tvm: Vm\n\tmaxSize?: number\n\tmaxPerSender?: number\n}\n\ntype TxPoolObject = {\n\ttx: TypedTransaction | ImpersonatedTx\n\thash: UnprefixedHash\n\tadded: number\n\terror?: Error\n}\n\ntype HandledObject = {\n\taddress: UnprefixedAddress\n\tadded: number\n\terror?: Error\n}\n\ntype UnprefixedAddress = string\ntype UnprefixedHash = string\n\ntype GasPrice = {\n\ttip: bigint\n\tmaxFee: bigint\n}\n\n/**\n * @module service\n */\n\n/**\n * @experimental\n * Tx pool (mempool)\n * @memberof module:service\n */\nexport class TxPool {\n\tprivate vm: Vm\n\tprivate maxSize: number\n\tprivate maxPerSender: number\n\tprivate opened: boolean\n\tpublic running: boolean\n\n\t/* global NodeJS */\n\tprivate _cleanupInterval: Timer | undefined\n\tprivate _logInterval: Timer | undefined\n\n\t/**\n\t * The central pool dataset.\n\t *\n\t * Maps an address to a `TxPoolObject`\n\t */\n\tpublic pool: Map<UnprefixedAddress, TxPoolObject[]>\n\n\t/**\n\t * Transactions in nonce order for all senders\n\t */\n\tpublic txsInNonceOrder: Map<UnprefixedAddress, TypedTransaction[]> = new Map()\n\n\t/**\n\t * Transactions by hash\n\t */\n\tpublic txsByHash: Map<UnprefixedHash, TypedTransaction> = new Map()\n\n\t/**\n\t * Transactions by account and nonce\n\t */\n\tpublic txsByNonce: Map<UnprefixedAddress, Map<bigint, TypedTransaction>> = new Map()\n\n\t/**\n\t * The number of txs currently in the pool\n\t */\n\tpublic txsInPool: number\n\n\t/**\n\t * Map for handled tx hashes\n\t * (have been added to the pool at some point)\n\t *\n\t * This is meant to be a superset of the tx pool\n\t * so at any point it time containing minimally\n\t * all txs from the pool.\n\t */\n\tprivate handled: Map<UnprefixedHash, HandledObject>\n\n\t/**\n\t * Activate before chain head is reached to start\n\t * tx pool preparation (sorting out included txs)\n\t */\n\tpublic BLOCKS_BEFORE_TARGET_HEIGHT_ACTIVATION = 20\n\n\t/**\n\t * Number of minutes to keep txs in the pool\n\t */\n\tpublic POOLED_STORAGE_TIME_LIMIT = 20\n\n\t/**\n\t * Number of minutes to forget about handled\n\t * txs (for cleanup/memory reasons)\n\t */\n\tpublic HANDLED_CLEANUP_TIME_LIMIT = 60\n\n\t/**\n\t * Create new tx pool\n\t * @param options constructor parameters\n\t */\n\tconstructor({ vm, maxSize = MAX_POOL_SIZE, maxPerSender = MAX_TXS_PER_ACCOUNT }: TxPoolOptions) {\n\t\tthis.vm = vm\n\t\tthis.maxSize = maxSize\n\t\tthis.maxPerSender = maxPerSender\n\t\tthis.pool = new Map<UnprefixedAddress, TxPoolObject[]>()\n\t\tthis.txsInPool = 0\n\t\tthis.handled = new Map<UnprefixedHash, HandledObject>()\n\t\tthis.txsByHash = new Map<UnprefixedHash, TypedTransaction>()\n\t\tthis.txsByNonce = new Map<UnprefixedAddress, Map<bigint, TypedTransaction>>()\n\t\tthis.txsInNonceOrder = new Map<UnprefixedAddress, TypedTransaction[]>()\n\n\t\tthis.opened = false\n\t\tthis.running = true\n\t}\n\n\tdeepCopy(opt: TxPoolOptions): TxPool {\n\t\tconst newTxPool = new TxPool(opt)\n\t\tnewTxPool.pool = new Map(this.pool)\n\t\tnewTxPool.txsInPool = this.txsInPool\n\t\tnewTxPool.handled = new Map(this.handled)\n\t\tnewTxPool.txsByHash = new Map(this.txsByHash)\n\t\tnewTxPool.txsByNonce = new Map(this.txsByNonce)\n\t\tnewTxPool.txsInNonceOrder = new Map(this.txsInNonceOrder)\n\t\tnewTxPool.opened = this.opened\n\t\tnewTxPool.running = this.running\n\t\treturn newTxPool\n\t}\n\n\t/**\n\t * Open pool\n\t */\n\topen(): boolean {\n\t\tif (this.opened) {\n\t\t\treturn false\n\t\t}\n\t\tthis.opened = true\n\n\t\treturn true\n\t}\n\n\t/**\n\t * Start tx processing\n\t */\n\tstart(): boolean {\n\t\tif (this.running) {\n\t\t\treturn false\n\t\t}\n\t\tthis._cleanupInterval = setInterval(this.cleanup.bind(this), this.POOLED_STORAGE_TIME_LIMIT * 1000 * 60)\n\n\t\tthis.running = true\n\t\treturn true\n\t}\n\n\tprivate validateTxGasBump(existingTx: TypedTransaction | ImpersonatedTx, addedTx: TypedTransaction | ImpersonatedTx) {\n\t\tconst existingTxGasPrice = this.txGasPrice(existingTx)\n\t\tconst newGasPrice = this.txGasPrice(addedTx)\n\t\tconst minTipCap =\n\t\t\texistingTxGasPrice.tip + (existingTxGasPrice.tip * BigInt(MIN_GAS_PRICE_BUMP_PERCENT)) / BigInt(100)\n\n\t\tconst minFeeCap =\n\t\t\texistingTxGasPrice.maxFee + (existingTxGasPrice.maxFee * BigInt(MIN_GAS_PRICE_BUMP_PERCENT)) / BigInt(100)\n\t\tif (newGasPrice.tip < minTipCap || newGasPrice.maxFee < minFeeCap) {\n\t\t\tthrow new Error(\n\t\t\t\t`replacement gas too low, got tip ${newGasPrice.tip}, min: ${minTipCap}, got fee ${newGasPrice.maxFee}, min: ${minFeeCap}`,\n\t\t\t)\n\t\t}\n\n\t\tif (addedTx instanceof BlobEIP4844Transaction && existingTx instanceof BlobEIP4844Transaction) {\n\t\t\tconst minblobGasFee =\n\t\t\t\texistingTx.maxFeePerBlobGas + (existingTx.maxFeePerBlobGas * BigInt(MIN_GAS_PRICE_BUMP_PERCENT)) / BigInt(100)\n\t\t\tif (addedTx.maxFeePerBlobGas < minblobGasFee) {\n\t\t\t\tthrow new Error(`replacement blob gas too low, got: ${addedTx.maxFeePerBlobGas}, min: ${minblobGasFee}`)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Validates a transaction against the pool and other constraints\n\t * @param tx The tx to validate\n\t */\n\tprivate async validate(\n\t\ttx: TypedTransaction | ImpersonatedTx,\n\t\tisLocalTransaction = false,\n\t\trequireSignature = true,\n\t\tskipBalance = false,\n\t) {\n\t\tif (requireSignature && !tx.isSigned()) {\n\t\t\tthrow new Error('Attempting to add tx to txpool which is not signed')\n\t\t}\n\t\tif (tx.data.length > TX_MAX_DATA_SIZE) {\n\t\t\tthrow new Error(\n\t\t\t\t`Tx is too large (${tx.data.length} bytes) and exceeds the max data size of ${TX_MAX_DATA_SIZE} bytes`,\n\t\t\t)\n\t\t}\n\t\tconst currentGasPrice = this.txGasPrice(tx)\n\t\t// This is the tip which the miner receives: miner does not want\n\t\t// to mine underpriced txs where miner gets almost no fees\n\t\tconst currentTip = currentGasPrice.tip\n\t\tif (!isLocalTransaction) {\n\t\t\tconst txsInPool = this.txsInPool\n\t\t\tif (txsInPool >= this.maxSize) {\n\t\t\t\tthrow new Error('Transaction pool is full')\n\t\t\t}\n\t\t\t// Local txs are not checked against MIN_GAS_PRICE\n\t\t\tif (currentTip < MIN_GAS_PRICE) {\n\t\t\t\tthrow new Error(`Tx does not pay the minimum gas price of ${MIN_GAS_PRICE}`)\n\t\t\t}\n\t\t}\n\t\tconst senderAddress = tx.getSenderAddress()\n\t\tconst sender: UnprefixedAddress = senderAddress.toString().slice(2).toLowerCase()\n\t\tconst inPool = this.pool.get(sender)\n\t\tif (inPool) {\n\t\t\tif (!isLocalTransaction && inPool.length >= this.maxPerSender) {\n\t\t\t\tthrow new Error(`Sender has too many transactions: already have ${inPool.length} txs for this account`)\n\t\t\t}\n\t\t\t// Replace pooled txs with the same nonce\n\t\t\tconst existingTxn = inPool.find((poolObj) => poolObj.tx.nonce === tx.nonce)\n\t\t\tif (existingTxn) {\n\t\t\t\tif (equalsBytes(existingTxn.tx.hash(), tx.hash())) {\n\t\t\t\t\tthrow new Error(`${bytesToHex(tx.hash())}: this transaction is already in the TxPool`)\n\t\t\t\t}\n\t\t\t\tthis.validateTxGasBump(existingTxn.tx, tx)\n\t\t\t}\n\t\t}\n\t\t// TODO\n\t\tconst block = await this.vm.blockchain.getCanonicalHeadBlock()\n\t\tif (typeof block.header.baseFeePerGas === 'bigint' && block.header.baseFeePerGas !== 0n) {\n\t\t\tif (currentGasPrice.maxFee < block.header.baseFeePerGas / 2n && !isLocalTransaction) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Tx cannot pay basefee of ${block.header.baseFeePerGas}, have ${currentGasPrice.maxFee} (not within 50% range of current basefee)`,\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\tif (tx.gasLimit > block.header.gasLimit) {\n\t\t\tthrow new Error(\n\t\t\t\t`Tx gaslimit of ${tx.gasLimit} exceeds block gas limit of ${block.header.gasLimit} (exceeds last block gas limit)`,\n\t\t\t)\n\t\t}\n\n\t\t// Copy VM in order to not overwrite the state root of the VMExecution module which may be concurrently running blocks\n\t\tconst vmCopy = await this.vm.deepCopy()\n\t\t// TODO We should set state root to latest block so that account balance is correct when doing balance check\n\t\t// This should be fixed via abstracting chain history wrt state and blockchain in the new `chain` object\n\t\t// await vmCopy.stateManager.setStateRoot(block.stateRoot)\n\t\tlet account = await vmCopy.stateManager.getAccount(senderAddress)\n\t\tif (account === undefined) {\n\t\t\taccount = new EthjsAccount()\n\t\t}\n\t\tif (account.nonce > tx.nonce) {\n\t\t\tthrow new Error(\n\t\t\t\t`0x${sender} tries to send a tx with nonce ${tx.nonce}, but account has nonce ${account.nonce} (tx nonce too low)`,\n\t\t\t)\n\t\t}\n\t\tconst minimumBalance = tx.value + currentGasPrice.maxFee * tx.gasLimit\n\t\tif (!skipBalance && account.balance < minimumBalance) {\n\t\t\tthrow new Error(\n\t\t\t\t`0x${sender} does not have enough balance to cover transaction costs, need ${minimumBalance}, but have ${account.balance} (insufficient balance)`,\n\t\t\t)\n\t\t}\n\t}\n\n\t/**\n\t * Adds a tx to the pool without validating it.\n\t *\n\t * If there is a tx in the pool with the same address and\n\t * nonce it will be replaced by the new tx, if it has a sufficient gas bump.\n\t * This also verifies certain constraints, if these are not met, tx will not be added to the pool.\n\t * @param tx Transaction\n\t * @param isLocalTransaction if this is a local transaction (loosens some constraints) (default: false)\n\t */\n\tasync addUnverified(tx: TypedTransaction | ImpersonatedTx) {\n\t\tconst hash: UnprefixedHash = bytesToUnprefixedHex(tx.hash())\n\t\tconst added = Date.now()\n\t\tconst address: UnprefixedAddress = tx.getSenderAddress().toString().slice(2).toLowerCase()\n\t\ttry {\n\t\t\tlet add: TxPoolObject[] = this.pool.get(address) ?? []\n\t\t\tconst inPool = this.pool.get(address)\n\n\t\t\t// Update txsByHash\n\t\t\tthis.txsByHash.set(hash, tx)\n\n\t\t\t// Update txsByNonce\n\t\t\tlet nonceMap = this.txsByNonce.get(address)\n\t\t\tif (!nonceMap) {\n\t\t\t\tnonceMap = new Map()\n\t\t\t\tthis.txsByNonce.set(address, nonceMap)\n\t\t\t}\n\t\t\tnonceMap.set(tx.nonce, tx)\n\n\t\t\t// Update txsInNonceOrder\n\t\t\tlet txList = this.txsInNonceOrder.get(address) ?? []\n\t\t\ttxList = txList.filter((existingTx) => existingTx.nonce !== tx.nonce)\n\t\t\ttxList.push(tx)\n\t\t\ttxList.sort((a, b) => Number(a.nonce - b.nonce))\n\t\t\tthis.txsInNonceOrder.set(address, txList)\n\n\t\t\tif (inPool) {\n\t\t\t\t// Replace pooled txs with the same nonce\n\t\t\t\tadd = inPool.filter((poolObj) => poolObj.tx.nonce !== tx.nonce)\n\t\t\t}\n\t\t\tadd.push({ tx, added, hash })\n\t\t\tthis.pool.set(address, add)\n\t\t\tthis.handled.set(hash, { address, added })\n\t\t\tthis.txsInPool++\n\n\t\t\t// Fire txadded event\n\t\t\tthis.fireEvent('txadded', bytesToHex(tx.hash()))\n\n\t\t\treturn { error: null, hash: bytesToHex(tx.hash()) }\n\t\t} catch (e) {\n\t\t\tthis.handled.set(hash, { address, added, error: e as Error })\n\t\t\treturn { error: (e as Error).message, hash: bytesToHex(tx.hash()) }\n\t\t}\n\t}\n\n\t/**\n\t * Adds a tx to the pool.\n\t *\n\t * If there is a tx in the pool with the same address and\n\t * nonce it will be replaced by the new tx, if it has a sufficient gas bump.\n\t * This also verifies certain constraints, if these are not met, tx will not be added to the pool.\n\t * @param tx Transaction\n\t * @param isLocalTransaction if this is a local transaction (loosens some constraints) (default: false)\n\t */\n\tasync add(tx: TypedTransaction | ImpersonatedTx, requireSignature = true, skipBalance = false) {\n\t\ttry {\n\t\t\tawait this.validate(tx, true, requireSignature, skipBalance)\n\t\t\treturn this.addUnverified(tx)\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\terror: (error as Error).message,\n\t\t\t\thash: bytesToHex(tx.hash()),\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns the available txs from the pool\n\t * @param txHashes\n\t * @returns Array with tx objects\n\t */\n\tgetByHash(txHashes: string): TypedTransaction | ImpersonatedTx | null\n\tgetByHash(txHashes: ReadonlyArray<Uint8Array>): Array<TypedTransaction | ImpersonatedTx>\n\tgetByHash(\n\t\ttxHashes: ReadonlyArray<Uint8Array> | string,\n\t): Array<TypedTransaction | ImpersonatedTx> | TypedTransaction | ImpersonatedTx | null {\n\t\tif (typeof txHashes === 'string') {\n\t\t\t// Single hash case\n\t\t\tconst txHashStr = txHashes.startsWith('0x') ? txHashes.slice(2).toLowerCase() : txHashes.toLowerCase()\n\t\t\tconst handled = this.handled.get(txHashStr)\n\t\t\tif (!handled) return null\n\t\t\tconst inPool = this.pool.get(handled.address)?.filter((poolObj) => poolObj.hash === txHashStr)\n\t\t\tif (inPool && inPool.length === 1) {\n\t\t\t\tif (!inPool[0]) {\n\t\t\t\t\tthrow new Error('Expected element to exist in pool')\n\t\t\t\t}\n\t\t\t\treturn inPool[0].tx\n\t\t\t}\n\t\t\treturn null\n\t\t}\n\t\t// Array of hashes case\n\t\tconst found = []\n\t\tfor (const txHash of txHashes) {\n\t\t\tconst txHashStr = bytesToUnprefixedHex(txHash)\n\t\t\tconst handled = this.handled.get(txHashStr)\n\t\t\tif (!handled) continue\n\t\t\tconst inPool = this.pool.get(handled.address)?.filter((poolObj) => poolObj.hash === txHashStr)\n\t\t\tif (inPool && inPool.length === 1) {\n\t\t\t\tif (!inPool[0]) {\n\t\t\t\t\tthrow new Error('Expected element to exist in pool')\n\t\t\t\t}\n\t\t\t\tfound.push(inPool[0].tx)\n\t\t\t}\n\t\t}\n\t\treturn found\n\t}\n\n\t/**\n\t * Removes the given tx from the pool\n\t * @param txHash Hash of the transaction\n\t */\n\tremoveByHash(txHash: string) {\n\t\tconst unprefixedTxHash = txHash.startsWith('0x') ? txHash.slice(2).toLowerCase() : txHash.toLowerCase()\n\t\tconst handled = this.handled.get(unprefixedTxHash)\n\t\tif (!handled) return\n\t\tconst { address } = handled\n\n\t\t// Remove from txsByHash\n\t\tthis.txsByHash.delete(unprefixedTxHash)\n\n\t\t// Get the transaction to find its nonce\n\t\tconst poolObjects = this.pool.get(address)\n\t\tif (!poolObjects) return\n\n\t\t// Find the tx to get its nonce\n\t\tconst txToRemove = poolObjects.find((poolObj) => poolObj.hash === unprefixedTxHash)\n\t\tif (txToRemove) {\n\t\t\t// Remove from txsByNonce\n\t\t\tconst nonceMap = this.txsByNonce.get(address)\n\t\t\tif (nonceMap) {\n\t\t\t\tnonceMap.delete(txToRemove.tx.nonce)\n\t\t\t\tif (nonceMap.size === 0) {\n\t\t\t\t\tthis.txsByNonce.delete(address)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove from txsInNonceOrder\n\t\t\tconst txList = this.txsInNonceOrder.get(address)\n\t\t\tif (txList) {\n\t\t\t\tconst newTxList = txList.filter((tx) => tx.nonce !== txToRemove.tx.nonce)\n\t\t\t\tif (newTxList.length === 0) {\n\t\t\t\t\tthis.txsInNonceOrder.delete(address)\n\t\t\t\t} else {\n\t\t\t\t\tthis.txsInNonceOrder.set(address, newTxList)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Update main pool\n\t\tconst newPoolObjects = poolObjects.filter((poolObj) => poolObj.hash !== unprefixedTxHash)\n\t\tthis.txsInPool--\n\t\tif (newPoolObjects.length === 0) {\n\t\t\t// List of txs for address is now empty, can delete\n\t\t\tthis.pool.delete(address)\n\t\t} else {\n\t\t\t// There are more txs from this address\n\t\t\tthis.pool.set(address, newPoolObjects)\n\t\t}\n\n\t\t// Fire txremoved event\n\t\tthis.fireEvent('txremoved', `0x${unprefixedTxHash}`)\n\t}\n\n\t/**\n\t * Remove txs included in the latest blocks from the tx pool\n\t */\n\tremoveNewBlockTxs(newBlocks: Block[]) {\n\t\tif (!this.running) return\n\t\tfor (const block of newBlocks) {\n\t\t\tfor (const tx of block.transactions) {\n\t\t\t\tconst txHash: UnprefixedHash = bytesToUnprefixedHex(tx.hash())\n\t\t\t\tthis.removeByHash(txHash)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Regular tx pool cleanup\n\t */\n\tcleanup() {\n\t\t// Remove txs older than POOLED_STORAGE_TIME_LIMIT from the pool\n\t\tlet compDate = Date.now() - this.POOLED_STORAGE_TIME_LIMIT * 1000 * 60\n\t\tfor (const [i, mapToClean] of [this.pool].entries()) {\n\t\t\tfor (const [key, objects] of mapToClean) {\n\t\t\t\tconst updatedObjects = objects.filter((obj) => obj.added >= compDate)\n\t\t\t\tif (updatedObjects.length < objects.length) {\n\t\t\t\t\tif (i === 0) this.txsInPool -= objects.length - updatedObjects.length\n\t\t\t\t\tif (updatedObjects.length === 0) {\n\t\t\t\t\t\tmapToClean.delete(key)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmapToClean.set(key, updatedObjects)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Cleanup handled txs\n\t\tcompDate = Date.now() - this.HANDLED_CLEANUP_TIME_LIMIT * 1000 * 60\n\t\tfor (const [address, handleObj] of this.handled) {\n\t\t\tif (handleObj.added < compDate) {\n\t\t\t\tthis.handled.delete(address)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Helper to return a normalized gas price across different\n\t * transaction types. Providing the baseFee param returns the\n\t * priority tip, and omitting it returns the max total fee.\n\t * @param tx The tx\n\t * @param baseFee Provide a baseFee to subtract from the legacy\n\t * gasPrice to determine the leftover priority tip.\n\t */\n\tprivate normalizedGasPrice(tx: TypedTransaction | ImpersonatedTx, baseFee?: bigint) {\n\t\tconst supports1559 = tx.supports(Capability.EIP1559FeeMarket)\n\t\tif (typeof baseFee === 'bigint' && baseFee !== 0n) {\n\t\t\tif (supports1559) {\n\t\t\t\treturn (tx as FeeMarketEIP1559Transaction).maxPriorityFeePerGas\n\t\t\t}\n\t\t\treturn (tx as LegacyTransaction).gasPrice - baseFee\n\t\t}\n\t\tif (supports1559) {\n\t\t\treturn (tx as FeeMarketEIP1559Transaction).maxFeePerGas\n\t\t}\n\t\treturn (tx as LegacyTransaction).gasPrice\n\t}\n\t/**\n\t * Returns the GasPrice object to provide information of the tx' gas prices\n\t * @param tx Tx to use\n\t * @returns Gas price (both tip and max fee)\n\t */\n\tprivate txGasPrice(tx: TypedTransaction | ImpersonatedTx): GasPrice {\n\t\tif ('isImpersonated' in tx && tx.isImpersonated) {\n\t\t\treturn {\n\t\t\t\tmaxFee: tx.maxFeePerGas,\n\t\t\t\ttip: tx.maxPriorityFeePerGas,\n\t\t\t}\n\t\t}\n\t\tif (isLegacyTx(tx)) {\n\t\t\treturn {\n\t\t\t\tmaxFee: tx.gasPrice,\n\t\t\t\ttip: tx.gasPrice,\n\t\t\t}\n\t\t}\n\n\t\tif (isAccessListEIP2930Tx(tx)) {\n\t\t\treturn {\n\t\t\t\tmaxFee: tx.gasPrice,\n\t\t\t\ttip: tx.gasPrice,\n\t\t\t}\n\t\t}\n\n\t\tif (isFeeMarketEIP1559Tx(tx) || isBlobEIP4844Tx(tx)) {\n\t\t\treturn {\n\t\t\t\tmaxFee: tx.maxFeePerGas,\n\t\t\t\ttip: tx.maxPriorityFeePerGas,\n\t\t\t}\n\t\t}\n\t\tthrow new Error(`tx of type ${(tx as TypedTransaction).type} unknown`)\n\t}\n\n\tasync getBySenderAddress(address: EthjsAddress): Promise<Array<TxPoolObject>> {\n\t\tconst unprefixedAddress = address.toString().slice(2).toLowerCase()\n\t\treturn this.pool.get(unprefixedAddress) ?? []\n\t}\n\n\t/**\n\t * Get all pending transactions in the pool\n\t * @returns Array of transactions\n\t */\n\tasync getPendingTransactions(): Promise<Array<TypedTransaction | ImpersonatedTx>> {\n\t\tconst allTxs: Array<TypedTransaction | ImpersonatedTx> = []\n\t\tfor (const txs of this.pool.values()) {\n\t\t\tallTxs.push(...txs.map((obj) => obj.tx))\n\t\t}\n\t\treturn allTxs\n\t}\n\n\t/**\n\t * Get transaction status\n\t * @param txHash Transaction hash\n\t * @returns Transaction status: 'pending', 'mined', or 'unknown'\n\t */\n\tasync getTransactionStatus(txHash: string): Promise<'pending' | 'mined' | 'unknown'> {\n\t\tconst hash = txHash.startsWith('0x') ? txHash.slice(2).toLowerCase() : txHash.toLowerCase()\n\n\t\t// Check if in pool (pending)\n\t\tif (this.txsByHash.has(hash)) {\n\t\t\treturn 'pending'\n\t\t}\n\n\t\t// Check if in handled map but not in pool (could be mined)\n\t\tconst handled = this.handled.get(hash)\n\t\tif (handled) {\n\t\t\treturn 'mined'\n\t\t}\n\n\t\treturn 'unknown'\n\t}\n\n\t/**\n\t * Events system for transaction pool\n\t */\n\tprivate events: { [key: string]: Array<(hash: string) => void> } = {\n\t\ttxadded: [],\n\t\ttxremoved: [],\n\t}\n\n\t/**\n\t * Register an event handler\n\t * @param event Event name ('txadded' or 'txremoved')\n\t * @param callback Handler function\n\t */\n\ton(event: 'txadded' | 'txremoved', callback: (hash: string) => void) {\n\t\tif (!this.events[event]) {\n\t\t\tthis.events[event] = []\n\t\t}\n\t\tthis.events[event].push(callback)\n\t}\n\n\t/**\n\t * Fire an event\n\t * @param event Event name\n\t * @param hash Transaction hash\n\t */\n\tprivate fireEvent(event: 'txadded' | 'txremoved', hash: string) {\n\t\tif (this.events[event]) {\n\t\t\tfor (const callback of this.events[event]) {\n\t\t\t\tcallback(hash)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Handle block being added to the chain\n\t * @param block The block that was added\n\t */\n\tasync onBlockAdded(block: Block) {\n\t\tthis.removeNewBlockTxs([block])\n\t}\n\n\t/**\n\t * Handle chain reorganization\n\t * @param removedBlocks Blocks that were removed from the canonical chain\n\t * @param addedBlocks Blocks that were added to the canonical chain\n\t */\n\tasync onChainReorganization(removedBlocks: Block[], addedBlocks: Block[]) {\n\t\t// First process removed blocks - add their txs back to the pool\n\t\tfor (const block of removedBlocks) {\n\t\t\tfor (const tx of block.transactions) {\n\t\t\t\t// Skip if tx is already in pool or in one of the added blocks\n\t\t\t\tconst txHash = bytesToHex(tx.hash())\n\t\t\t\tconst txHashUnprefixed = txHash.slice(2).toLowerCase()\n\t\t\t\tif (this.txsByHash.has(txHashUnprefixed)) continue\n\n\t\t\t\t// Add tx back to the pool\n\t\t\t\tawait this.addUnverified(tx)\n\t\t\t}\n\t\t}\n\n\t\t// Then process added blocks - remove their txs from the pool\n\t\tthis.removeNewBlockTxs(addedBlocks)\n\t}\n\n\t/**\n\t * Returns eligible txs to be mined sorted by price in such a way that the\n\t * nonce orderings within a single account are maintained.\n\t *\n\t * Note, this is not as trivial as it seems from the first look as there are three\n\t * different criteria that need to be taken into account (price, nonce, account\n\t * match), which cannot be done with any plain sorting method, as certain items\n\t * cannot be compared without context.\n\t *\n\t * This method first sorts the separates the list of transactions into individual\n\t * sender accounts and sorts them by nonce. After the account nonce ordering is\n\t * satisfied, the results are merged back together by price, always comparing only\n\t * the head transaction from each account. This is done via a heap to keep it fast.\n\t *\n\t * @param baseFee Provide a baseFee to exclude txs with a lower gasPrice\n\t */\n\tasync txsByPriceAndNonce({ baseFee, allowedBlobs }: { baseFee?: bigint; allowedBlobs?: number } = {}) {\n\t\tconst txs: Array<TypedTransaction | ImpersonatedTx> = []\n\t\t// Separate the transactions by account and sort by nonce\n\t\tconst byNonce = new Map<string, Array<TypedTransaction | ImpersonatedTx>>()\n\t\tconst skippedStats = { byNonce: 0, byPrice: 0, byBlobsLimit: 0 }\n\t\tfor (const [address, poolObjects] of this.pool) {\n\t\t\tlet txsSortedByNonce = poolObjects.map((obj) => obj.tx).sort((a, b) => Number(a.nonce - b.nonce))\n\t\t\t// TODO we should be checking this but removing for now works\n\t\t\t// Check if the account nonce matches the lowest known tx nonce\n\t\t\t// let account = await vm.stateManager.getAccount(new EthjsAddress(hexToBytes(`0x${address}`)))\n\t\t\t// if (account === undefined) {\n\t\t\t// account = new EthjsAccount()\n\t\t\t// }\n\t\t\t// const { nonce } = account\n\t\t\t// if (txsSortedByNonce[0]?.nonce !== nonce) {\n\t\t\t// Account nonce does not match the lowest known tx nonce,\n\t\t\t// therefore no txs from this address are currently executable\n\t\t\t// skippedStats.byNonce += txsSortedByNonce.length\n\t\t\t// console.log('skipped', txsSortedByNonce[0]?.nonce, nonce)\n\t\t\t// continue\n\t\t\t// }\n\t\t\tif (typeof baseFee === 'bigint' && baseFee !== 0n) {\n\t\t\t\t// If any tx has an insufficient gasPrice,\n\t\t\t\t// remove all txs after that since they cannot be executed\n\t\t\t\tconst found = txsSortedByNonce.findIndex((tx) => this.normalizedGasPrice(tx) < baseFee)\n\t\t\t\tif (found > -1) {\n\t\t\t\t\tskippedStats.byPrice += found + 1\n\t\t\t\t\ttxsSortedByNonce = txsSortedByNonce.slice(0, found)\n\t\t\t\t}\n\t\t\t}\n\t\t\tbyNonce.set(address, txsSortedByNonce)\n\t\t}\n\t\t// Initialize a price based heap with the head transactions\n\t\tconst byPrice = new Heap({\n\t\t\tcomparBefore: (a: TypedTransaction, b: TypedTransaction) =>\n\t\t\t\tthis.normalizedGasPrice(b, baseFee) - this.normalizedGasPrice(a, baseFee) < 0n,\n\t\t}) as QHeap<TypedTransaction | ImpersonatedTx>\n\t\tfor (const [address, txs] of byNonce) {\n\t\t\tif (!txs[0]) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tbyPrice.insert(txs[0])\n\t\t\tbyNonce.set(address, txs.slice(1))\n\t\t}\n\t\t// Merge by replacing the best with the next from the same account\n\t\tlet blobsCount = 0\n\t\twhile (byPrice.length > 0) {\n\t\t\t// Retrieve the next best transaction by price\n\t\t\tconst best = byPrice.remove()\n\t\t\tif (best === undefined) break\n\n\t\t\t// Push in its place the next transaction from the same account\n\t\t\tconst address = best.getSenderAddress().toString().slice(2).toLowerCase()\n\t\t\tconst accTxs = byNonce.get(address)\n\n\t\t\tif (!accTxs) {\n\t\t\t\tthrow new Error('Expected accTxs to be defined')\n\t\t\t}\n\n\t\t\t// Insert the best tx into byPrice if\n\t\t\t//   i) this is not a blob tx,\n\t\t\t//   ii) or there is no blobs limit provided\n\t\t\t//   iii) or blobs are still within limit if this best tx's blobs are included\n\t\t\tif (\n\t\t\t\t!(best instanceof BlobEIP4844Transaction) ||\n\t\t\t\tallowedBlobs === undefined ||\n\t\t\t\t((best as BlobEIP4844Transaction).blobs ?? []).length + blobsCount <= allowedBlobs\n\t\t\t) {\n\t\t\t\tif (accTxs.length > 0) {\n\t\t\t\t\tif (!accTxs[0]) {\n\t\t\t\t\t\tthrow new Error('Expected accTxs to be defined')\n\t\t\t\t\t}\n\t\t\t\t\tbyPrice.insert(accTxs[0])\n\t\t\t\t\tbyNonce.set(address, accTxs.slice(1))\n\t\t\t\t}\n\t\t\t\t// Accumulate the best priced transaction and increment blobs count\n\t\t\t\ttxs.push(best)\n\t\t\t\tif (best instanceof BlobEIP4844Transaction) {\n\t\t\t\t\tblobsCount += ((best as BlobEIP4844Transaction).blobs ?? []).length\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Since no more blobs can fit in the block, not only skip inserting in byPrice but also remove all other\n\t\t\t\t// txs (blobs or not) of this sender address from further consideration\n\t\t\t\tskippedStats.byBlobsLimit += 1 + accTxs.length\n\t\t\t\tbyNonce.set(address, [])\n\t\t\t}\n\t\t}\n\t\treturn txs\n\t}\n\n\t/**\n\t * Stop pool execution\n\t */\n\tstop(): boolean {\n\t\tif (!this.running) return false\n\t\tclearInterval(this._cleanupInterval as NodeJS.Timeout)\n\t\tclearInterval(this._logInterval as NodeJS.Timeout)\n\t\tthis.running = false\n\t\treturn true\n\t}\n\n\t/**\n\t * Close pool\n\t */\n\tclose() {\n\t\tthis.pool.clear()\n\t\tthis.handled.clear()\n\t\tthis.txsByHash.clear()\n\t\tthis.txsByNonce.clear()\n\t\tthis.txsInNonceOrder.clear()\n\t\tthis.txsInPool = 0\n\t\tthis.opened = false\n\t}\n\n\t/**\n\t * Clears the pool of all transactions.\n\t */\n\tasync clear() {\n\t\tthis.pool.clear()\n\t\tthis.txsByHash.clear()\n\t\tthis.txsByNonce.clear()\n\t\tthis.txsInNonceOrder.clear()\n\t\tthis.txsInPool = 0\n\t}\n\n\tlogStats() {\n\t\tconsole.log('TxPool Stats:')\n\t\tconsole.log(`  Pending: ${this.txsInPool}`)\n\t\tconsole.log(`  Handled: ${this.handled.size}`)\n\n\t\tlet handledadds = 0\n\t\tlet handlederrors = 0\n\t\tfor (const handledobject of this.handled.values()) {\n\t\t\tif (handledobject.error === undefined) {\n\t\t\t\thandledadds++\n\t\t\t} else {\n\t\t\t\thandlederrors++\n\t\t\t}\n\t\t}\n\n\t\tconsole.log(`  Successful: ${handledadds}`)\n\t\tconsole.log(`  Errors: ${handlederrors}`)\n\n\t\tconst addresses = Array.from(this.pool.keys())\n\t\tconsole.log(`  Unique accounts: ${addresses.length}`)\n\t}\n\n\t// For backward compatibility with tests\n\t_logPoolStats() {\n\t\tthis.logStats()\n\t}\n}\n"]}