From a89d9b565f2943a6f9138a059013051542b25718 Mon Sep 17 00:00:00 2001 From: nicholaspai Date: Mon, 14 Mar 2022 12:09:19 -0400 Subject: [PATCH 1/5] feat: Add stress tests to estimate max size of leafs that executed by functions with for-loops --- package.json | 1 + test/gas-analytics/HubPool.RootExecution.ts | 68 +++++++++++++++++-- .../SpokePool.RelayerRefundRootExecution.ts | 28 ++++++++ 3 files changed, 90 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index a4c047768..49d7734b9 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "test": "hardhat test", "test:report-gas": "REPORT_GAS=true hardhat test", "test:gas-analytics": "GAS_TEST_ENABLED=true hardhat test ./test/gas-analytics/*", + "test:all": "GAS_TEST_ENABLED=true REPORT_GAS=true yarn hardhat test", "prepublish": "yarn build" }, "dependencies": { diff --git a/test/gas-analytics/HubPool.RootExecution.ts b/test/gas-analytics/HubPool.RootExecution.ts index 234fb29cd..9a1b81b0d 100644 --- a/test/gas-analytics/HubPool.RootExecution.ts +++ b/test/gas-analytics/HubPool.RootExecution.ts @@ -11,6 +11,7 @@ require("dotenv").config(); let hubPool: Contract, timer: Contract, weth: Contract; let owner: SignerWithAddress, dataWorker: SignerWithAddress, liquidityProvider: SignerWithAddress; +let hubPoolChainId: number; // Associates an array of L1 tokens to sends refunds for to each chain ID. let l1Tokens: Contract[]; @@ -25,6 +26,7 @@ const SEND_AMOUNT = toBNWei("10"); const STARTING_LP_AMOUNT = SEND_AMOUNT.mul(100); // This should be >= `SEND_AMOUNT` otherwise some relays will revert because // the pool balance won't be sufficient to cover the relay. const LP_FEE = SEND_AMOUNT.div(toBN(10)); +const STRESS_TEST_L1_TOKEN_COUNT = 150; // Construct tree with REFUND_CHAIN_COUNT leaves, each containing REFUND_TOKEN_COUNT sends async function constructSimpleTree(_destinationChainIds: number[], _l1Tokens: Contract[]) { @@ -65,7 +67,7 @@ describe("Gas Analytics: HubPool Root Bundle Execution", function () { [owner, dataWorker, liquidityProvider] = await ethers.getSigners(); ({ hubPool, timer, weth } = await hubPoolFixture()); - const hubPoolChainId = Number(await hre.getChainId()); + hubPoolChainId = Number(await hre.getChainId()); // Seed data worker with bond tokens. await seedWallet(dataWorker, [], weth, consts.bondAmount.mul(10)); @@ -77,10 +79,6 @@ describe("Gas Analytics: HubPool Root Bundle Execution", function () { const _l1Token = await deployErc20(owner, `Test Token #${i}`, `T-${i}`); l1Tokens.push(_l1Token); - // Mint data worker amount of tokens needed to bond a new root - await seedWallet(dataWorker, [_l1Token], undefined, consts.bondAmount.mul(100)); - await _l1Token.connect(dataWorker).approve(hubPool.address, consts.maxUint256); - // Mint LP amount of tokens needed to cover relay await seedWallet(liquidityProvider, [_l1Token], undefined, STARTING_LP_AMOUNT); await enableTokensForLP(owner, hubPool, weth, [_l1Token]); @@ -190,7 +188,6 @@ describe("Gas Analytics: HubPool Root Bundle Execution", function () { const gasUsed = receipts.map((_receipt) => _receipt.gasUsed).reduce((x, y) => x.add(y)); console.log(`(average) executeRootBundle-gasUsed: ${gasUsed.div(REFUND_CHAIN_COUNT)}`); }); - it("Executing all leaves using multicall", async function () { await hubPool.connect(dataWorker).proposeRootBundle( destinationChainIds, // bundleEvaluationBlockNumbers used by bots to construct bundles. Length must equal the number of leafs. @@ -203,11 +200,68 @@ describe("Gas Analytics: HubPool Root Bundle Execution", function () { // Advance time so the request can be executed and execute the request. await timer.setCurrentTime(Number(await timer.getCurrentTime()) + consts.refundProposalLiveness + 1); const multicallData = leaves.map((leaf) => { - return hubPool.interface.encodeFunctionData("executeRootBundle", [leaf, tree.getHexProof(leaf)]); + return hubPool.interface.encodeFunctionData("executeRootBundle", [ + ...Object.values(leaf), + tree.getHexProof(leaf), + ]); }); const receipt = await (await hubPool.connect(dataWorker).multicall(multicallData)).wait(); console.log(`(average) executeRootBundle-gasUsed: ${receipt.gasUsed.div(REFUND_CHAIN_COUNT)}`); }); + it(`Stress Test: 1 leaf contains ${STRESS_TEST_L1_TOKEN_COUNT} L1 tokens with netSendAmounts > 0`, async function () { + // This test should inform the limit # of L1 tokens that we would allow a PoolRebalanceLeaf to contain to avoid + // publishing a leaf that is unexecutable due to the block gas limit. Note that this estimate is a bit contrived + // and likely an underestimate because we are relaying tokens via the MockAdapter, not an Adapter used for + // production. + + // Regarding the block limit, we should target a maximum of 30 million gas. Technically block's can support up + // to 30 million gas, with a target of 15 million. In practice, we should set the maximum number of L1 tokens + // allowed in one leaf to much lower than this limit fo 30 million. + const l1TokenAddresses = []; + for (let i = 0; i < STRESS_TEST_L1_TOKEN_COUNT; i++) { + const _l1Token = await deployErc20(owner, `Test Token #${i}`, `T-${i}`); + l1TokenAddresses.push(_l1Token.address); + + // Mint LP amount of tokens needed to cover relay + await seedWallet(liquidityProvider, [_l1Token], undefined, STARTING_LP_AMOUNT); + await enableTokensForLP(owner, hubPool, weth, [_l1Token]); + await _l1Token.connect(liquidityProvider).approve(hubPool.address, consts.maxUint256); + await hubPool.connect(liquidityProvider).addLiquidity(_l1Token.address, STARTING_LP_AMOUNT); + + // Whitelist token route from HubPool to dest. chain ID + await hubPool.whitelistRoute(hubPoolChainId, destinationChainIds[0], _l1Token.address, randomAddress(), true); + } + + // Add leaf to tree that contains enough L1 tokens that we can determine the limit after which the executeRoot + // will fail due to out of gas. + const bigLeaves = buildPoolRebalanceLeafs( + [destinationChainIds[0]], + [l1TokenAddresses], + [Array(STRESS_TEST_L1_TOKEN_COUNT).fill(toBNWei("0"))], + [Array(STRESS_TEST_L1_TOKEN_COUNT).fill(SEND_AMOUNT)], + [Array(STRESS_TEST_L1_TOKEN_COUNT).fill(SEND_AMOUNT)] + ); + const bigLeafTree = await buildPoolRebalanceLeafTree(bigLeaves); + + await hubPool + .connect(dataWorker) + .proposeRootBundle( + [consts.mockBundleEvaluationBlockNumbers[0]], + 1, + bigLeafTree.getHexRoot(), + consts.mockRelayerRefundRoot, + consts.mockSlowRelayRoot + ); + + // Advance time so the request can be executed and execute the request. + await timer.setCurrentTime(Number(await timer.getCurrentTime()) + consts.refundProposalLiveness + 1); + const txn = await hubPool + .connect(dataWorker) + .executeRootBundle(...Object.values(bigLeaves[0]), bigLeafTree.getHexProof(bigLeaves[0])); + + const receipt = await txn.wait(); + console.log(`executeRootBundle-gasUsed: ${receipt.gasUsed}`); + }); }); }); diff --git a/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts b/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts index 848843641..6cc41e09a 100644 --- a/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts +++ b/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts @@ -32,6 +32,7 @@ let tree: MerkleTree; const REFUND_LEAF_COUNT = 10; const REFUNDS_PER_LEAF = 10; const REFUND_AMOUNT = toBNWei("10"); +const STRESS_TEST_REFUND_COUNT = 500; // Construct tree with REFUND_LEAF_COUNT leaves, each containing REFUNDS_PER_LEAF refunds. async function constructSimpleTree( @@ -244,5 +245,32 @@ describe("Gas Analytics: SpokePool Relayer Refund Root Execution", function () { const receipt = await txn.wait(); console.log(`executeRelayerRefundRoot-gasUsed: ${receipt.gasUsed}`); }); + it(`Stress Test: 1 leaf contains ${STRESS_TEST_REFUND_COUNT} refunds with amount > 0`, async function () { + // This test should inform the limit # refunds that we would allow a RelayerRefundLeaf to contain to avoid + // publishing a leaf that is unexecutable due to the block gas limit. + + // Regarding the block limit, we should target a maximum of 30 million gas. Technically block's can support up + // to 30 million gas, with a target of 15 million. In practice, we should set the maximum number of L1 tokens + // allowed in one leaf to much lower than this limit fo 30 million. + await seedContract(spokePool, owner, [], weth, toBN(STRESS_TEST_REFUND_COUNT).mul(REFUND_AMOUNT).mul(toBN(5))); + + // Create tree with 1 large leaf. + const bigLeaves = buildRelayerRefundLeafs( + [destinationChainIds[0]], + [toBNWei("1")], + [weth.address], + [Array(STRESS_TEST_REFUND_COUNT).fill(recipient.address)], + [Array(STRESS_TEST_REFUND_COUNT).fill(REFUND_AMOUNT)] + ); + const bigLeafTree = await buildRelayerRefundTree(bigLeaves); + + await spokePool.connect(dataWorker).relayRootBundle(bigLeafTree.getHexRoot(), consts.mockSlowRelayRoot); + const txn = await spokePool + .connect(dataWorker) + .executeRelayerRefundRoot(1, bigLeaves[0], bigLeafTree.getHexProof(bigLeaves[0])); + + const receipt = await txn.wait(); + console.log(`executeRelayerRefundRoot-gasUsed: ${receipt.gasUsed}`); + }); }); }); From 57713c4aa4cac3300fc04f10da40324697cc693d Mon Sep 17 00:00:00 2001 From: nicholaspai Date: Thu, 17 Mar 2022 14:32:44 -0400 Subject: [PATCH 2/5] Add limits + language --- test/gas-analytics/HubPool.RootExecution.ts | 36 +++++++++++++----- .../SpokePool.RelayerRefundRootExecution.ts | 38 +++++++++++++++---- 2 files changed, 58 insertions(+), 16 deletions(-) diff --git a/test/gas-analytics/HubPool.RootExecution.ts b/test/gas-analytics/HubPool.RootExecution.ts index 1d5f3f4dc..d1d3c24a6 100644 --- a/test/gas-analytics/HubPool.RootExecution.ts +++ b/test/gas-analytics/HubPool.RootExecution.ts @@ -1,4 +1,4 @@ -import { toBNWei, toBN, SignerWithAddress, seedWallet, Contract, ethers, hre } from "../utils"; +import { toBNWei, toBN, SignerWithAddress, seedWallet, Contract, ethers, hre, expect } from "../utils"; import { getContractFactory, BigNumber, randomAddress, createRandomBytes32 } from "../utils"; import { deployErc20 } from "./utils"; import * as consts from "../constants"; @@ -26,7 +26,13 @@ const SEND_AMOUNT = toBNWei("10"); const STARTING_LP_AMOUNT = SEND_AMOUNT.mul(100); // This should be >= `SEND_AMOUNT` otherwise some relays will revert because // the pool balance won't be sufficient to cover the relay. const LP_FEE = SEND_AMOUNT.div(toBN(10)); -const STRESS_TEST_L1_TOKEN_COUNT = 150; +// Regarding the block limit, the max limit is 30 million gas, the expected block gas limit is 15 million, so +// we'll target 12 million gas as a conservative upper-bound. This test script will fail if executing a leaf with +// `STRESS_TEST_L1_TOKEN_COUNT` number of tokens to send pool rebalances for is not within the +// [TARGET_GAS_LOWER_BOUND, TARGET_GAS_UPPER_BOUND] gas usage range. +const TARGET_GAS_UPPER_BOUND = 12_000_000; +const TARGET_GAS_LOWER_BOUND = 10_000_000; +const STRESS_TEST_L1_TOKEN_COUNT = 100; // Construct tree with REFUND_CHAIN_COUNT leaves, each containing REFUND_TOKEN_COUNT sends async function constructSimpleTree(_destinationChainIds: number[], _l1Tokens: Contract[]) { @@ -215,9 +221,8 @@ describe("Gas Analytics: HubPool Root Bundle Execution", function () { // and likely an underestimate because we are relaying tokens via the MockAdapter, not an Adapter used for // production. - // Regarding the block limit, we should target a maximum of 30 million gas. Technically block's can support up - // to 30 million gas, with a target of 15 million. In practice, we should set the maximum number of L1 tokens - // allowed in one leaf to much lower than this limit fo 30 million. + // Regarding the block limit, the max limit is 30 million gas, the expected block gas limit is 15 million, so + // we'll target 12 million gas as a conservative upper-bound. const l1TokenAddresses = []; for (let i = 0; i < STRESS_TEST_L1_TOKEN_COUNT; i++) { const _l1Token = await deployErc20(owner, `Test Token #${i}`, `T-${i}`); @@ -229,8 +234,8 @@ describe("Gas Analytics: HubPool Root Bundle Execution", function () { await _l1Token.connect(liquidityProvider).approve(hubPool.address, consts.maxUint256); await hubPool.connect(liquidityProvider).addLiquidity(_l1Token.address, STARTING_LP_AMOUNT); - // Whitelist token route from HubPool to dest. chain ID - await hubPool.whitelistRoute(hubPoolChainId, destinationChainIds[0], _l1Token.address, randomAddress(), true); + // Whitelist token route from HubPool to dest. chain ID. Destination token doesn't matter for this test. + await hubPool.setPoolRebalanceRoute(destinationChainIds[0], _l1Token.address, randomAddress()); } // Add leaf to tree that contains enough L1 tokens that we can determine the limit after which the executeRoot @@ -240,7 +245,8 @@ describe("Gas Analytics: HubPool Root Bundle Execution", function () { [l1TokenAddresses], [Array(STRESS_TEST_L1_TOKEN_COUNT).fill(toBNWei("0"))], [Array(STRESS_TEST_L1_TOKEN_COUNT).fill(SEND_AMOUNT)], - [Array(STRESS_TEST_L1_TOKEN_COUNT).fill(SEND_AMOUNT)] + [Array(STRESS_TEST_L1_TOKEN_COUNT).fill(SEND_AMOUNT)], + [0] ); const bigLeafTree = await buildPoolRebalanceLeafTree(bigLeaves); @@ -256,12 +262,24 @@ describe("Gas Analytics: HubPool Root Bundle Execution", function () { // Advance time so the request can be executed and execute the request. await timer.setCurrentTime(Number(await timer.getCurrentTime()) + consts.refundProposalLiveness + 1); + + // Estimate the transaction gas and set it (plus some buffer) explicitly as the transaction's gas limit. This is + // done because ethers.js' default gas limit setting doesn't seem to always work and sometimes overestimates + // it and throws something like: + // "InvalidInputError: Transaction gas limit is X and exceeds block gas limit of 30000000" + const gasEstimate = await hubPool + .connect(dataWorker) + .estimateGas.executeRootBundle(...Object.values(bigLeaves[0]), bigLeafTree.getHexProof(bigLeaves[0])); const txn = await hubPool .connect(dataWorker) - .executeRootBundle(...Object.values(bigLeaves[0]), bigLeafTree.getHexProof(bigLeaves[0])); + .executeRootBundle(...Object.values(bigLeaves[0]), bigLeafTree.getHexProof(bigLeaves[0]), { + gasLimit: gasEstimate.mul(toBN("1.2")), + }); const receipt = await txn.wait(); console.log(`executeRootBundle-gasUsed: ${receipt.gasUsed}`); + expect(Number(receipt.gasUsed)).to.be.lessThanOrEqual(TARGET_GAS_UPPER_BOUND); + expect(Number(receipt.gasUsed)).to.be.greaterThanOrEqual(TARGET_GAS_LOWER_BOUND); }); }); }); diff --git a/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts b/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts index 6cc41e09a..1f98dbf4e 100644 --- a/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts +++ b/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts @@ -32,7 +32,15 @@ let tree: MerkleTree; const REFUND_LEAF_COUNT = 10; const REFUNDS_PER_LEAF = 10; const REFUND_AMOUNT = toBNWei("10"); -const STRESS_TEST_REFUND_COUNT = 500; +// Regarding the block limit, the max limit is 30 million gas, the expected block gas limit is 15 million, so +// we'll target 12 million gas as a conservative upper-bound. This test script will fail if executing a leaf with +// `STRESS_TEST_REFUND_COUNT` number of refunds is not within the [TARGET_GAS_LOWER_BOUND, TARGET_GAS_UPPER_BOUND] +// gas usage range. +const TARGET_GAS_UPPER_BOUND = 12_000_000; +const TARGET_GAS_LOWER_BOUND = 6_000_000; +// Note: I can't get this to work with a gas > 8mil without the transaction timing out. This is why I've set +// the lower bound to 6mil instead of a tighter 10mil. +const STRESS_TEST_REFUND_COUNT = 1000; // Construct tree with REFUND_LEAF_COUNT leaves, each containing REFUNDS_PER_LEAF refunds. async function constructSimpleTree( @@ -249,15 +257,19 @@ describe("Gas Analytics: SpokePool Relayer Refund Root Execution", function () { // This test should inform the limit # refunds that we would allow a RelayerRefundLeaf to contain to avoid // publishing a leaf that is unexecutable due to the block gas limit. - // Regarding the block limit, we should target a maximum of 30 million gas. Technically block's can support up - // to 30 million gas, with a target of 15 million. In practice, we should set the maximum number of L1 tokens - // allowed in one leaf to much lower than this limit fo 30 million. - await seedContract(spokePool, owner, [], weth, toBN(STRESS_TEST_REFUND_COUNT).mul(REFUND_AMOUNT).mul(toBN(5))); + // Note: Since the SpokePool is deployed on L2s we care specifically about L2 block gas limits. + // - Optimism: same as L1 + // - Arbitrum: TODO + // - Polygon: same as L1 + + // Regarding the block limit, the max limit is 30 million gas, the expected block gas limit is 15 million, so + // we'll target 12 million gas as a conservative upper-bound. + await seedContract(spokePool, owner, [], weth, toBN(STRESS_TEST_REFUND_COUNT).mul(REFUND_AMOUNT).mul(toBN(10))); // Create tree with 1 large leaf. const bigLeaves = buildRelayerRefundLeafs( [destinationChainIds[0]], - [toBNWei("1")], + [toBNWei("1")], // Set amount to return > 0 to better simulate long execution path of _executeRelayerRefundLeaf [weth.address], [Array(STRESS_TEST_REFUND_COUNT).fill(recipient.address)], [Array(STRESS_TEST_REFUND_COUNT).fill(REFUND_AMOUNT)] @@ -265,12 +277,24 @@ describe("Gas Analytics: SpokePool Relayer Refund Root Execution", function () { const bigLeafTree = await buildRelayerRefundTree(bigLeaves); await spokePool.connect(dataWorker).relayRootBundle(bigLeafTree.getHexRoot(), consts.mockSlowRelayRoot); + + // Estimate the transaction gas and set it (plus some buffer) explicitly as the transaction's gas limit. This is + // done because ethers.js' default gas limit setting doesn't seem to always work and sometimes overestimates + // it and throws something like: + // "InvalidInputError: Transaction gas limit is X and exceeds block gas limit of 30000000" + const gasEstimate = await spokePool + .connect(dataWorker) + .estimateGas.executeRelayerRefundRoot(1, bigLeaves[0], bigLeafTree.getHexProof(bigLeaves[0])); const txn = await spokePool .connect(dataWorker) - .executeRelayerRefundRoot(1, bigLeaves[0], bigLeafTree.getHexProof(bigLeaves[0])); + .executeRelayerRefundRoot(1, bigLeaves[0], bigLeafTree.getHexProof(bigLeaves[0]), { + gasLimit: gasEstimate.mul(toBN("1.2")), + }); const receipt = await txn.wait(); console.log(`executeRelayerRefundRoot-gasUsed: ${receipt.gasUsed}`); + expect(Number(receipt.gasUsed)).to.be.lessThanOrEqual(TARGET_GAS_UPPER_BOUND); + expect(Number(receipt.gasUsed)).to.be.greaterThanOrEqual(TARGET_GAS_LOWER_BOUND); }); }); }); From 6f0617891c5425ff33ea08c928fa8ec7eb4a2f72 Mon Sep 17 00:00:00 2001 From: nicholaspai Date: Thu, 17 Mar 2022 14:35:37 -0400 Subject: [PATCH 3/5] Update SpokePool.RelayerRefundRootExecution.ts --- test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts b/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts index 1f98dbf4e..631d6d095 100644 --- a/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts +++ b/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts @@ -258,8 +258,10 @@ describe("Gas Analytics: SpokePool Relayer Refund Root Execution", function () { // publishing a leaf that is unexecutable due to the block gas limit. // Note: Since the SpokePool is deployed on L2s we care specifically about L2 block gas limits. - // - Optimism: same as L1 - // - Arbitrum: TODO + // - Optimism: 15mil cap, soon to be raised to 30mil when they upgrade to London. + // - Arbitrum: uses different units when reasoning about gas (but with the nitro upgrade those will then be + // closer to Ethereum). You can do about the same amount of computation per second on the chain; each + // transaction can use up to 2.5m arbgas in computation. // - Polygon: same as L1 // Regarding the block limit, the max limit is 30 million gas, the expected block gas limit is 15 million, so From a6db7ad5ac06bfef1f8318fec85ff2486df33ffa Mon Sep 17 00:00:00 2001 From: nicholaspai Date: Thu, 17 Mar 2022 17:16:47 -0400 Subject: [PATCH 4/5] Update SpokePool.RelayerRefundRootExecution.ts --- test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts b/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts index 631d6d095..abb54924f 100644 --- a/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts +++ b/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts @@ -37,10 +37,10 @@ const REFUND_AMOUNT = toBNWei("10"); // `STRESS_TEST_REFUND_COUNT` number of refunds is not within the [TARGET_GAS_LOWER_BOUND, TARGET_GAS_UPPER_BOUND] // gas usage range. const TARGET_GAS_UPPER_BOUND = 12_000_000; -const TARGET_GAS_LOWER_BOUND = 6_000_000; -// Note: I can't get this to work with a gas > 8mil without the transaction timing out. This is why I've set +const TARGET_GAS_LOWER_BOUND = 5_000_000; +// Note: I can't get this to work with a gas >> 5mil without the transaction timing out. This is why I've set // the lower bound to 6mil instead of a tighter 10mil. -const STRESS_TEST_REFUND_COUNT = 1000; +const STRESS_TEST_REFUND_COUNT = 600; // Construct tree with REFUND_LEAF_COUNT leaves, each containing REFUNDS_PER_LEAF refunds. async function constructSimpleTree( From ca27c3239101b3b28e0dacd7cd8f983751bf8489 Mon Sep 17 00:00:00 2001 From: nicholaspai Date: Thu, 17 Mar 2022 17:18:18 -0400 Subject: [PATCH 5/5] Update SpokePool.RelayerRefundRootExecution.ts --- test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts b/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts index abb54924f..ba34843e1 100644 --- a/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts +++ b/test/gas-analytics/SpokePool.RelayerRefundRootExecution.ts @@ -40,7 +40,7 @@ const TARGET_GAS_UPPER_BOUND = 12_000_000; const TARGET_GAS_LOWER_BOUND = 5_000_000; // Note: I can't get this to work with a gas >> 5mil without the transaction timing out. This is why I've set // the lower bound to 6mil instead of a tighter 10mil. -const STRESS_TEST_REFUND_COUNT = 600; +const STRESS_TEST_REFUND_COUNT = 800; // Construct tree with REFUND_LEAF_COUNT leaves, each containing REFUNDS_PER_LEAF refunds. async function constructSimpleTree(