diff --git a/packages/core/src/internal/reconciliation/helpers/reconcile-from.ts b/packages/core/src/internal/reconciliation/helpers/reconcile-from.ts index 287be1562..f9fe4e33a 100644 --- a/packages/core/src/internal/reconciliation/helpers/reconcile-from.ts +++ b/packages/core/src/internal/reconciliation/helpers/reconcile-from.ts @@ -1,11 +1,11 @@ import { + ContractCallFuture, ContractDeploymentFuture, LibraryDeploymentFuture, - ContractCallFuture, NamedArtifactContractDeploymentFuture, NamedArtifactLibraryDeploymentFuture, - StaticCallFuture, SendDataFuture, + StaticCallFuture, } from "../../../types/module"; import { resolveFutureFrom } from "../../execution/future-processor/helpers/future-resolvers"; import { @@ -37,6 +37,10 @@ export function reconcileFrom( | StaticCallExecutionState, context: ReconciliationContext ): ReconciliationFutureResultFailure | undefined { + if (future.from === undefined && context.accounts.includes(exState.from)) { + return undefined; + } + const resolvedFrom = resolveFutureFrom( future.from, context.accounts, diff --git a/packages/core/test/reconciliation/futures/reconcileNamedContractCall.ts b/packages/core/test/reconciliation/futures/reconcileNamedContractCall.ts index 37aa17c44..88cc138e8 100644 --- a/packages/core/test/reconciliation/futures/reconcileNamedContractCall.ts +++ b/packages/core/test/reconciliation/futures/reconcileNamedContractCall.ts @@ -94,6 +94,40 @@ describe("Reconciliation - named contract call", () => { ); }); + it("should reconcile when the from is undefined but the exState's from is in the accounts list", async () => { + const moduleDefinition = buildModule("Module", (m) => { + const contract1 = m.contract("Contract1"); + + m.call(contract1, "function1", [1, "a", contract1], { from: undefined }); + + return { contract1 }; + }); + + await assertSuccessReconciliation( + moduleDefinition, + createDeploymentState( + { + ...exampleDeploymentState, + id: "Module#Contract1", + status: ExecutionStatus.SUCCESS, + result: { + type: ExecutionResultType.SUCCESS, + address: differentAddress, + }, + }, + { + ...exampleContractCallState, + id: "Module#Contract1.function1", + futureType: FutureType.CONTRACT_CALL, + status: ExecutionStatus.SUCCESS, + functionName: "function1", + args: [1, "a", differentAddress], + from: exampleAccounts[2], + } + ) + ); + }); + it("should find changes to contract unreconciliable", async () => { const moduleDefinition = buildModule("Module", (m) => { const contract1 = m.contract("Contract1"); diff --git a/packages/core/test/reconciliation/futures/reconcileNamedContractDeployment.ts b/packages/core/test/reconciliation/futures/reconcileNamedContractDeployment.ts index 7271abf4e..3ba19a6b0 100644 --- a/packages/core/test/reconciliation/futures/reconcileNamedContractDeployment.ts +++ b/packages/core/test/reconciliation/futures/reconcileNamedContractDeployment.ts @@ -96,6 +96,34 @@ describe("Reconciliation - named contract", () => { ); }); + /** + * This test here is in a first run, the from is undefined and the defaultSender is used. + * On the second run the from is undefined but a different defaultSender is now in play. + * We say this should reconcile but the account from the first run should be used, as long + * as it is in the accounts list + */ + it("should reconcile where the future is undefined but the exState's from is in the accounts list", async () => { + const moduleDefinition = buildModule("Module", (m) => { + const contract1 = m.contract("Contract", [], { + id: "Example", + from: undefined, + }); + + return { contract1 }; + }); + + await assertSuccessReconciliation( + moduleDefinition, + createDeploymentState({ + ...exampleDeploymentState, + id: "Module#Example", + status: ExecutionStatus.STARTED, + contractName: "Contract", + from: exampleAccounts[3], + }) + ); + }); + it("should find changes to contract name unreconciliable", async () => { const moduleDefinition = buildModule("Module", (m) => { const contract1 = m.contract("ContractChanged", [], { diff --git a/packages/core/test/reconciliation/futures/reconcileNamedStaticCall.ts b/packages/core/test/reconciliation/futures/reconcileNamedStaticCall.ts index 691ec4c33..e8892a548 100644 --- a/packages/core/test/reconciliation/futures/reconcileNamedStaticCall.ts +++ b/packages/core/test/reconciliation/futures/reconcileNamedStaticCall.ts @@ -95,6 +95,43 @@ describe("Reconciliation - named static call", () => { ); }); + it("should reconcile when the from is undefined but the exState's from is in the accounts list", async () => { + const moduleDefinition = buildModule("Module", (m) => { + const contract1 = m.contract("Contract1"); + + m.staticCall(contract1, "function1", [1, "a"], 0, { + from: undefined, + }); + + return { contract1 }; + }); + + await assertSuccessReconciliation( + moduleDefinition, + createDeploymentState( + { + ...exampleDeploymentState, + id: "Module#Contract1", + status: ExecutionStatus.SUCCESS, + result: { + type: ExecutionResultType.SUCCESS, + address: exampleAddress, + }, + }, + { + ...exampleStaticCallState, + id: "Module#Contract1.function1", + futureType: FutureType.STATIC_CALL, + status: ExecutionStatus.SUCCESS, + contractAddress: exampleAddress, + functionName: "function1", + args: [1, "a"], + from: exampleAccounts[4], + } + ) + ); + }); + it("should find changes to contract unreconciliable", async () => { const moduleDefinition = buildModule("Module", (m) => { const contract1 = m.contract("Contract1"); diff --git a/packages/core/test/reconciliation/futures/reconcileSendData.ts b/packages/core/test/reconciliation/futures/reconcileSendData.ts index 06dca8e5c..6303f3658 100644 --- a/packages/core/test/reconciliation/futures/reconcileSendData.ts +++ b/packages/core/test/reconciliation/futures/reconcileSendData.ts @@ -56,6 +56,31 @@ describe("Reconciliation - send data", () => { ); }); + /** + * This test here is in a first run, the from is undefined and the defaultSender is used. + * On the second run the from is undefined but a different defaultSender is now in play. + * We say this should reconcile but the account from the first run should be used, as long + * as it is in the accounts list. + */ + it("should reconcile where the future is undefined but the exState's from is in the accounts list", async () => { + const moduleDefinition = buildModule("Module", (m) => { + m.send("test_send", exampleAddress, 0n, "example_data", { + from: undefined, + }); + + return {}; + }); + + await assertSuccessReconciliation( + moduleDefinition, + createDeploymentState({ + ...exampleSendState, + id: "Module#test_send", + status: ExecutionStatus.STARTED, + }) + ); + }); + it("should reconcile between undefined and 0x for data", async () => { const moduleDefinition = buildModule("Module", (m) => { m.send("test_send", exampleAddress, 0n, undefined);