Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
feat: txpool_contentFrom
Browse files Browse the repository at this point in the history
  • Loading branch information
amandesai01 committed Sep 25, 2022
1 parent 46609dc commit 3843ec2
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 1 deletion.
30 changes: 30 additions & 0 deletions src/chains/ethereum/ethereum/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3437,6 +3437,36 @@ export default class EthereumApi implements Api {
};
}


/**
* Returns the number of transactions created by specified address currently pending for inclusion in the next block(s), as well as the ones that are being scheduled for future execution only.
*
* @param address - The account address
* @returns The count of transactions currently pending or queued in the transaction pool by address.
* @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_contentFrom", [from]);
* console.log(pool);
* ```
*/
@assertArgLength(1)
async txpool_contentFrom(address: DATA): Promise<Ethereum.Pool.Content<"private">> {
const { transactions } = this.#blockchain;
const {
transactionPool: { executables, origins, processMap }
} = transactions;

const fromAddress = Address.from(address);

return {
pending: processMap(executables.pending, fromAddress),
queued: processMap(origins, fromAddress)
};
}

/**
* 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.
*
Expand Down
8 changes: 7 additions & 1 deletion src/chains/ethereum/ethereum/src/transaction-pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { EthereumInternalOptions } from "@ganache/ethereum-options";
import { Executables } from "./miner/executables";
import { TypedTransaction } from "@ganache/ethereum-transaction";
import { Ethereum } from "./api-types";
import { Address } from "@ganache/ethereum-address";

/**
* Checks if the `replacer` is eligible to replace the `replacee` transaction
Expand Down Expand Up @@ -454,7 +455,7 @@ export default class TransactionPool extends Emittery<{ drain: undefined }> {
return null;
}

public processMap(map: Map<string, Heap<TypedTransaction>>) {
public processMap(map: Map<string, Heap<TypedTransaction>>, address?: Address) {
let res: Record<
string,
Record<string, Ethereum.Pool.Transaction<"private">>
Expand All @@ -463,6 +464,11 @@ export default class TransactionPool extends Emittery<{ drain: undefined }> {
for (let [_, { array, length }] of map) {
for (let i = 0; i < length; ++i) {
const transaction = array[i];

if(address && transaction.from.toString() != address.toString()) {
continue;
}

const from = transaction.from.toString();
if (res[from] === undefined) {
res[from] = {};
Expand Down
58 changes: 58 additions & 0 deletions src/chains/ethereum/ethereum/tests/api/txpool/txpool.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,64 @@ describe("txpool", () => {
});
});

describe("contentFrom", () => {
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_contentFrom", [accounts[1]]);

const pendingAddresses = Object.keys(pending);
const queuedAddresses = Object.keys(queued);

assert(pendingAddresses.findIndex((value) => value === accounts[1]) == 0)
assert(pendingAddresses.findIndex((value) => value === accounts[2]) == -1)
assert(pendingAddresses.length == 1)

assert(queuedAddresses.findIndex((value) => value === accounts[1]) == 0)
assert(queuedAddresses.findIndex((value) => value === accounts[2]) == -1)
assert(queuedAddresses.length == 1)
})
})

describe("status", () => {
let provider: EthereumProvider;
let accounts: string[];
Expand Down

0 comments on commit 3843ec2

Please sign in to comment.