public void Should_make_sure_external_contract_extcodehashes_stays_same_after_simulation(bool paymasterValidation, bool whitelisted, bool selfdestruct, bool shouldMatch) { Address externalContractAddress = TestItem.GetRandomAddress(); Address paymasterContractAddress = TestItem.GetRandomAddress(); // simple storage access contract byte[] externalContractCalledByPaymasterCode = Prepare.EvmCode .PushData(Address.Zero) .Op(selfdestruct ? Instruction.SELFDESTRUCT : Instruction.DUP1) .Done; TestState.CreateAccount(externalContractAddress, 1.Ether()); Keccak externalContractDeployedCodeHash = TestState.UpdateCode(externalContractCalledByPaymasterCode); TestState.UpdateCodeHash(externalContractAddress, externalContractDeployedCodeHash, Spec); byte[] paymasterCode = Prepare.EvmCode .Call(externalContractAddress, 70000) .Done; TestState.CreateAccount(paymasterContractAddress, 1.Ether()); Keccak paymasterDeployedCodeHash = TestState.UpdateCode(paymasterCode); TestState.UpdateCodeHash(paymasterContractAddress, paymasterDeployedCodeHash, Spec); byte[] code = Prepare.EvmCode .Op(paymasterValidation ? Instruction.NUMBER : Instruction.BASEFEE) // switch to paymaster validation with NUMBER .Call(paymasterContractAddress, 100000) .Op(Instruction.STOP) .Done; Keccak initialCodeHash = TestState.GetCodeHash(externalContractAddress); (UserOperationTxTracer tracer, _, _) = ExecuteAndTraceAccessCall(SenderRecipientAndMiner.Default, code, whitelisted); if (shouldMatch) { TestState.GetCodeHash(externalContractAddress).Should().Be(initialCodeHash); } else { TestState.GetCodeHash(externalContractAddress).Should().NotBe(initialCodeHash); } }
protected void AssertCodeHash(Address address, Keccak codeHash) { Assert.AreEqual(codeHash, TestState.GetCodeHash(address), "code hash"); }