Skip to content

Commit ce479e4

Browse files
committed
port txHash bug fix to v3
1 parent 25067ca commit ce479e4

31 files changed

+1143
-50
lines changed

v-next/hardhat-ignition-core/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ export * from "./types/provider.js";
1919
export * from "./types/serialization.js";
2020
export * from "./types/status.js";
2121
export * from "./types/verify.js";
22+
export { trackTransaction } from "./track-transaction.js";
2223
export { getVerificationInformation } from "./verify.js";
2324
export { wipe } from "./wipe.js";

v-next/hardhat-ignition-core/src/internal/errors-list.ts

+41
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ export const ERROR_RANGES: {
7878
max: 1299,
7979
title: "List transactions errors",
8080
},
81+
TRACK_TRANSACTION: {
82+
min: 1300,
83+
max: 1399,
84+
title: "Track transaction errors",
85+
},
8186
};
8287

8388
/**
@@ -201,6 +206,12 @@ export const ERRORS = {
201206
number: 410,
202207
message: "Gas estimation failed: %error%",
203208
},
209+
TRANSACTION_LOST: {
210+
number: 411,
211+
message: `An error occured while trying to send a transaction for future %futureId%.
212+
Please use a block explorer to find the hash of the transaction with nonce %nonce% sent from account %sender% and use the following command to add it to your deployment:
213+
npx hardhat ignition track-tx <txHash> <deploymentId> --network <networkName>`,
214+
},
204215
},
205216
RECONCILIATION: {
206217
INVALID_EXECUTION_STATUS: {
@@ -412,6 +423,36 @@ export const ERRORS = {
412423
"Cannot list transactions for nonexistant deployment at %deploymentDir%",
413424
},
414425
},
426+
TRACK_TRANSACTION: {
427+
DEPLOYMENT_DIR_NOT_FOUND: {
428+
number: 1300,
429+
message: "Deployment directory %deploymentDir% not found",
430+
},
431+
UNINITIALIZED_DEPLOYMENT: {
432+
number: 1301,
433+
message:
434+
"Cannot track transaction for nonexistant deployment at %deploymentDir%",
435+
},
436+
TRANSACTION_NOT_FOUND: {
437+
number: 1302,
438+
message: `Transaction %txHash% not found. Please double check the transaction hash and try again.`,
439+
},
440+
MATCHING_NONCE_NOT_FOUND: {
441+
number: 1303,
442+
message: `The transaction you provided doesn't seem to belong to your deployment.
443+
Please double check the error you are getting when running Hardhat Ignition, and the instructions it's providing.`,
444+
},
445+
KNOWN_TRANSACTION: {
446+
number: 1304,
447+
message: `The transaction hash that you provided was already present in your deployment.
448+
Please double check the error you are getting when running Hardhat Ignition, and the instructions it's providing.`,
449+
},
450+
INSUFFICIENT_CONFIRMATIONS: {
451+
number: 1305,
452+
message: `The transaction you provided doesn't have enough confirmations yet.
453+
Please try again later.`,
454+
},
455+
},
415456
};
416457

417458
/**

v-next/hardhat-ignition-core/src/internal/execution/deployment-state-helpers.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ export async function initializeDeploymentState(
5151
* This function applies a new message to the deployment state, recording it to the
5252
* journal if needed.
5353
*
54-
* @param message The message to apply.
55-
* @param deploymentState The original deployment state.
56-
* @param deploymentLoader The deployment loader that will be used to record the message.
54+
* @param message - The message to apply.
55+
* @param deploymentState - The original deployment state.
56+
* @param deploymentLoader - The deployment loader that will be used to record the message.
5757
* @returns The new deployment state.
5858
*/
5959
export async function applyNewMessage(

v-next/hardhat-ignition-core/src/internal/execution/execution-engine.ts

+32
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@ import type { DeploymentLoader } from "../deployment-loader/types.js";
1313

1414
import sortBy from "lodash-es/sortBy.js";
1515

16+
import { IgnitionError } from "../../errors.js";
1617
import { ExecutionEventType } from "../../types/execution-events.js";
18+
import { ERRORS } from "../errors-list.js";
1719
import { assertIgnitionInvariant } from "../utils/assertions.js";
1820
import { getFuturesFromModule } from "../utils/get-futures-from-module.js";
21+
import { getNetworkExecutionStates } from "../views/execution-state/get-network-execution-states.js";
1922
import { getPendingNonceAndSender } from "../views/execution-state/get-pending-nonce-and-sender.js";
2023
import { hasExecutionSucceeded } from "../views/has-execution-succeeded.js";
2124
import { isBatchFinished } from "../views/is-batch-finished.js";
@@ -26,6 +29,7 @@ import { getMaxNonceUsedBySender } from "./nonce-management/get-max-nonce-used-b
2629
import { getNonceSyncMessages } from "./nonce-management/get-nonce-sync-messages.js";
2730
import { JsonRpcNonceManager } from "./nonce-management/json-rpc-nonce-manager.js";
2831
import { TransactionTrackingTimer } from "./transaction-tracking-timer.js";
32+
import { NetworkInteractionType } from "./types/network-interaction.js";
2933

3034
/**
3135
* This class is used to execute a module to completion, returning the new
@@ -69,6 +73,8 @@ export class ExecutionEngine {
6973
deploymentParameters: DeploymentParameters,
7074
defaultSender: string,
7175
): Promise<DeploymentState> {
76+
await this._checkForMissingTransactions(deploymentState);
77+
7278
deploymentState = await this._syncNonces(
7379
deploymentState,
7480
module,
@@ -199,6 +205,32 @@ export class ExecutionEngine {
199205
}
200206
}
201207

208+
/**
209+
* Checks the journal for missing transactions, throws if any are found
210+
* and asks the user to track the missing transaction via the `track-tx` command.
211+
*/
212+
private async _checkForMissingTransactions(
213+
deploymentState: DeploymentState,
214+
): Promise<void> {
215+
const exStates = getNetworkExecutionStates(deploymentState);
216+
217+
for (const exState of exStates) {
218+
for (const ni of exState.networkInteractions) {
219+
if (
220+
ni.type === NetworkInteractionType.ONCHAIN_INTERACTION &&
221+
ni.nonce !== undefined &&
222+
ni.transactions.length === 0
223+
) {
224+
throw new IgnitionError(ERRORS.EXECUTION.TRANSACTION_LOST, {
225+
futureId: exState.id,
226+
nonce: ni.nonce,
227+
sender: exState.from,
228+
});
229+
}
230+
}
231+
}
232+
}
233+
202234
/**
203235
* Syncs the nonces of the deployment state with the blockchain, returning
204236
* the new deployment state, and throwing if they can't be synced.

v-next/hardhat-ignition-core/src/internal/execution/future-processor/future-processor.ts

+1
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ export class FutureProcessor {
195195
this._jsonRpcClient,
196196
this._nonceManager,
197197
this._transactionTrackingTimer,
198+
this._deploymentLoader,
198199
);
199200

200201
case NextAction.QUERY_STATIC_CALL:

v-next/hardhat-ignition-core/src/internal/execution/future-processor/handlers/send-transaction.ts

+4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import type {
1818
TransactionSendMessage,
1919
} from "../../types/messages.js";
2020

21+
import { DeploymentLoader } from "../../../deployment-loader/types.js";
2122
import { assertIgnitionInvariant } from "../../../utils/assertions.js";
2223
import { ExecutionResultType } from "../../types/execution-result.js";
2324
import { JournalMessageType } from "../../types/messages.js";
@@ -58,6 +59,7 @@ export async function sendTransaction(
5859
jsonRpcClient: JsonRpcClient,
5960
nonceManager: NonceManager,
6061
transactionTrackingTimer: TransactionTrackingTimer,
62+
deploymentLoader: DeploymentLoader,
6163
): Promise<
6264
| TransactionSendMessage
6365
| DeploymentExecutionStateCompleteMessage
@@ -89,6 +91,8 @@ export async function sendTransaction(
8991
lastNetworkInteraction,
9092
nonceManager,
9193
decodeSimulationResult(strategyGenerator, exState),
94+
deploymentLoader,
95+
exState.id,
9296
);
9397

9498
// If the transaction failed during simulation, we need to revert the nonce allocation

v-next/hardhat-ignition-core/src/internal/execution/future-processor/helpers/network-interaction-execution.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ import type {
2222
} from "../../types/network-interaction.js";
2323

2424
import { IgnitionError } from "../../../../errors.js";
25+
import { DeploymentLoader } from "../../../deployment-loader/types.js";
2526
import { ERRORS } from "../../../errors-list.js";
2627
import { assertIgnitionInvariant } from "../../../utils/assertions.js";
28+
import { JournalMessageType } from "../../types/messages.js";
2729

2830
/**
2931
* Runs a StaticCall NetworkInteraction to completion, returning its raw result.
@@ -108,12 +110,14 @@ export async function sendTransactionForOnchainInteraction(
108110
| StrategySimulationErrorExecutionResult
109111
| undefined
110112
>,
113+
deploymentLoader: DeploymentLoader,
114+
futureId: string,
111115
): Promise<
112116
| SimulationErrorExecutionResult
113117
| StrategySimulationErrorExecutionResult
114118
| {
115119
type: typeof TRANSACTION_SENT_TYPE;
116-
transaction: Transaction;
120+
transaction: Pick<Transaction, "hash" | "fees">;
117121
nonce: number;
118122
}
119123
> {
@@ -201,6 +205,13 @@ export async function sendTransactionForOnchainInteraction(
201205
return decodedSimulationResult;
202206
}
203207

208+
await deploymentLoader.recordToJournal({
209+
type: JournalMessageType.TRANSACTION_PREPARE_SEND,
210+
futureId,
211+
networkInteractionId: onchainInteraction.id,
212+
nonce: transactionParams.nonce,
213+
});
214+
204215
const txHash = await client.sendTransaction(transactionParams);
205216

206217
return {

0 commit comments

Comments
 (0)