From cce546965aaa343346bc01b6cde964397011d800 Mon Sep 17 00:00:00 2001 From: David Murdoch <187813+davidmurdoch@users.noreply.github.com> Date: Wed, 27 Jul 2022 17:04:59 -0400 Subject: [PATCH 01/10] test: make bundle-size-check test run on external contributor PRs (#3408) --- .github/workflows/pr.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 2c2c51e78e..469fa60851 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -63,4 +63,6 @@ jobs: echo "Bundle size is $([[ "$size" -lt 99000000 ]] && echo "ok" || echo "not ok")" && test "$size" -lt 99000000 env: - INFURA_KEY: ${{ secrets.INFURA_KEY }} + # use a fake infura key for the bundle size check so this test will + # run successfully on external contributor Pull Requests + INFURA_KEY: "badcode0deadcodebadcode0deadcode" From d48d998bd057a82b78c15ce197de06abc3487d2c Mon Sep 17 00:00:00 2001 From: Emil Bay Date: Thu, 28 Jul 2022 03:23:43 +0200 Subject: [PATCH 02/10] fix: correct signature of `eth_getWork` (#3349) --- src/chains/ethereum/ethereum/RPC-METHODS.md | 4 ---- src/chains/ethereum/ethereum/src/api.ts | 7 +++---- src/chains/ethereum/ethereum/tests/api/eth/eth.test.ts | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/chains/ethereum/ethereum/RPC-METHODS.md b/src/chains/ethereum/ethereum/RPC-METHODS.md index 1f38fa1326..461ea8e201 100644 --- a/src/chains/ethereum/ethereum/RPC-METHODS.md +++ b/src/chains/ethereum/ethereum/RPC-METHODS.md @@ -518,10 +518,6 @@ Returns: An Array with the following elements: 2. `DATA`, 32 Bytes - the seed hash used for the DAG. 3. `DATA`, 32 Bytes - the boundary condition ("target"), 2^256 / difficulty. -##### Arguments - -- `filterId: QUANTITY` : A filter id. - ##### Returns `Promise<[] | [string, string, string]>` : The hash of the current block, the seedHash, and the boundary condition to be met ("target"). diff --git a/src/chains/ethereum/ethereum/src/api.ts b/src/chains/ethereum/ethereum/src/api.ts index 72e286d632..8ca3a26d1c 100644 --- a/src/chains/ethereum/ethereum/src/api.ts +++ b/src/chains/ethereum/ethereum/src/api.ts @@ -1498,15 +1498,14 @@ export default class EthereumApi implements Api { * 2: `DATA`, 32 Bytes - the seed hash used for the DAG. * 3: `DATA`, 32 Bytes - the boundary condition ("target"), 2^256 / difficulty. * - * @param filterId - A filter id. * @returns The hash of the current block, the seedHash, and the boundary condition to be met ("target"). * @example * ```javascript - * console.log(await provider.send("eth_getWork", ["0x0"] )); + * console.log(await provider.send("eth_getWork", [] )); * ``` */ - @assertArgLength(1) - async eth_getWork(filterId: QUANTITY) { + @assertArgLength(0) + async eth_getWork() { return [] as [string, string, string] | []; } diff --git a/src/chains/ethereum/ethereum/tests/api/eth/eth.test.ts b/src/chains/ethereum/ethereum/tests/api/eth/eth.test.ts index 7a86015224..c2999c70a9 100644 --- a/src/chains/ethereum/ethereum/tests/api/eth/eth.test.ts +++ b/src/chains/ethereum/ethereum/tests/api/eth/eth.test.ts @@ -83,7 +83,7 @@ describe("api", () => { describe("eth_getWork", () => { it("should get compilers list", async () => { - const result = await provider.send("eth_getWork", ["0x0"]); + const result = await provider.send("eth_getWork"); assert.deepStrictEqual(result, []); }); }); From 16144b8c38f187a7c8b7dd0b97c154590ff5e148 Mon Sep 17 00:00:00 2001 From: Robert McLaughlin Date: Wed, 27 Jul 2022 18:28:08 -0700 Subject: [PATCH 03/10] fix: EIP-1559 access list transaction gas cost (#3227) EIP-1559 'Access List' transactions were not counting gas correctly. Up-front gas cost did not factor in the cost of of the access list itself. --- .../transaction/src/eip1559-fee-market-transaction.ts | 5 ++++- src/chains/ethereum/transaction/tests/index.test.ts | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) 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 3ad6e61dd1..60ce39d1a7 100644 --- a/src/chains/ethereum/transaction/src/eip1559-fee-market-transaction.ts +++ b/src/chains/ethereum/transaction/src/eip1559-fee-market-transaction.ts @@ -50,6 +50,7 @@ export class EIP1559FeeMarketTransaction extends RuntimeTransaction { public maxFeePerGas: Quantity; public accessList: AccessListBuffer; public accessListJSON: AccessList; + public accessListDataFee: bigint; public type: Quantity = Quantity.from("0x2"); public constructor( @@ -70,6 +71,7 @@ export class EIP1559FeeMarketTransaction extends RuntimeTransaction { const accessListData = AccessLists.getAccessListData(data[8]); this.accessList = accessListData.accessList; this.accessListJSON = accessListData.AccessListJSON; + this.accessListDataFee = accessListData.dataFeeEIP2930; this.v = Quantity.from(data[9]); this.r = Quantity.from(data[10]); this.s = Quantity.from(data[11]); @@ -107,6 +109,7 @@ export class EIP1559FeeMarketTransaction extends RuntimeTransaction { const accessListData = AccessLists.getAccessListData(data.accessList); this.accessList = accessListData.accessList; this.accessListJSON = accessListData.AccessListJSON; + this.accessListDataFee = accessListData.dataFeeEIP2930; this.validateAndSetSignature(data); } } @@ -177,7 +180,7 @@ export class EIP1559FeeMarketTransaction extends RuntimeTransaction { */ getBaseFee: () => { const fee = this.calculateIntrinsicGas(); - return new BN(Quantity.toBuffer(fee)); + return new BN(Quantity.toBuffer(fee + this.accessListDataFee)); }, getUpfrontCost: (baseFee: BN = new BN(0)) => { const { gas, maxPriorityFeePerGas, maxFeePerGas, value } = this; diff --git a/src/chains/ethereum/transaction/tests/index.test.ts b/src/chains/ethereum/transaction/tests/index.test.ts index 2467683e23..796856f45f 100644 --- a/src/chains/ethereum/transaction/tests/index.test.ts +++ b/src/chains/ethereum/transaction/tests/index.test.ts @@ -521,7 +521,7 @@ describe("@ganache/ethereum-transaction", async () => { ); }); it("has a function to get base fee", () => { - assert.strictEqual(vmTx.getBaseFee().toString(), "21000"); + assert.strictEqual(vmTx.getBaseFee().toString(), "25300"); }); it("has a function to get base upfront cost", () => { assert.strictEqual(vmTx.getUpfrontCost().toString(), "0"); From 701799fa0942346a5036f6ee3c34742f36320ecd Mon Sep 17 00:00:00 2001 From: David Murdoch <187813+davidmurdoch@users.noreply.github.com> Date: Wed, 27 Jul 2022 21:28:39 -0400 Subject: [PATCH 04/10] build: ensure webpack's `INFURA_KEY` is exactly 32 lowercase hex characters (#3409) --- src/packages/ganache/webpack/webpack.common.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/ganache/webpack/webpack.common.config.ts b/src/packages/ganache/webpack/webpack.common.config.ts index f07d4f9477..95a258328c 100644 --- a/src/packages/ganache/webpack/webpack.common.config.ts +++ b/src/packages/ganache/webpack/webpack.common.config.ts @@ -26,7 +26,7 @@ if ( // validate INFURA_KEY if (INFURA_KEY) { - if (!/[a-z0-9]{32}/.test(INFURA_KEY)) { + if (!/^[a-f0-9]{32}$/.test(INFURA_KEY)) { throw new Error( "INFURA_KEY must 32 characters long and contain only the characters a-f0-9" ); From bf711e64467a4b13d945f4ff0ae156cdcac669ad Mon Sep 17 00:00:00 2001 From: Ikko Ashimine Date: Thu, 28 Jul 2022 10:29:09 +0900 Subject: [PATCH 05/10] refactor: fix typo in promise-queue/index.ts (#3434) entrys -> entries --- src/packages/promise-queue/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/promise-queue/index.ts b/src/packages/promise-queue/index.ts index fa3d36f23d..56b1a5ec61 100644 --- a/src/packages/promise-queue/index.ts +++ b/src/packages/promise-queue/index.ts @@ -74,7 +74,7 @@ class PromiseQueue { * given value. */ clear(value: T) { - // remove all entrys from the queue and mark them. + // remove all entries from the queue and mark them. const cancelledQueue = this.#queue.splice(0); cancelledQueue.forEach(entry => { entry.queue = cancelledQueue; From 1ba2af5e7521a8ece82d1ef70c3f21189db989c7 Mon Sep 17 00:00:00 2001 From: David Murdoch <187813+davidmurdoch@users.noreply.github.com> Date: Thu, 28 Jul 2022 12:04:07 -0400 Subject: [PATCH 06/10] test: make bundle-size-check test work again (#3444) [This change](https://github.com/trufflesuite/ganache/commit/cce546965aaa343346bc01b6cde964397011d800) combined with [this one](https://github.com/trufflesuite/ganache/pull/3409) caused the bundle-size-check to fail for all PRs. --- .github/workflows/pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 469fa60851..1e3f464d9b 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -65,4 +65,4 @@ jobs: env: # use a fake infura key for the bundle size check so this test will # run successfully on external contributor Pull Requests - INFURA_KEY: "badcode0deadcodebadcode0deadcode" + INFURA_KEY: "badc0de0deadc0debadc0de0deadc0de" From 90b3f2b743974b13d23ec72e713350021655c6f9 Mon Sep 17 00:00:00 2001 From: Alex Sherbuck Date: Thu, 28 Jul 2022 14:10:45 -0500 Subject: [PATCH 07/10] test: correct webpack infura key validation error message grammar (#3443) --- src/packages/ganache/webpack/webpack.common.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/ganache/webpack/webpack.common.config.ts b/src/packages/ganache/webpack/webpack.common.config.ts index 95a258328c..7ba7a35c5e 100644 --- a/src/packages/ganache/webpack/webpack.common.config.ts +++ b/src/packages/ganache/webpack/webpack.common.config.ts @@ -28,7 +28,7 @@ if ( if (INFURA_KEY) { if (!/^[a-f0-9]{32}$/.test(INFURA_KEY)) { throw new Error( - "INFURA_KEY must 32 characters long and contain only the characters a-f0-9" + "INFURA_KEY must be 32 characters long and contain only the characters a-f0-9" ); } } From df29a09be2f2109fd4a7f4572c4a6dfaec2fa5d4 Mon Sep 17 00:00:00 2001 From: Micaiah Reid Date: Fri, 5 Aug 2022 15:48:57 -0400 Subject: [PATCH 08/10] fix: switch to user-provided logger rather than `console.log` (#3466) * use user-provided logger in blockchain.resume * use user-provided logger in ws-handler * remove unused dependency * pass logging instead of all options --- src/chains/ethereum/ethereum/src/blockchain.ts | 4 +++- .../src/forking/handlers/ws-handler.ts | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/chains/ethereum/ethereum/src/blockchain.ts b/src/chains/ethereum/ethereum/src/blockchain.ts index 0c720d37ef..dfa03cbe47 100644 --- a/src/chains/ethereum/ethereum/src/blockchain.ts +++ b/src/chains/ethereum/ethereum/src/blockchain.ts @@ -618,7 +618,9 @@ export default class Blockchain extends Emittery { resume(_threads: number = 1) { if (!this.#isPaused()) { - console.log("Warning: startMining called when miner was already started"); + this.#options.logging.logger.log( + "Warning: startMining called when miner was already started" + ); return; } diff --git a/src/chains/ethereum/ethereum/src/forking/handlers/ws-handler.ts b/src/chains/ethereum/ethereum/src/forking/handlers/ws-handler.ts index 55a2ff5414..5c49af15cc 100644 --- a/src/chains/ethereum/ethereum/src/forking/handlers/ws-handler.ts +++ b/src/chains/ethereum/ethereum/src/forking/handlers/ws-handler.ts @@ -1,5 +1,5 @@ import { EthereumInternalOptions } from "@ganache/ethereum-options"; -import { AbortError, CodedError } from "@ganache/ethereum-utils"; +import { AbortError } from "@ganache/ethereum-utils"; import { AbortSignal } from "abort-controller"; import WebSocket from "ws"; import { Handler } from "../types"; @@ -23,7 +23,10 @@ export class WsHandler extends BaseHandler implements Handler { constructor(options: EthereumInternalOptions, abortSignal: AbortSignal) { super(options, abortSignal); - const { url, origin } = options.fork; + const { + fork: { url, origin }, + logging + } = options; this.connection = new WebSocket(url.toString(), { origin, @@ -40,11 +43,11 @@ export class WsHandler extends BaseHandler implements Handler { // handler too. this.connection.binaryType = "nodebuffer"; - this.open = this.connect(this.connection); + this.open = this.connect(this.connection, logging); this.connection.onclose = () => { // try to connect again... // TODO: backoff and eventually fail - this.open = this.connect(this.connection); + this.open = this.connect(this.connection, logging); }; this.abortSignal.addEventListener("abort", () => { this.connection.onclose = null; @@ -98,7 +101,10 @@ export class WsHandler extends BaseHandler implements Handler { } } - private connect(connection: WebSocket) { + private connect( + connection: WebSocket, + logging: EthereumInternalOptions["logging"] + ) { let open = new Promise((resolve, reject) => { connection.onopen = resolve; connection.onerror = reject; @@ -109,7 +115,7 @@ export class WsHandler extends BaseHandler implements Handler { connection.onerror = null; }, err => { - console.log(err); + logging.logger.log(err); } ); return open; From 1592b1d1410f16f368f8d7a53640df54969d8e65 Mon Sep 17 00:00:00 2001 From: Leonard Ginters Date: Fri, 12 Aug 2022 00:16:49 +0200 Subject: [PATCH 09/10] test: replace `assert.equal` with `assert.strictEqual` in tests (#3508) * refactor(chains/ethereum/address): replace `assert.equal` with `assert.strictEqual` * refactor(chains/ethereum/ethereum): replace `assert.equal` with `assert.strictEqual` * refactor(chains/ethereum/options): replace `assert.equal` with `assert.strictEqual` * refactor(packages/utils): replace `assert.equal` with `assert.strictEqual` --- .../ethereum/address/tests/index.test.ts | 10 ++++----- .../ethereum/tests/blockchain.test.ts | 9 +++++--- .../ethereum/options/tests/index.test.ts | 4 ++-- .../utils/tests/json-rpc-data.test.ts | 8 +++---- .../utils/tests/json-rpc-quantity.test.ts | 21 ++++++++++++------- 5 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/chains/ethereum/address/tests/index.test.ts b/src/chains/ethereum/address/tests/index.test.ts index f2c786fa58..90ed8feecd 100644 --- a/src/chains/ethereum/address/tests/index.test.ts +++ b/src/chains/ethereum/address/tests/index.test.ts @@ -7,7 +7,7 @@ describe("@ganache/ethereum-address", () => { const address = new Address("0x1"); const stringifiedAddress = address.toString(); - assert.equal( + assert.strictEqual( stringifiedAddress, "0x0000000000000000000000000000000000000001" ); @@ -17,14 +17,14 @@ describe("@ganache/ethereum-address", () => { const address = new Address("0x1"); const stringifiedAddress = address.toString(1); - assert.equal(stringifiedAddress, "0x01"); + assert.strictEqual(stringifiedAddress, "0x01"); }); it("should stringify a 20 byte address string", () => { const address = new Address("0x2104859394604359378433865360947116707876"); const stringifiedAddress = address.toString(); - assert.equal( + assert.strictEqual( stringifiedAddress, "0x2104859394604359378433865360947116707876" ); @@ -33,7 +33,7 @@ describe("@ganache/ethereum-address", () => { it("should pad an address to 20 bytes when called as static function", () => { const stringifiedAddress = Address.toString("0x1"); - assert.equal( + assert.strictEqual( stringifiedAddress, "0x0000000000000000000000000000000000000001" ); @@ -54,7 +54,7 @@ describe("@ganache/ethereum-address", () => { const address = new Address("0x2104859394604359378433865360947116707876"); const stringifiedAddress = address.toString(1); - assert.equal(stringifiedAddress, "0x21"); + assert.strictEqual(stringifiedAddress, "0x21"); }); it("should convert a 20 byte address to a buffer", () => { diff --git a/src/chains/ethereum/ethereum/tests/blockchain.test.ts b/src/chains/ethereum/ethereum/tests/blockchain.test.ts index 0c36475c61..d8edbdd0e1 100644 --- a/src/chains/ethereum/ethereum/tests/blockchain.test.ts +++ b/src/chains/ethereum/ethereum/tests/blockchain.test.ts @@ -82,11 +82,14 @@ describe("blockchain", async () => { try { const blockNumber = block.header.number.toString(); const expectedBlockNumber = startingBlockNumber + i + 1; - assert.equal(blockNumber, `0x${expectedBlockNumber.toString(16)}`); - assert.equal(transactions.length, 1); + assert.strictEqual( + blockNumber, + `0x${expectedBlockNumber.toString(16)}` + ); + assert.strictEqual(transactions.length, 1); const transaction = transactions[0]; - assert.equal( + assert.strictEqual( transaction.hash.toString(), transactionHashes[i].toString() ); diff --git a/src/chains/ethereum/options/tests/index.test.ts b/src/chains/ethereum/options/tests/index.test.ts index d8b50773f1..fe5a2057ac 100644 --- a/src/chains/ethereum/options/tests/index.test.ts +++ b/src/chains/ethereum/options/tests/index.test.ts @@ -38,7 +38,7 @@ describe("EthereumOptionsConfig", () => { const options = EthereumOptionsConfig.normalize({ wallet: { totalAccounts: 7 } }); - assert.equal(options.wallet.totalAccounts, 7); + assert.strictEqual(options.wallet.totalAccounts, 7); }); it("throws an error when an option conflict is found", () => { assert.throws(() => { @@ -55,7 +55,7 @@ describe("EthereumOptionsConfig", () => { it("accepts some legacy input formats", () => { const seed = "from their voids, cry to the dolphined sea"; const options = EthereumOptionsConfig.normalize({ seed } as Object); - assert.equal(options.wallet.seed, seed); + assert.strictEqual(options.wallet.seed, seed); }); it("errors if there is a conflict with legacy inputs", () => { const seed = "I ate three cookies"; diff --git a/src/packages/utils/tests/json-rpc-data.test.ts b/src/packages/utils/tests/json-rpc-data.test.ts index b8f67ea735..80a5cee334 100644 --- a/src/packages/utils/tests/json-rpc-data.test.ts +++ b/src/packages/utils/tests/json-rpc-data.test.ts @@ -47,7 +47,7 @@ describe("json-rpc-data", () => { "hex" )}`, () => { const result = new Data(input).toString(); - assert.equal(result, expected); + assert.strictEqual(result, expected); }); }); @@ -55,12 +55,12 @@ describe("json-rpc-data", () => { const result = new Data( Buffer.from([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]) ).toString(1); - assert.equal(result, "0x01"); + assert.strictEqual(result, "0x01"); }); it("should pad to a longer byteLength", () => { const result = new Data(Buffer.from([0x01])).toString(10); - assert.equal(result, "0x00000000000000000001"); + assert.strictEqual(result, "0x00000000000000000001"); }); }); @@ -113,7 +113,7 @@ describe("json-rpc-data", () => { it("should return false for any non-empty buffer", () => { [Buffer.allocUnsafe(1), Buffer.allocUnsafe(2)].forEach(input => { const data = new Data(input); - assert.equal(data.isNull(), false); + assert.strictEqual(data.isNull(), false); }); }); }); diff --git a/src/packages/utils/tests/json-rpc-quantity.test.ts b/src/packages/utils/tests/json-rpc-quantity.test.ts index 6e1383114a..8dfeef74ee 100644 --- a/src/packages/utils/tests/json-rpc-quantity.test.ts +++ b/src/packages/utils/tests/json-rpc-quantity.test.ts @@ -14,7 +14,12 @@ const testData = [ 0x0123456789abcdef, Buffer.from([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]) ], - [Buffer.from([0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), "0x10000000000000", 0x10000000000000, Buffer.from([ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])] + [ + Buffer.from([0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), + "0x10000000000000", + 0x10000000000000, + Buffer.from([0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) + ] ]; const nullLikeInputs = [null, undefined, Buffer.alloc(0)]; @@ -70,14 +75,14 @@ describe("json-rpc-quantity", () => { it("should return 0x0 for a non-empty buffer of 0x00 bytes", () => { const result = new Quantity(Buffer.alloc(10), true).toString(); - assert.equal(result, "0x0"); + assert.strictEqual(result, "0x0"); }); it(`should return "0x0" for null-like inputs`, () => { nullLikeInputs.forEach(input => { const result = new Quantity(input, false).toString(); - assert.equal(result, "0x0"); + assert.strictEqual(result, "0x0"); }); }); @@ -88,7 +93,7 @@ describe("json-rpc-quantity", () => { [true, false].forEach(nullable => { const result = new Quantity(input, nullable).toString(); - assert.equal(result, expected); + assert.strictEqual(result, expected); }); }); }); @@ -106,14 +111,14 @@ describe("json-rpc-quantity", () => { it("should return null for empty input", () => { const result = new Quantity(Buffer.alloc(0), true).toNumber(); - assert.equal(result, null); + assert.strictEqual(result, null); }); it("should return 0 for null-like inputs", () => { nullLikeInputs.forEach(input => { const result = new Quantity(input, false).toNumber(); - assert.equal(result, 0); + assert.strictEqual(result, 0); }); }); @@ -124,7 +129,7 @@ describe("json-rpc-quantity", () => { [true, false].forEach(nullable => { const result = new Quantity(input, nullable).toNumber(); - assert.equal(result, expected); + assert.strictEqual(result, expected); }); }); }); @@ -182,7 +187,7 @@ describe("json-rpc-quantity", () => { [Buffer.alloc(1), Buffer.alloc(2)].forEach(input => { const quantity = new Quantity(input, nullable); - assert.equal(quantity.isNull(), false); + assert.strictEqual(quantity.isNull(), false); }); }); }); From 2cdf9bdc5ea3da5515f3a9beadb7b1449e68831b Mon Sep 17 00:00:00 2001 From: Alex Sherbuck Date: Mon, 15 Aug 2022 06:05:18 -0500 Subject: [PATCH 10/10] chore: remove unnecessary TODOs from api, update TODOs with issue numbers (#3472) --- src/chains/ethereum/ethereum/src/api.ts | 8 +++++--- src/chains/ethereum/ethereum/src/blockchain.ts | 1 + .../ethereum/ethereum/src/data-managers/block-manager.ts | 1 + .../ethereum/src/data-managers/blocklog-manager.ts | 1 + .../ethereum/src/forking/handlers/http-handler.ts | 2 ++ .../ethereum/ethereum/src/forking/handlers/ws-handler.ts | 4 ++++ .../src/forking/persistent-cache/persistent-cache.ts | 1 + .../ethereum/src/forking/rate-limiter/rate-limiter.ts | 5 ++--- src/chains/ethereum/ethereum/src/forking/trie.ts | 2 ++ src/chains/ethereum/transaction/src/base-transaction.ts | 1 + .../ethereum/transaction/src/transaction-factory.ts | 1 + src/packages/core/tests/server.test.ts | 1 + 12 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/chains/ethereum/ethereum/src/api.ts b/src/chains/ethereum/ethereum/src/api.ts index 8ca3a26d1c..20a04bc7d9 100644 --- a/src/chains/ethereum/ethereum/src/api.ts +++ b/src/chains/ethereum/ethereum/src/api.ts @@ -353,6 +353,7 @@ export default class EthereumApi implements Api { async evm_setAccountNonce(address: DATA, nonce: QUANTITY) { // TODO: the effect of this function could happen during a block mine operation, which would cause all sorts of // issues. We need to figure out a good way of timing this. + // Issue: https://github.com/trufflesuite/ganache/issues/1646 const buffer = Address.from(address).toBuffer(); const blockchain = this.#blockchain; const stateManager = blockchain.vm.stateManager; @@ -391,6 +392,7 @@ export default class EthereumApi implements Api { async evm_setAccountBalance(address: DATA, balance: QUANTITY) { // TODO: the effect of this function could happen during a block mine operation, which would cause all sorts of // issues. We need to figure out a good way of timing this. + // Issue: https://github.com/trufflesuite/ganache/issues/1646 const buffer = Address.from(address).toBuffer(); const blockchain = this.#blockchain; const stateManager = blockchain.vm.stateManager; @@ -429,6 +431,7 @@ export default class EthereumApi implements Api { async evm_setAccountCode(address: DATA, code: DATA) { // TODO: the effect of this function could happen during a block mine operation, which would cause all sorts of // issues. We need to figure out a good way of timing this. + // Issue: https://github.com/trufflesuite/ganache/issues/1646 const addressBuffer = Address.from(address).toBuffer(); const codeBuffer = Data.toBuffer(code); const blockchain = this.#blockchain; @@ -477,6 +480,7 @@ export default class EthereumApi implements Api { async evm_setAccountStorageAt(address: DATA, slot: DATA, value: DATA) { // TODO: the effect of this function could happen during a block mine operation, which would cause all sorts of // issues. We need to figure out a good way of timing this. + // Issue: https://github.com/trufflesuite/ganache/issues/1646 const addressBuffer = Address.from(address).toBuffer(); const slotBuffer = Data.toBuffer(slot); const valueBuffer = Data.toBuffer(value); @@ -866,7 +870,6 @@ export default class EthereumApi implements Api { //#region eth - // TODO: example doesn't return correct value /** * Generates and returns an estimate of how much gas is necessary to allow the * transaction to complete. The transaction will not be added to the @@ -2939,6 +2942,7 @@ export default class EthereumApi implements Api { } // TODO: example doesn't return correct value + // Issue: https://github.com/trufflesuite/ganache/issues/3203 /** * Attempts to replay the transaction as it was executed on the network and * return storage data given a starting key and max number of entries to return. @@ -3014,7 +3018,6 @@ export default class EthereumApi implements Api { return this.#wallet.addresses; } - // TODO: example doesn't return correct value /** * Generates a new account with private key. Returns the address of the new * account. @@ -3093,7 +3096,6 @@ export default class EthereumApi implements Api { return this.#wallet.lockAccount(address.toLowerCase()); } - // TODO: example doesn't return correct value /** * Unlocks the account for use. * diff --git a/src/chains/ethereum/ethereum/src/blockchain.ts b/src/chains/ethereum/ethereum/src/blockchain.ts index dfa03cbe47..1e35b9fa15 100644 --- a/src/chains/ethereum/ethereum/src/blockchain.ts +++ b/src/chains/ethereum/ethereum/src/blockchain.ts @@ -1209,6 +1209,7 @@ export default class Blockchain extends Emittery { // TODO: gas could go theoretically go over Number.MAX_SAFE_INTEGER. // (Ganache v2 didn't handle this possibility either, so it hasn't been // updated yet) + // Issue: https://github.com/trufflesuite/ganache/issues/3473 let gas = 0; const structLogs: Array = []; const TraceData = TraceDataFactory(); diff --git a/src/chains/ethereum/ethereum/src/data-managers/block-manager.ts b/src/chains/ethereum/ethereum/src/data-managers/block-manager.ts index 380ad30d4b..26b923b7d7 100644 --- a/src/chains/ethereum/ethereum/src/data-managers/block-manager.ts +++ b/src/chains/ethereum/ethereum/src/data-managers/block-manager.ts @@ -210,6 +210,7 @@ export default class BlockManager extends Manager { async getRawByBlockNumber(blockNumber: Quantity): Promise { // TODO(perf): make the block's raw fields accessible on latest/earliest/pending so // we don't have to fetch them from the db each time a block tag is used. + // Issue: https://github.com/trufflesuite/ganache/issues/3481 const fallback = this.#blockchain.fallback; const numBuf = blockNumber.toBuffer(); return this.getRaw(numBuf).then(block => { diff --git a/src/chains/ethereum/ethereum/src/data-managers/blocklog-manager.ts b/src/chains/ethereum/ethereum/src/data-managers/blocklog-manager.ts index 3f2a88b248..367e6ce172 100644 --- a/src/chains/ethereum/ethereum/src/data-managers/blocklog-manager.ts +++ b/src/chains/ethereum/ethereum/src/data-managers/blocklog-manager.ts @@ -65,6 +65,7 @@ export default class BlockLogManager extends Manager { blockLogsRange.forEach(blockLogs => { // TODO(perf): this loops over all addresses for every block. // Maybe make it loop only once? + // Issue: https://github.com/trufflesuite/ganache/issues/3482 if (blockLogs) filteredBlockLogs.push(...blockLogs.filter(addresses, topics)); }); diff --git a/src/chains/ethereum/ethereum/src/forking/handlers/http-handler.ts b/src/chains/ethereum/ethereum/src/forking/handlers/http-handler.ts index 6491c10088..61f6aefc19 100644 --- a/src/chains/ethereum/ethereum/src/forking/handlers/http-handler.ts +++ b/src/chains/ethereum/ethereum/src/forking/handlers/http-handler.ts @@ -2,6 +2,7 @@ import { EthereumInternalOptions } from "@ganache/ethereum-options"; import { JsonRpcResponse, JsonRpcError } from "@ganache/utils"; import { AbortError } from "@ganache/ethereum-utils"; // TODO: support http2 +// Issue: https://github.com/trufflesuite/ganache/issues/3474 import http, { RequestOptions, Agent as HttpAgent } from "http"; import https, { Agent as HttpsAgent } from "https"; import { AbortSignal } from "abort-controller"; @@ -138,6 +139,7 @@ export class HttpHandler extends BaseHandler implements Handler { } // TODO: handle invalid JSON (throws on parse)? + // Issue: https://github.com/trufflesuite/ganache/issues/3475 buffer.then(buffer => { try { deferred.resolve({ diff --git a/src/chains/ethereum/ethereum/src/forking/handlers/ws-handler.ts b/src/chains/ethereum/ethereum/src/forking/handlers/ws-handler.ts index 5c49af15cc..eca6f9e01a 100644 --- a/src/chains/ethereum/ethereum/src/forking/handlers/ws-handler.ts +++ b/src/chains/ethereum/ethereum/src/forking/handlers/ws-handler.ts @@ -46,7 +46,9 @@ export class WsHandler extends BaseHandler implements Handler { this.open = this.connect(this.connection, logging); this.connection.onclose = () => { // try to connect again... + // Issue: https://github.com/trufflesuite/ganache/issues/3476 // TODO: backoff and eventually fail + // Issue: https://github.com/trufflesuite/ganache/issues/3477 this.open = this.connect(this.connection, logging); }; this.abortSignal.addEventListener("abort", () => { @@ -76,6 +78,7 @@ export class WsHandler extends BaseHandler implements Handler { }>(); // TODO: timeout an in-flight request after some amount of time + // Issue: https://github.com/trufflesuite/ganache/issues/3478 this.inFlightRequests.set(messageId, deferred); this.connection.send(`${JSONRPC_PREFIX}${messageId},${key.slice(1)}`); @@ -92,6 +95,7 @@ export class WsHandler extends BaseHandler implements Handler { const raw = event.data as Buffer; // TODO: handle invalid JSON (throws on parse)? + // Issue: https://github.com/trufflesuite/ganache/issues/3479 const response = JSON.parse(raw) as JsonRpcResponse | JsonRpcError; const id = response.id; const prom = this.inFlightRequests.get(id); diff --git a/src/chains/ethereum/ethereum/src/forking/persistent-cache/persistent-cache.ts b/src/chains/ethereum/ethereum/src/forking/persistent-cache/persistent-cache.ts index 8ecaf7c29d..35c21d01a4 100644 --- a/src/chains/ethereum/ethereum/src/forking/persistent-cache/persistent-cache.ts +++ b/src/chains/ethereum/ethereum/src/forking/persistent-cache/persistent-cache.ts @@ -222,6 +222,7 @@ export class PersistentCache { // TODO(perf): we always re-save the targetBlock but could optimize to only // resave if it is needed. + // Issue: https://github.com/trufflesuite/ganache/issues/3485 atomicBatch.put(targetBlock.key, targetBlock.serialize()); await atomicBatch.write(); diff --git a/src/chains/ethereum/ethereum/src/forking/rate-limiter/rate-limiter.ts b/src/chains/ethereum/ethereum/src/forking/rate-limiter/rate-limiter.ts index 95a1cffd69..52e6a4abc2 100644 --- a/src/chains/ethereum/ethereum/src/forking/rate-limiter/rate-limiter.ts +++ b/src/chains/ethereum/ethereum/src/forking/rate-limiter/rate-limiter.ts @@ -4,9 +4,7 @@ import { AbortSignal } from "abort-controller"; import Semaphore from "semaphore"; import { LimitCounter } from "./limit-counter"; -type PromiseFn = ( - ...args: unknown[] -) => Promise<{ +type PromiseFn = (...args: unknown[]) => Promise<{ response: { result: any } | { error: { message: string; code: number } }; raw: T; }>; @@ -234,6 +232,7 @@ export default class RateLimiter { // a LIMIT_EXCEEDED error behave, otherwise we'll just send ALL // requests back to Infura simultaneously after their initial 30 // backoff_seconds have elapsed. + // Issue: https://github.com/trufflesuite/ganache/issues/3480 // // When we are *not* self-rate limited (meaning fork.rps isn't set) // we need to be able to go at full speed until we are, and THEN we diff --git a/src/chains/ethereum/ethereum/src/forking/trie.ts b/src/chains/ethereum/ethereum/src/forking/trie.ts index b809a54fb4..ecc9947022 100644 --- a/src/chains/ethereum/ethereum/src/forking/trie.ts +++ b/src/chains/ethereum/ethereum/src/forking/trie.ts @@ -121,6 +121,7 @@ export class ForkTrie extends GanacheTrie { // checking the database itself // TODO(perf): there is probably a better/faster way of doing this for the // common case. + // Issue: https://github.com/trufflesuite/ganache/issues/3483 const checkpoints = this.metadata.checkpoints; for (let i = checkpoints.length - 1; i >= 0; i--) { for (let [encodedKeyStr, value] of checkpoints[i].keyValueMap.entries()) { @@ -137,6 +138,7 @@ export class ForkTrie extends GanacheTrie { // TODO(perf): this is just going to be slow once we get lots of keys // because it just checks every single key we've ever deleted (before this // one). + // Issue: https://github.com/trufflesuite/ganache/issues/3484 const stream = this.metadata._leveldb.createReadStream({ lte: this.createDelKey(key), reverse: true diff --git a/src/chains/ethereum/transaction/src/base-transaction.ts b/src/chains/ethereum/transaction/src/base-transaction.ts index 819d3419aa..e8d89a2f26 100644 --- a/src/chains/ethereum/transaction/src/base-transaction.ts +++ b/src/chains/ethereum/transaction/src/base-transaction.ts @@ -47,6 +47,7 @@ export const calculateIntrinsicGas = ( // Make sure we don't exceed uint64 for all data combinations. // TODO: make sure these upper-bound checks are safe to remove, then // remove if so. + // Issue: https://github.com/trufflesuite/ganache/issues/3486 // NOTE: This is an upper-bounds limit ported from geth that doesn't // make sense for Ethereum, as exceeding the upper bound would require // something like 200+ Petabytes of data. diff --git a/src/chains/ethereum/transaction/src/transaction-factory.ts b/src/chains/ethereum/transaction/src/transaction-factory.ts index 9d815e3fa3..fa8a99b4c3 100644 --- a/src/chains/ethereum/transaction/src/transaction-factory.ts +++ b/src/chains/ethereum/transaction/src/transaction-factory.ts @@ -82,6 +82,7 @@ export class TransactionFactory { } else { // TODO: I believe this is unreachable with current architecture. // If 2718 is supported, so is 2930. + // Issue: https://github.com/trufflesuite/ganache/issues/3487 throw new CodedError( `EIP 2930 is not activated.`, JsonRpcErrorCode.INVALID_PARAMS diff --git a/src/packages/core/tests/server.test.ts b/src/packages/core/tests/server.test.ts index faa04585f8..09cab25b13 100644 --- a/src/packages/core/tests/server.test.ts +++ b/src/packages/core/tests/server.test.ts @@ -1607,6 +1607,7 @@ describe("server", () => { }); // TODO: actually handle backpressure! + // Issue: https://github.com/trufflesuite/ganache/issues/2790 it.skip("can handle backpressure", async () => { { // create tons of data to force websocket backpressure