diff --git a/.changeset/weak-apricots-guess.md b/.changeset/weak-apricots-guess.md new file mode 100644 index 00000000000..9ba3a5250d4 --- /dev/null +++ b/.changeset/weak-apricots-guess.md @@ -0,0 +1,8 @@ +--- +"@nomicfoundation/ignition-core": patch +"@nomicfoundation/hardhat-ignition-ethers": patch +"@nomicfoundation/hardhat-ignition-viem": patch +"@nomicfoundation/hardhat-ignition": patch +--- + +Expose ignition retry loop variables in user config (Hardhat v3) ([#7303](https://github.com/NomicFoundation/hardhat/issues/7303)) diff --git a/v-next/hardhat-ignition-core/src/deploy.ts b/v-next/hardhat-ignition-core/src/deploy.ts index a253d19116c..87c6a765f14 100644 --- a/v-next/hardhat-ignition-core/src/deploy.ts +++ b/v-next/hardhat-ignition-core/src/deploy.ts @@ -54,6 +54,8 @@ export async function deploy< maxPriorityFeePerGas, gasPrice, disableFeeBumping, + maxRetries, + retryInterval, }: { config?: Partial; artifactResolver: ArtifactResolver; @@ -74,6 +76,8 @@ export async function deploy< maxPriorityFeePerGas?: bigint; gasPrice?: bigint; disableFeeBumping?: boolean; + maxRetries?: number; + retryInterval?: number; }): Promise { const executionStrategy: ExecutionStrategy = resolveStrategy( strategy, @@ -131,6 +135,8 @@ export async function deploy< ? DEFAULT_AUTOMINE_REQUIRED_CONFIRMATIONS : config.requiredConfirmations ?? defaultConfig.requiredConfirmations, disableFeeBumping: disableFeeBumping ?? defaultConfig.disableFeeBumping, + maxRetries: maxRetries ?? defaultConfig.maxRetries, + retryInterval: retryInterval ?? defaultConfig.retryInterval, ...config, }; diff --git a/v-next/hardhat-ignition-core/src/internal/defaultConfig.ts b/v-next/hardhat-ignition-core/src/internal/defaultConfig.ts index e8de4d4b9e9..7b4c15b64de 100644 --- a/v-next/hardhat-ignition-core/src/internal/defaultConfig.ts +++ b/v-next/hardhat-ignition-core/src/internal/defaultConfig.ts @@ -9,6 +9,8 @@ export const defaultConfig: DeployConfig = { maxFeeBumps: 4, requiredConfirmations: 5, disableFeeBumping: false, + maxRetries: 10, + retryInterval: 1_000, }; /** diff --git a/v-next/hardhat-ignition-core/src/internal/deployer.ts b/v-next/hardhat-ignition-core/src/internal/deployer.ts index ce984972bea..646b87a67cf 100644 --- a/v-next/hardhat-ignition-core/src/internal/deployer.ts +++ b/v-next/hardhat-ignition-core/src/internal/deployer.ts @@ -193,6 +193,8 @@ export class Deployer { this._config.maxFeeBumps, this._config.blockPollingInterval, this._config.disableFeeBumping, + this._config.maxRetries, + this._config.retryInterval, ); deploymentState = await executionEngine.executeModule( diff --git a/v-next/hardhat-ignition-core/src/internal/execution/execution-engine.ts b/v-next/hardhat-ignition-core/src/internal/execution/execution-engine.ts index 018f8dde08e..54ddc332a05 100644 --- a/v-next/hardhat-ignition-core/src/internal/execution/execution-engine.ts +++ b/v-next/hardhat-ignition-core/src/internal/execution/execution-engine.ts @@ -48,6 +48,8 @@ export class ExecutionEngine { private readonly _maxFeeBumps: number, private readonly _blockPollingInterval: number, private readonly _disableFeeBumping: boolean, + private readonly _maxRetries: number, + private readonly _retryInterval: number, ) {} /** @@ -107,6 +109,8 @@ export class ExecutionEngine { deploymentParameters, defaultSender, this._disableFeeBumping, + this._maxRetries, + this._retryInterval, ); const futures = getFuturesFromModule(module); diff --git a/v-next/hardhat-ignition-core/src/internal/execution/future-processor/future-processor.ts b/v-next/hardhat-ignition-core/src/internal/execution/future-processor/future-processor.ts index 130ed70652b..5def9ef4420 100644 --- a/v-next/hardhat-ignition-core/src/internal/execution/future-processor/future-processor.ts +++ b/v-next/hardhat-ignition-core/src/internal/execution/future-processor/future-processor.ts @@ -53,6 +53,8 @@ export class FutureProcessor { private readonly _deploymentParameters: DeploymentParameters, private readonly _defaultSender: string, private readonly _disableFeeBumping: boolean, + private readonly _maxRetries: number, + private readonly _retryInterval: number, ) {} /** @@ -207,16 +209,17 @@ export class FutureProcessor { `Unexpected transaction request in StaticCallExecutionState ${exState.id}`, ); - return monitorOnchainInteraction( + return monitorOnchainInteraction({ exState, - this._jsonRpcClient, - this._transactionTrackingTimer, - this._requiredConfirmations, - this._millisecondBeforeBumpingFees, - this._maxFeeBumps, - undefined, - this._disableFeeBumping, - ); + jsonRpcClient: this._jsonRpcClient, + transactionTrackingTimer: this._transactionTrackingTimer, + requiredConfirmations: this._requiredConfirmations, + millisecondBeforeBumpingFees: this._millisecondBeforeBumpingFees, + maxFeeBumps: this._maxFeeBumps, + disableFeeBumping: this._disableFeeBumping, + maxRetries: this._maxRetries, + retryInterval: this._retryInterval, + }); } } } diff --git a/v-next/hardhat-ignition-core/src/internal/execution/future-processor/handlers/monitor-onchain-interaction.ts b/v-next/hardhat-ignition-core/src/internal/execution/future-processor/handlers/monitor-onchain-interaction.ts index 67f63230f6a..428a14629e0 100644 --- a/v-next/hardhat-ignition-core/src/internal/execution/future-processor/handlers/monitor-onchain-interaction.ts +++ b/v-next/hardhat-ignition-core/src/internal/execution/future-processor/handlers/monitor-onchain-interaction.ts @@ -11,7 +11,10 @@ import type { OnchainInteractionTimeoutMessage, TransactionConfirmMessage, } from "../../types/messages.js"; -import type { OnchainInteraction } from "../../types/network-interaction.js"; +import type { + GetTransactionRetryConfig, + OnchainInteraction, +} from "../../types/network-interaction.js"; import { HardhatError } from "@nomicfoundation/hardhat-errors"; import setupDebug from "debug"; @@ -22,11 +25,6 @@ import { NetworkInteractionType } from "../../types/network-interaction.js"; const debug = setupDebug("hardhat-ignition:onchain-interaction-monitor"); -export interface GetTransactionRetryConfig { - maxRetries: number; - retryInterval: number; -} - /** * Checks the transactions of the latest network interaction of the execution state, * and returns a message, or undefined if we need to wait for more confirmations. @@ -40,81 +38,82 @@ export interface GetTransactionRetryConfig { * * SIDE EFFECTS: This function doesn't have any side effects. * - * @param exState The execution state that requires the transactions to be checked. - * @param jsonRpcClient The JSON RPC client to use for accessing the network. - * @param transactionTrackingTimer The TransactionTrackingTimer to use for checking the + * @param params.exState The execution state that requires the transactions to be checked. + * @param params.jsonRpcClient The JSON RPC client to use for accessing the network. + * @param params.transactionTrackingTimer The TransactionTrackingTimer to use for checking the * if a transaction has been pending for too long. - * @param requiredConfirmations The number of confirmations required for a transaction + * @param params.requiredConfirmations The number of confirmations required for a transaction * to be considered confirmed. - * @param millisecondBeforeBumpingFees The number of milliseconds before bumping the fees + * @param params.millisecondBeforeBumpingFees The number of milliseconds before bumping the fees * of a transaction. - * @param maxFeeBumps The maximum number of times we can bump the fees of a transaction + * @param params.maxFeeBumps The maximum number of times we can bump the fees of a transaction * before considering the onchain interaction timed out. - * @param getTransactionRetryConfig This is really only a parameter to help with testing this function - * @param disableFeeBumping Disables fee bumping for all transactions. + * @param params.getTransactionRetryConfig This is really only a parameter to help with testing this function + * @param params.disableFeeBumping Disables fee bumping for all transactions. + * @param params.maxRetries The maximum number of times to retry fetching a transaction from the mempool. + * @param params.retryInterval The number of milliseconds to wait between retries when fetching + * a transaction from the mempool. * @returns A message indicating the result of checking the transactions of the latest * network interaction. */ export async function monitorOnchainInteraction( - exState: - | DeploymentExecutionState - | CallExecutionState - | SendDataExecutionState, - jsonRpcClient: JsonRpcClient, - transactionTrackingTimer: TransactionTrackingTimer, - requiredConfirmations: number, - millisecondBeforeBumpingFees: number, - maxFeeBumps: number, - givenGetTransactionRetryConfig: GetTransactionRetryConfig | undefined, - disableFeeBumping: boolean, + params: { + exState: + | DeploymentExecutionState + | CallExecutionState + | SendDataExecutionState; + jsonRpcClient: JsonRpcClient; + transactionTrackingTimer: TransactionTrackingTimer; + requiredConfirmations: number; + millisecondBeforeBumpingFees: number; + maxFeeBumps: number; + disableFeeBumping: boolean; + } & GetTransactionRetryConfig, ): Promise< | TransactionConfirmMessage | OnchainInteractionBumpFeesMessage | OnchainInteractionTimeoutMessage | undefined > { - const lastNetworkInteraction = exState.networkInteractions.at(-1); - const getTransactionRetryConfig = givenGetTransactionRetryConfig ?? { - maxRetries: 10, - retryInterval: 1000, - }; + const lastNetworkInteraction = params.exState.networkInteractions.at(-1); assertIgnitionInvariant( lastNetworkInteraction !== undefined, - `No network interaction for ExecutionState ${exState.id} when trying to check its transactions`, + `No network interaction for ExecutionState ${params.exState.id} when trying to check its transactions`, ); assertIgnitionInvariant( lastNetworkInteraction.type === NetworkInteractionType.ONCHAIN_INTERACTION, - `StaticCall found as last network interaction of ExecutionState ${exState.id} when trying to check its transactions`, + `StaticCall found as last network interaction of ExecutionState ${params.exState.id} when trying to check its transactions`, ); assertIgnitionInvariant( lastNetworkInteraction.transactions.length > 0, - `No transaction found in OnchainInteraction ${exState.id}/${lastNetworkInteraction.id} when trying to check its transactions`, + `No transaction found in OnchainInteraction ${params.exState.id}/${lastNetworkInteraction.id} when trying to check its transactions`, ); - const transaction = await _getTransactionWithRetry( - jsonRpcClient, - lastNetworkInteraction, - getTransactionRetryConfig, - exState.id, - ); + const transaction = await _getTransactionWithRetry({ + jsonRpcClient: params.jsonRpcClient, + onchainInteraction: lastNetworkInteraction, + futureId: params.exState.id, + maxRetries: params.maxRetries, + retryInterval: params.retryInterval, + }); // We do not try to recover from dropped transactions mid-execution if (transaction === undefined) { throw new HardhatError( HardhatError.ERRORS.IGNITION.EXECUTION.DROPPED_TRANSACTION, { - futureId: exState.id, + futureId: params.exState.id, networkInteractionId: lastNetworkInteraction.id, }, ); } const [block, receipt] = await Promise.all([ - jsonRpcClient.getLatestBlock(), - jsonRpcClient.getTransactionReceipt(transaction.hash), + params.jsonRpcClient.getLatestBlock(), + params.jsonRpcClient.getTransactionReceipt(transaction.hash), ]); if (receipt !== undefined) { @@ -127,10 +126,10 @@ export async function monitorOnchainInteraction( // values that are high enough to avoid reorgs, we don't do it. const confirmations = block.number - receipt.blockNumber + 1; - if (confirmations >= requiredConfirmations) { + if (confirmations >= params.requiredConfirmations) { return { type: JournalMessageType.TRANSACTION_CONFIRM, - futureId: exState.id, + futureId: params.exState.id, networkInteractionId: lastNetworkInteraction.id, hash: transaction.hash, receipt, @@ -140,53 +139,55 @@ export async function monitorOnchainInteraction( return undefined; } - const timeTrackingTx = transactionTrackingTimer.getTransactionTrackingTime( - transaction.hash, - ); + const timeTrackingTx = + params.transactionTrackingTimer.getTransactionTrackingTime( + transaction.hash, + ); - if (timeTrackingTx < millisecondBeforeBumpingFees) { + if (timeTrackingTx < params.millisecondBeforeBumpingFees) { return undefined; } if ( - disableFeeBumping || - lastNetworkInteraction.transactions.length > maxFeeBumps + params.disableFeeBumping || + lastNetworkInteraction.transactions.length > params.maxFeeBumps ) { return { type: JournalMessageType.ONCHAIN_INTERACTION_TIMEOUT, - futureId: exState.id, + futureId: params.exState.id, networkInteractionId: lastNetworkInteraction.id, }; } return { type: JournalMessageType.ONCHAIN_INTERACTION_BUMP_FEES, - futureId: exState.id, + futureId: params.exState.id, networkInteractionId: lastNetworkInteraction.id, }; } async function _getTransactionWithRetry( - jsonRpcClient: JsonRpcClient, - onchainInteraction: OnchainInteraction, - retryConfig: GetTransactionRetryConfig, - futureId: string, + params: { + jsonRpcClient: JsonRpcClient; + onchainInteraction: OnchainInteraction; + futureId: string; + } & GetTransactionRetryConfig, ): Promise { let transaction: Transaction | undefined; // Small retry loop for up to X seconds to handle blockchain nodes // that are slow to propagate transactions. // See https://github.com/NomicFoundation/hardhat-ignition/issues/665 - for (let i = 0; i < retryConfig.maxRetries; i++) { + for (let i = 0; i < params.maxRetries; i++) { debug( - `Retrieving transaction for interaction ${futureId}/${ - onchainInteraction.id - } from mempool (attempt ${i + 1}/${retryConfig.maxRetries})`, + `Retrieving transaction for interaction ${params.futureId}/${ + params.onchainInteraction.id + } from mempool (attempt ${i + 1}/${params.maxRetries})`, ); const transactions = await Promise.all( - onchainInteraction.transactions.map((tx) => - jsonRpcClient.getTransaction(tx.hash), + params.onchainInteraction.transactions.map((tx) => + params.jsonRpcClient.getTransaction(tx.hash), ), ); @@ -197,12 +198,10 @@ async function _getTransactionWithRetry( } debug( - `Transaction lookup for ${futureId}/${onchainInteraction.id} not found in mempool, waiting ${retryConfig.retryInterval} seconds before retrying`, + `Transaction lookup for ${params.futureId}/${params.onchainInteraction.id} not found in mempool, waiting ${params.retryInterval} seconds before retrying`, ); - await new Promise((resolve) => - setTimeout(resolve, retryConfig.retryInterval), - ); + await new Promise((resolve) => setTimeout(resolve, params.retryInterval)); } return transaction; diff --git a/v-next/hardhat-ignition-core/src/internal/execution/types/network-interaction.ts b/v-next/hardhat-ignition-core/src/internal/execution/types/network-interaction.ts index 8f21eb5b7fc..18e84bfab3d 100644 --- a/v-next/hardhat-ignition-core/src/internal/execution/types/network-interaction.ts +++ b/v-next/hardhat-ignition-core/src/internal/execution/types/network-interaction.ts @@ -68,3 +68,11 @@ export interface StaticCall { from: string; result?: RawStaticCallResult; } + +/** + * Configuration for the retry loop when trying to fetch a transaction from the node. + */ +export interface GetTransactionRetryConfig { + maxRetries: number; + retryInterval: number; +} diff --git a/v-next/hardhat-ignition-core/src/types/deploy.ts b/v-next/hardhat-ignition-core/src/types/deploy.ts index 35bd4b5160e..91c92bd2a83 100644 --- a/v-next/hardhat-ignition-core/src/types/deploy.ts +++ b/v-next/hardhat-ignition-core/src/types/deploy.ts @@ -33,6 +33,18 @@ export interface DeployConfig { * Disables fee bumping for all transactions. */ disableFeeBumping: boolean; + + /** + * The maximum number of times to retry a call to getTransactionReceipt + * when monitoring the status of a transaction. + */ + maxRetries: number; + + /** + * The interval, in milliseconds, between retries when calling + * getTransactionReceipt. + */ + retryInterval: number; } /** diff --git a/v-next/hardhat-ignition-core/test/execution/execution-engine.ts b/v-next/hardhat-ignition-core/test/execution/execution-engine.ts index 0135b49ae0a..e11ae324163 100644 --- a/v-next/hardhat-ignition-core/test/execution/execution-engine.ts +++ b/v-next/hardhat-ignition-core/test/execution/execution-engine.ts @@ -29,6 +29,8 @@ describe("ExecutionEngine", () => { 5, 5, false, + 10, + 1000, ); const deploymentState = await loadDeploymentState(deploymentLoader); diff --git a/v-next/hardhat-ignition-core/test/execution/future-processor/helpers/network-interaction-execution.ts b/v-next/hardhat-ignition-core/test/execution/future-processor/helpers/network-interaction-execution.ts index 0ad12686d93..f2faf06e464 100644 --- a/v-next/hardhat-ignition-core/test/execution/future-processor/helpers/network-interaction-execution.ts +++ b/v-next/hardhat-ignition-core/test/execution/future-processor/helpers/network-interaction-execution.ts @@ -2,10 +2,7 @@ import { HardhatError } from "@nomicfoundation/hardhat-errors"; import { assertRejectsWithHardhatError } from "@nomicfoundation/hardhat-test-utils"; import { assert } from "chai"; -import { - type GetTransactionRetryConfig, - monitorOnchainInteraction, -} from "../../../../src/internal/execution/future-processor/handlers/monitor-onchain-interaction.js"; +import { monitorOnchainInteraction } from "../../../../src/internal/execution/future-processor/handlers/monitor-onchain-interaction.js"; import { decodeSimulationResult } from "../../../../src/internal/execution/future-processor/helpers/decode-simulation-result.js"; import { TRANSACTION_SENT_TYPE, @@ -221,11 +218,6 @@ describe("Network interactions", () => { const millisecondBeforeBumpingFees = 1; const maxFeeBumps = 1; - const testGetTransactionRetryConfig: GetTransactionRetryConfig = { - maxRetries: 10, - retryInterval: 1, - }; - let mockClient: MockGetTransactionJsonRpcClient; let fakeTransactionTrackingTimer: FakeTransactionTrackingTimer; @@ -284,16 +276,17 @@ describe("Network interactions", () => { }, }; - const message = await monitorOnchainInteraction( - deploymentExecutionState, - mockClient, - fakeTransactionTrackingTimer, + const message = await monitorOnchainInteraction({ + exState: deploymentExecutionState, + jsonRpcClient: mockClient, + transactionTrackingTimer: fakeTransactionTrackingTimer, requiredConfirmations, millisecondBeforeBumpingFees, maxFeeBumps, - testGetTransactionRetryConfig, - false, - ); + disableFeeBumping: false, + maxRetries: 10, + retryInterval: 1, + }); if (message === undefined) { return assert.fail("No message returned from monitoring"); @@ -329,16 +322,17 @@ describe("Network interactions", () => { }; await assertRejectsWithHardhatError( - monitorOnchainInteraction( - deploymentExecutionState, - mockClient, - fakeTransactionTrackingTimer, + monitorOnchainInteraction({ + exState: deploymentExecutionState, + jsonRpcClient: mockClient, + transactionTrackingTimer: fakeTransactionTrackingTimer, requiredConfirmations, millisecondBeforeBumpingFees, maxFeeBumps, - testGetTransactionRetryConfig, - false, - ), + disableFeeBumping: false, + maxRetries: 10, + retryInterval: 1, + }), HardhatError.ERRORS.IGNITION.EXECUTION.DROPPED_TRANSACTION, { futureId: "test", diff --git a/v-next/hardhat-ignition-core/test/execution/future-processor/utils.ts b/v-next/hardhat-ignition-core/test/execution/future-processor/utils.ts index 49330acc923..08f52fc5c68 100644 --- a/v-next/hardhat-ignition-core/test/execution/future-processor/utils.ts +++ b/v-next/hardhat-ignition-core/test/execution/future-processor/utils.ts @@ -66,6 +66,8 @@ export async function setupFutureProcessor( {}, getDefaultSender(exampleAccounts), false, // disableFeeBumping + 10, // maxRetries + 1000, // retryInterval ); return { processor, storedDeployedAddresses }; diff --git a/v-next/hardhat-ignition-ethers/src/internal/ethers-ignition-helper.ts b/v-next/hardhat-ignition-ethers/src/internal/ethers-ignition-helper.ts index 861029975a8..f2f856a6445 100644 --- a/v-next/hardhat-ignition-ethers/src/internal/ethers-ignition-helper.ts +++ b/v-next/hardhat-ignition-ethers/src/internal/ethers-ignition-helper.ts @@ -190,6 +190,12 @@ export class EthersIgnitionHelperImpl this.#connection.networkConfig?.ignition.maxFeePerGasLimit, maxPriorityFeePerGas: this.#connection.networkConfig?.ignition.maxPriorityFeePerGas, + maxRetries: + resolvedConfig.maxRetries ?? + this.#connection.networkConfig.ignition.maxRetries, + retryInterval: + resolvedConfig.retryInterval ?? + this.#connection.networkConfig.ignition.retryInterval, }); if (result.type !== DeploymentResultType.SUCCESSFUL_DEPLOYMENT) { diff --git a/v-next/hardhat-ignition-viem/src/internal/viem-ignition-helper.ts b/v-next/hardhat-ignition-viem/src/internal/viem-ignition-helper.ts index 903f0420476..54b9dce37da 100644 --- a/v-next/hardhat-ignition-viem/src/internal/viem-ignition-helper.ts +++ b/v-next/hardhat-ignition-viem/src/internal/viem-ignition-helper.ts @@ -193,6 +193,12 @@ export class ViemIgnitionHelperImpl this.#connection.networkConfig?.ignition.maxFeePerGasLimit, maxPriorityFeePerGas: this.#connection.networkConfig?.ignition.maxPriorityFeePerGas, + maxRetries: + resolvedConfig.maxRetries ?? + this.#connection.networkConfig.ignition.maxRetries, + retryInterval: + resolvedConfig.retryInterval ?? + this.#connection.networkConfig.ignition.retryInterval, }); if (result.type !== DeploymentResultType.SUCCESSFUL_DEPLOYMENT) { diff --git a/v-next/hardhat-ignition/src/internal/hook-handlers/config.ts b/v-next/hardhat-ignition/src/internal/hook-handlers/config.ts index ccf0c336cfe..4b6c69ab116 100644 --- a/v-next/hardhat-ignition/src/internal/hook-handlers/config.ts +++ b/v-next/hardhat-ignition/src/internal/hook-handlers/config.ts @@ -43,6 +43,8 @@ export async function resolveUserConfig( gasPrice: givenIgnition.gasPrice, disableFeeBumping: givenIgnition.disableFeeBumping, explorerUrl: givenIgnition.explorerUrl, + maxRetries: givenIgnition.maxRetries, + retryInterval: givenIgnition.retryInterval, }, }, ]; diff --git a/v-next/hardhat-ignition/src/internal/tasks/deploy.ts b/v-next/hardhat-ignition/src/internal/tasks/deploy.ts index a0cfd5b3bcf..baa2ba95e66 100644 --- a/v-next/hardhat-ignition/src/internal/tasks/deploy.ts +++ b/v-next/hardhat-ignition/src/internal/tasks/deploy.ts @@ -214,6 +214,12 @@ const taskDeploy: NewTaskActionFunction = async ( disableFeeBumping: hre.config.ignition.disableFeeBumping ?? hre.config.networks[connection.networkName]?.ignition.disableFeeBumping, + maxRetries: + hre.config.ignition.maxRetries ?? + hre.config.networks[connection.networkName]?.ignition.maxRetries, + retryInterval: + hre.config.ignition.retryInterval ?? + hre.config.networks[connection.networkName]?.ignition.retryInterval, }); if (result.type === "SUCCESSFUL_DEPLOYMENT" && verify) { diff --git a/v-next/hardhat-ignition/src/type-extensions.ts b/v-next/hardhat-ignition/src/type-extensions.ts index 45f84c1ce2f..5c07cf424ea 100644 --- a/v-next/hardhat-ignition/src/type-extensions.ts +++ b/v-next/hardhat-ignition/src/type-extensions.ts @@ -21,6 +21,8 @@ declare module "hardhat/types/config" { gasPrice?: bigint; disableFeeBumping?: boolean; explorerUrl?: string; + maxRetries?: number; + retryInterval?: number; }; } @@ -31,6 +33,8 @@ declare module "hardhat/types/config" { gasPrice?: bigint; disableFeeBumping?: boolean; explorerUrl?: string; + maxRetries?: number; + retryInterval?: number; }; } @@ -41,6 +45,8 @@ declare module "hardhat/types/config" { gasPrice?: bigint; disableFeeBumping?: boolean; explorerUrl?: string; + maxRetries?: number; + retryInterval?: number; }; } @@ -51,6 +57,8 @@ declare module "hardhat/types/config" { gasPrice?: bigint; disableFeeBumping?: boolean; explorerUrl?: string; + maxRetries?: number; + retryInterval?: number; }; } diff --git a/v-next/hardhat-ignition/test/config.ts b/v-next/hardhat-ignition/test/config.ts index 729411fb048..e045581b649 100644 --- a/v-next/hardhat-ignition/test/config.ts +++ b/v-next/hardhat-ignition/test/config.ts @@ -11,7 +11,7 @@ import hardhatIgnition from "../src/index.js"; import { useEphemeralIgnitionProject } from "./test-helpers/use-ignition-project.js"; -describe("config", () => { +describe.only("config", () => { describe("loading", () => { let loadedOptions: Partial; let hardhatNetworkOptions: NetworkConfig; @@ -30,6 +30,8 @@ describe("config", () => { maxPriorityFeePerGas: 3n, gasPrice: 1n, disableFeeBumping: false, + maxRetries: 7, + retryInterval: 7000, }, }, }, @@ -44,6 +46,8 @@ describe("config", () => { }, }, disableFeeBumping: true, + maxRetries: 5, + retryInterval: 2000, }, }); @@ -93,12 +97,30 @@ describe("config", () => { assert.equal(hardhatNetworkOptions.ignition.disableFeeBumping, false); }); + it("should apply maxRetries at the top level", async function () { + assert.equal(loadedOptions.maxRetries, 5); + }); + + it("should apply maxRetries at the network level", async function () { + assert.equal(hardhatNetworkOptions.ignition.maxRetries, 7); + }); + + it("should apply retryInterval at the top level", async function () { + assert.equal(loadedOptions.retryInterval, 2000); + }); + + it("should apply retryInterval at the network level", async function () { + assert.equal(hardhatNetworkOptions.ignition.retryInterval, 7000); + }); + it("should only have known config", () => { const configOptions: KeyListOf = [ "blockPollingInterval", "disableFeeBumping", "maxFeeBumps", + "maxRetries", "requiredConfirmations", + "retryInterval", "strategyConfig", "timeBeforeBumpingFees", ]; diff --git a/v-next/hardhat-ignition/test/fixture-projects/with-config/hardhat.config.js b/v-next/hardhat-ignition/test/fixture-projects/with-config/hardhat.config.js index b214a20e900..e6230cb1b5a 100644 --- a/v-next/hardhat-ignition/test/fixture-projects/with-config/hardhat.config.js +++ b/v-next/hardhat-ignition/test/fixture-projects/with-config/hardhat.config.js @@ -35,5 +35,7 @@ module.exports = { }, }, disableFeeBumping: true, + maxRetries: 10, + retryInterval: 1000, }, }; diff --git a/v-next/hardhat-ignition/test/test-helpers/use-ignition-project.ts b/v-next/hardhat-ignition/test/test-helpers/use-ignition-project.ts index a75336a9507..7cd773eecf5 100644 --- a/v-next/hardhat-ignition/test/test-helpers/use-ignition-project.ts +++ b/v-next/hardhat-ignition/test/test-helpers/use-ignition-project.ts @@ -48,6 +48,8 @@ const defaultTestConfig: DeployConfig = { blockPollingInterval: 200, requiredConfirmations: 1, disableFeeBumping: false, + maxRetries: 10, + retryInterval: 1000, }; // todo: whenever these tests are migrated to node:test, diff --git a/v-next/hardhat-keystore/test/fixture-projects/keystore/.gitignore b/v-next/hardhat-keystore/test/fixture-projects/keystore/.gitignore index 8eb59446812..482bcf3fb92 100644 --- a/v-next/hardhat-keystore/test/fixture-projects/keystore/.gitignore +++ b/v-next/hardhat-keystore/test/fixture-projects/keystore/.gitignore @@ -4,3 +4,5 @@ keystore-change-password.json fake-keystore-hardhat.checksum-path-* # This is a temp file created by the config variables tests config-variables-keystore.json +config-variables-dev-keystore.json +keystore-dev.json