protected (Block block, Transaction transaction) PrepareTx( long blockNumber, long gasLimit, byte[] code, SenderRecipientAndMiner senderRecipientAndMiner = null) { senderRecipientAndMiner ??= SenderRecipientAndMiner.Default; TestState.CreateAccount(senderRecipientAndMiner.Sender, 100.Ether()); TestState.CreateAccount(senderRecipientAndMiner.Recipient, 100.Ether()); Keccak codeHash = TestState.UpdateCode(code); TestState.UpdateCodeHash(senderRecipientAndMiner.Recipient, codeHash, SpecProvider.GenesisSpec); TestState.Commit(SpecProvider.GenesisSpec); TestState.CommitTree(); Transaction transaction = Build.A.Transaction .WithGasLimit(gasLimit) .WithGasPrice(1) .To(senderRecipientAndMiner.Recipient) .SignedAndResolved(_ethereumEcdsa, senderRecipientAndMiner.SenderKey) .TestObject; Block block = BuildBlock(blockNumber, senderRecipientAndMiner, transaction); return(block, transaction); }
public void Test_out_of_gas_existing_account_with_storage() { byte[] salt = { 4, 5, 6 }; byte[] deployedCode = { 1, 2, 3 }; byte[] initCode = Prepare.EvmCode .ForInitOf(deployedCode).Done; byte[] createCode = Prepare.EvmCode .Create2(initCode, salt, 0).Done; Address expectedAddress = ContractAddress.From(TestItem.AddressC, salt.PadLeft(32).AsSpan(), initCode.AsSpan()); TestState.CreateAccount(expectedAddress, 1.Ether()); Storage.Set(new StorageCell(expectedAddress, 1), new byte[] { 1, 2, 3, 4, 5 }); Storage.Commit(); Storage.CommitTrees(); TestState.Commit(Spec); TestState.CommitTree(); Keccak storageRoot = TestState.GetAccount(expectedAddress).StorageRoot; storageRoot.Should().NotBe(PatriciaTree.EmptyTreeHash); TestState.CreateAccount(TestItem.AddressC, 1.Ether()); Keccak createCodeHash = TestState.UpdateCode(createCode); TestState.UpdateCodeHash(TestItem.AddressC, createCodeHash, Spec); byte[] code = Prepare.EvmCode .Call(TestItem.AddressC, 32100) .Done; Execute(code); TestState.GetAccount(expectedAddress).Should().NotBeNull(); TestState.GetAccount(expectedAddress).Balance.Should().Be(1.Ether()); TestState.GetAccount(expectedAddress).StorageRoot.Should().Be(storageRoot); AssertEip1014(expectedAddress, Bytes.Empty); }
public void Destroy_restore_store_different_cells_previously_existing() { byte[] baseInitCodeStore = Prepare.EvmCode .PushData(2) .Op(Instruction.CALLVALUE) .Op(Instruction.SSTORE).Done; byte[] contractCode = Prepare.EvmCode .PushData(1) .Op(Instruction.SLOAD) .PushData(1) .Op(Instruction.EQ) .PushData(17) .Op(Instruction.JUMPI) .PushData(1) .PushData(1) .Op(Instruction.SSTORE) .PushData(21) .Op(Instruction.JUMP) .Op(Instruction.JUMPDEST) .PushData(0) .Op(Instruction.SELFDESTRUCT) .Op(Instruction.JUMPDEST) .Done; byte[] baseInitCodeAfterStore = Prepare.EvmCode .ForInitOf(contractCode) .Done; byte[] baseInitCode = Bytes.Concat(baseInitCodeStore, baseInitCodeAfterStore); byte[] create2Code = Prepare.EvmCode .ForCreate2Of(baseInitCode) .Done; byte[] initOfCreate2Code = Prepare.EvmCode .ForInitOf(create2Code) .Done; Address deployingContractAddress = ContractAddress.From(TestItem.PrivateKeyA.Address, 0); Address deploymentAddress = ContractAddress.From(deployingContractAddress, new byte[32], baseInitCode); byte[] deploy = Prepare.EvmCode .CallWithValue(deployingContractAddress, 100000) .Op(Instruction.STOP).Done; byte[] byteCode1 = Prepare.EvmCode .CallWithValue(deploymentAddress, 100000) .Op(Instruction.STOP).Done; byte[] byteCode2 = Prepare.EvmCode .CallWithValue(deploymentAddress, 100000) .Op(Instruction.STOP).Done; TestState.CreateAccount(TestItem.PrivateKeyA.Address, 100.Ether()); //TestState.Commit(SpecProvider.GenesisSpec); //TestState.CommitTree(0); TestState.CreateAccount(deploymentAddress, UInt256.One); Keccak codeHash = TestState.UpdateCode(contractCode); TestState.UpdateCodeHash(deploymentAddress, codeHash, MuirGlacier.Instance); Storage.Set(new StorageCell(deploymentAddress, 7), new byte[] { 7 }); Storage.Commit(); Storage.CommitTrees(0); TestState.Commit(MuirGlacier.Instance); TestState.CommitTree(0); long gasLimit = 1000000; EthereumEcdsa ecdsa = new(1, LimboLogs.Instance); // deploy create 2 Transaction tx0 = Build.A.Transaction.WithCode(initOfCreate2Code).WithGasLimit(gasLimit).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; // call contract once Transaction tx1 = Build.A.Transaction.WithCode(byteCode1).WithGasLimit(gasLimit).WithNonce(1).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; // self destruct contract Transaction tx2 = Build.A.Transaction.WithCode(byteCode2).WithGasLimit(gasLimit).WithNonce(2).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; // deploy again using create2 Transaction tx3 = Build.A.Transaction.WithValue(3).WithCode(deploy).WithGasLimit(gasLimit).WithNonce(3).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; // call newly deployed once Transaction tx4 = Build.A.Transaction.WithCode(byteCode1).WithGasLimit(gasLimit).WithNonce(4).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; Block block = Build.A.Block.WithNumber(MainnetSpecProvider.MuirGlacierBlockNumber).WithTransactions(tx0, tx1, tx2, tx3, tx4).WithGasLimit(2 * gasLimit).TestObject; ParityLikeTxTracer tracer = new(block, tx0, ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); _processor.Execute(tx0, block.Header, tracer); tracer = new ParityLikeTxTracer(block, tx1, ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); _processor.Execute(tx1, block.Header, tracer); // AssertStorage(new StorageCell(deploymentAddress, 7), 7); tracer = new ParityLikeTxTracer(block, tx2, ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); _processor.Execute(tx2, block.Header, tracer); // AssertStorage(new StorageCell(deploymentAddress, 7), 0); tracer = new ParityLikeTxTracer(block, tx3, ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); _processor.Execute(tx3, block.Header, tracer); AssertStorage(new StorageCell(deploymentAddress, 7), 0); tracer = new ParityLikeTxTracer(block, tx4, ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); _processor.Execute(tx4, block.Header, tracer); AssertStorage(new StorageCell(deploymentAddress, 7), 0); }
public void Destroy_restore_store() { TestState.CreateAccount(TestItem.PrivateKeyA.Address, 100.Ether()); TestState.Commit(SpecProvider.GenesisSpec); TestState.CommitTree(); byte[] baseInitCodeStore = Prepare.EvmCode .PushData(2) .PushData(2) .Op(Instruction.SSTORE).Done; byte[] baseInitCodeAfterStore = Prepare.EvmCode .ForInitOf( Prepare.EvmCode .PushData(1) .Op(Instruction.SLOAD) .PushData(1) .Op(Instruction.EQ) .PushData(17) .Op(Instruction.JUMPI) .PushData(1) .PushData(1) .Op(Instruction.SSTORE) .PushData(21) .Op(Instruction.JUMP) .Op(Instruction.JUMPDEST) .PushData(0) .Op(Instruction.SELFDESTRUCT) .Op(Instruction.JUMPDEST) .Done) .Done; byte[] baseInitCode = Bytes.Concat(baseInitCodeStore, baseInitCodeAfterStore); byte[] create2Code = Prepare.EvmCode .ForCreate2Of(baseInitCode) .Done; byte[] initOfCreate2Code = Prepare.EvmCode .ForInitOf(create2Code) .Done; Address deployingContractAddress = ContractAddress.From(TestItem.PrivateKeyA.Address, 0); Address deploymentAddress = ContractAddress.From(deployingContractAddress, new byte[32], baseInitCode); byte[] deploy = Prepare.EvmCode .Call(deployingContractAddress, 100000) .Op(Instruction.STOP).Done; byte[] byteCode1 = Prepare.EvmCode .Call(deploymentAddress, 100000) .Op(Instruction.STOP).Done; byte[] byteCode2 = Prepare.EvmCode .Call(deploymentAddress, 100000) .Op(Instruction.STOP).Done; long gasLimit = 1000000; EthereumEcdsa ecdsa = new EthereumEcdsa(1, LimboLogs.Instance); // deploy create 2 Transaction tx0 = Build.A.Transaction.WithInit(initOfCreate2Code).WithGasLimit(gasLimit).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; // invoke create 2 to deploy contract Transaction tx1 = Build.A.Transaction.WithInit(deploy).WithGasLimit(gasLimit).WithNonce(1).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; // call contract once Transaction tx2 = Build.A.Transaction.WithInit(byteCode1).WithGasLimit(gasLimit).WithNonce(2).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; // self destruct contract Transaction tx3 = Build.A.Transaction.WithInit(byteCode2).WithGasLimit(gasLimit).WithNonce(3).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; // deploy again using create2 Transaction tx4 = Build.A.Transaction.WithInit(deploy).WithGasLimit(gasLimit).WithNonce(4).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; // call newly deployed once Transaction tx5 = Build.A.Transaction.WithInit(byteCode1).WithGasLimit(gasLimit).WithNonce(5).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; Block block = Build.A.Block.WithNumber(MainnetSpecProvider.MuirGlacierBlockNumber).WithTransactions(tx0, tx1, tx2, tx3, tx4, tx5).WithGasLimit(2 * gasLimit).TestObject; ParityLikeTxTracer tracer0 = new ParityLikeTxTracer(block, tx0, ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); _processor.Execute(tx0, block.Header, tracer0); // AssertStorage(new StorageCell(deploymentAddress, 1), 0); ParityLikeTxTracer tracer = new ParityLikeTxTracer(block, tx1, ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); _processor.Execute(tx1, block.Header, tracer); // AssertStorage(new StorageCell(deploymentAddress, 1), 0); // AssertStorage(new StorageCell(deploymentAddress, 2), 2); tracer = new ParityLikeTxTracer(block, tx2, ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); _processor.Execute(tx2, block.Header, tracer); // AssertStorage(new StorageCell(deploymentAddress, 1), 1); // AssertStorage(new StorageCell(deploymentAddress, 2), 2); tracer = new ParityLikeTxTracer(block, tx3, ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); _processor.Execute(tx3, block.Header, tracer); // AssertStorage(new StorageCell(deploymentAddress, 1), 0); // AssertStorage(new StorageCell(deploymentAddress, 2), 0); tracer = new ParityLikeTxTracer(block, tx4, ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); _processor.Execute(tx4, block.Header, tracer); // AssertStorage(new StorageCell(deploymentAddress, 1), 0); // AssertStorage(new StorageCell(deploymentAddress, 2), 2); tracer = new ParityLikeTxTracer(block, tx5, ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); _processor.Execute(tx5, block.Header, tracer); AssertStorage(new StorageCell(deploymentAddress, 1), 1); AssertStorage(new StorageCell(deploymentAddress, 2), 2); }
public void After_3529_self_destruct_has_zero_refund(bool eip3529Enabled) { TestState.CreateAccount(TestItem.PrivateKeyA.Address, 100.Ether()); TestState.Commit(SpecProvider.GenesisSpec); TestState.CommitTree(0); byte[] baseInitCodeStore = Prepare.EvmCode .PushData(2) .PushData(2) .Op(Instruction.SSTORE).Done; byte[] baseInitCodeAfterStore = Prepare.EvmCode .ForInitOf( Prepare.EvmCode .PushData(1) .Op(Instruction.SLOAD) .PushData(1) .Op(Instruction.EQ) .PushData(17) .Op(Instruction.JUMPI) .PushData(1) .PushData(1) .Op(Instruction.SSTORE) .PushData(21) .Op(Instruction.JUMP) .Op(Instruction.JUMPDEST) .PushData(0) .Op(Instruction.SELFDESTRUCT) .Op(Instruction.JUMPDEST) .Done) .Done; byte[] baseInitCode = Bytes.Concat(baseInitCodeStore, baseInitCodeAfterStore); byte[] create2Code = Prepare.EvmCode .ForCreate2Of(baseInitCode) .Done; byte[] initOfCreate2Code = Prepare.EvmCode .ForInitOf(create2Code) .Done; Address deployingContractAddress = ContractAddress.From(TestItem.PrivateKeyA.Address, 0); Address deploymentAddress = ContractAddress.From(deployingContractAddress, new byte[32], baseInitCode); byte[] deploy = Prepare.EvmCode .Call(deployingContractAddress, 100000) .Op(Instruction.STOP).Done; byte[] byteCode1 = Prepare.EvmCode .Call(deploymentAddress, 100000) .Op(Instruction.STOP).Done; byte[] byteCode2 = Prepare.EvmCode .Call(deploymentAddress, 100000) .Op(Instruction.STOP).Done; long gasLimit = 1000000; EthereumEcdsa ecdsa = new(1, LimboLogs.Instance); // deploy create 2 Transaction tx0 = Build.A.Transaction.WithCode(initOfCreate2Code).WithGasLimit(gasLimit).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; // invoke create 2 to deploy contract Transaction tx1 = Build.A.Transaction.WithCode(deploy).WithGasLimit(gasLimit).WithNonce(1).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; // call contract once Transaction tx2 = Build.A.Transaction.WithCode(byteCode1).WithGasLimit(gasLimit).WithNonce(2).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; // self destruct contract Transaction tx3 = Build.A.Transaction.WithCode(byteCode2).WithGasLimit(gasLimit).WithNonce(3).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; int gasUsedByTx3 = 37767; long blockNumber = eip3529Enabled ? LondonTestBlockNumber : LondonTestBlockNumber - 1; Block block = Build.A.Block.WithNumber(blockNumber).WithTransactions(tx0, tx1, tx2, tx3).WithGasLimit(2 * gasLimit).TestObject; ParityLikeTxTracer tracer0 = new(block, tx0, ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); _processor.Execute(tx0, block.Header, tracer0); TestAllTracerWithOutput tracer = CreateTracer(); _processor.Execute(tx1, block.Header, tracer); tracer = CreateTracer(); _processor.Execute(tx2, block.Header, tracer); tracer = CreateTracer(); _processor.Execute(tx3, block.Header, tracer); long expectedRefund = eip3529Enabled ? 0 : 24000; Assert.AreEqual(expectedRefund, tracer.Refund); AssertGas(tracer, gasUsedByTx3 + GasCostOf.Transaction - Math.Min((gasUsedByTx3 + GasCostOf.Transaction) / (eip3529Enabled ? RefundHelper.MaxRefundQuotientEIP3529 : RefundHelper.MaxRefundQuotient), expectedRefund)); }