From f06c0342f18ed61ea958a4dbd92b9f27f3df6a00 Mon Sep 17 00:00:00 2001 From: David Murdoch <187813+davidmurdoch@users.noreply.github.com> Date: Fri, 3 Dec 2021 13:34:48 -0500 Subject: [PATCH] fix: ensure `eth_sendTransaction` returns the correct error when the account has insufficient funds (#1661) --- .../tests/api/eth/sendTransaction.test.ts | 24 +++++++++++++++++++ .../src/eip1559-fee-market-transaction.ts | 8 +++++-- .../src/eip2930-access-list-transaction.ts | 6 ++++- .../transaction/src/legacy-transaction.ts | 8 +++++-- 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/chains/ethereum/ethereum/tests/api/eth/sendTransaction.test.ts b/src/chains/ethereum/ethereum/tests/api/eth/sendTransaction.test.ts index 9805869ce1..afdb8d6e71 100644 --- a/src/chains/ethereum/ethereum/tests/api/eth/sendTransaction.test.ts +++ b/src/chains/ethereum/ethereum/tests/api/eth/sendTransaction.test.ts @@ -46,6 +46,30 @@ describe("api", () => { }); }); + describe("insufficient funds", () => { + it("returns an error when account has insufficient funds to send the transaction", async () => { + const p = await getProvider({ + miner: { legacyInstamine: true }, + chain: { vmErrorsOnRPCResponse: true } + }); + const [from, to] = await p.send("eth_accounts"); + const balance = await p.send("eth_getBalance", [from]); + const types = ["0x0", "0x1", "0x2"] as const; + for (let i = 0; i < types.length; i++) { + await assert.rejects( + p.send("eth_sendTransaction", [ + { type: types[i], from, to, value: balance } + ]), + new RegExp( + `VM Exception while processing transaction: sender doesn't have enough funds to send tx\\. The upfront cost is: \\d+ and the sender's account \\(${from}\\) only has: ${BigInt( + balance + )} \\(vm hf=london -> block -> tx\\)` + ) + ); + } + }); + }); + describe("contracts", () => { const contractDir = join(__dirname, "contracts"); describe("out of gas", () => { diff --git a/src/chains/ethereum/transaction/src/eip1559-fee-market-transaction.ts b/src/chains/ethereum/transaction/src/eip1559-fee-market-transaction.ts index 4a257966c8..977ab03e6d 100644 --- a/src/chains/ethereum/transaction/src/eip1559-fee-market-transaction.ts +++ b/src/chains/ethereum/transaction/src/eip1559-fee-market-transaction.ts @@ -151,7 +151,8 @@ export class EIP1559FeeMarketTransaction extends RuntimeTransaction { } public toVmTransaction() { - const sender = this.from.toBuffer(); + const from = this.from; + const sender = from.toBuffer(); const to = this.to.toBuffer(); const data = this.data.toBuffer(); return { @@ -169,7 +170,10 @@ export class EIP1559FeeMarketTransaction extends RuntimeTransaction { AccessListJSON: this.accessListJSON, getSenderAddress: () => ({ buf: sender, - equals: (a: { buf: Buffer }) => sender.equals(a.buf) + equals: (a: { buf: Buffer }) => sender.equals(a.buf), + toString() { + return from.toString(); + } }), /** * the minimum amount of gas the tx must have (DataFee + TxFee + Creation Fee) diff --git a/src/chains/ethereum/transaction/src/eip2930-access-list-transaction.ts b/src/chains/ethereum/transaction/src/eip2930-access-list-transaction.ts index 21ec309857..8faac4101a 100644 --- a/src/chains/ethereum/transaction/src/eip2930-access-list-transaction.ts +++ b/src/chains/ethereum/transaction/src/eip2930-access-list-transaction.ts @@ -153,6 +153,7 @@ export class EIP2930AccessListTransaction extends RuntimeTransaction { } public toVmTransaction() { + const from = this.from; const sender = this.from.toBuffer(); const to = this.to.toBuffer(); const data = this.data.toBuffer(); @@ -170,7 +171,10 @@ export class EIP2930AccessListTransaction extends RuntimeTransaction { AccessListJSON: this.accessListJSON, getSenderAddress: () => ({ buf: sender, - equals: (a: { buf: Buffer }) => sender.equals(a.buf) + equals: (a: { buf: Buffer }) => sender.equals(a.buf), + toString() { + return from.toString(); + } }), /** * the minimum amount of gas the tx must have (DataFee + TxFee + Creation Fee) diff --git a/src/chains/ethereum/transaction/src/legacy-transaction.ts b/src/chains/ethereum/transaction/src/legacy-transaction.ts index 76273aa1d8..02798d7735 100644 --- a/src/chains/ethereum/transaction/src/legacy-transaction.ts +++ b/src/chains/ethereum/transaction/src/legacy-transaction.ts @@ -115,7 +115,8 @@ export class LegacyTransaction extends RuntimeTransaction { return new LegacyTransaction(data, common); } public toVmTransaction() { - const sender = this.from.toBuffer(); + const from = this.from; + const sender = from.toBuffer(); const to = this.to.toBuffer(); const data = this.data.toBuffer(); return { @@ -131,7 +132,10 @@ export class LegacyTransaction extends RuntimeTransaction { data, getSenderAddress: () => ({ buf: sender, - equals: (a: { buf: Buffer }) => sender.equals(a.buf) + equals: (a: { buf: Buffer }) => sender.equals(a.buf), + toString() { + return from.toString(); + } }), /** * the minimum amount of gas the tx must have (DataFee + TxFee + Creation Fee)