diff --git a/src/chains/ethereum/ethereum/src/api.ts b/src/chains/ethereum/ethereum/src/api.ts index 578bab5da0..b12dca8cdf 100644 --- a/src/chains/ethereum/ethereum/src/api.ts +++ b/src/chains/ethereum/ethereum/src/api.ts @@ -3430,12 +3430,49 @@ export default class EthereumApi implements Api { const { transactionPool: { executables, origins, processMap } } = transactions; - + return { pending: processMap(executables.pending), queued: processMap(origins) }; } + /** + * Returns the number of transactions currently pending for inclusion in the next block(s), as well as the ones that are being scheduled for future execution only. + * + * @returns The count of transactions currently pending or queued in the transaction pool. + * @example + * ```javascript + * const [from] = await provider.request({ method: "eth_accounts", params: [] }); + * const pendingTx = await provider.request({ method: "eth_sendTransaction", params: [{ from, gas: "0x5b8d80", nonce:"0x0" }] }); + * const queuedTx = await provider.request({ method: "eth_sendTransaction", params: [{ from, gas: "0x5b8d80", nonce:"0x2" }] }); + * const pool = await provider.send("txpool_status"); + * console.log(pool); + * ``` + */ + @assertArgLength(0) + async txpool_status(): Promise<{pending: number, queued: number}> { + const { transactions } = this.#blockchain; + const { + transactionPool: { executables, origins } + } = transactions; + + let pending = 0; + let queued = 0; + + for (const [_, transactions] of executables.pending) { + pending += transactions?.array.length || 0; + } + + for (const [_, transactions] of origins) { + queued += transactions?.array.length || 0; + } + + return { + pending, + queued + }; + } + //#endregion } diff --git a/src/chains/ethereum/ethereum/tests/api/txpool/txpool.test.ts b/src/chains/ethereum/ethereum/tests/api/txpool/txpool.test.ts index f01ff0b46d..c8745f75b0 100644 --- a/src/chains/ethereum/ethereum/tests/api/txpool/txpool.test.ts +++ b/src/chains/ethereum/ethereum/tests/api/txpool/txpool.test.ts @@ -120,4 +120,52 @@ describe("txpool", () => { assert.deepStrictEqual(queued, {}); }); }); + + describe("status", () => { + let provider: EthereumProvider; + let accounts: string[]; + beforeEach(async () => { + provider = await getProvider({ + miner: { blockTime: 1000 } + }); + accounts = await provider.send("eth_accounts"); + }); + + it("handles pending and queued transactions", async () => { + const pendingTransactions = await Promise.all([ + provider.send("eth_sendTransaction", [ + { + from: accounts[1], + to: accounts[2] + } + ]), + provider.send("eth_sendTransaction", [ + { + from: accounts[2], + to: accounts[3] + } + ]), + provider.send("eth_sendTransaction", [ + { + from: accounts[1], + to: accounts[2] + } + ]) + ]); + + const queuedTransactions = await Promise.all([ + provider.send("eth_sendTransaction", [ + { + from: accounts[1], + to: accounts[2], + nonce: "0x123", + } + ]) + ]); + + const { pending, queued } = await provider.send("txpool_status"); + assert.strictEqual(pending, pendingTransactions.length); + assert.strictEqual(queued, queuedTransactions.length); + }); + }); });