コード例 #1
0
        private (Block block, Transaction transaction) PrepareInitTx(UInt256 blockNumber, long gasLimit, byte[] code)
        {
            TestState.CreateAccount(Sender, 100.Ether());
            TestState.Commit(SpecProvider.GenesisSpec);

            Transaction transaction = Build.A.Transaction
                                      .WithTo(null)
                                      .WithData(Bytes.Empty)
                                      .WithGasLimit((ulong)gasLimit)
                                      .WithGasPrice(1)
                                      .WithInit(code)
                                      .SignedAndResolved(_ethereumSigner, TestObject.PrivateKeyA, blockNumber)
                                      .TestObject;

            Block block = BuildBlock(blockNumber);

            return(block, transaction);
        }
コード例 #2
0
        protected (Block block, Transaction transaction) PrepareInitTx(long blockNumber, long gasLimit, byte[] code, SenderRecipientAndMiner senderRecipientAndMiner = null)
        {
            senderRecipientAndMiner ??= SenderRecipientAndMiner.Default;
            TestState.CreateAccount(senderRecipientAndMiner.Sender, 100.Ether());
            TestState.Commit(SpecProvider.GenesisSpec);

            Transaction transaction = Build.A.Transaction
                                      .WithTo(null)
                                      .WithGasLimit(gasLimit)
                                      .WithGasPrice(1)
                                      .WithCode(code)
                                      .SignedAndResolved(_ethereumEcdsa, senderRecipientAndMiner.SenderKey)
                                      .TestObject;

            Block block = BuildBlock(blockNumber, senderRecipientAndMiner);

            return(block, transaction);
        }
コード例 #3
0
        private void Test(string codeHex, long gasUsed, long refund, byte originalValue, bool eip3529Enabled)
        {
            TestState.CreateAccount(Recipient, 0);
            Storage.Set(new StorageCell(Recipient, 0), new [] { originalValue });
            Storage.Commit();
            TestState.Commit(eip3529Enabled ? London.Instance : Berlin.Instance);
            _processor = new TransactionProcessor(SpecProvider, TestState, Storage, Machine, LimboLogs.Instance);
            long blockNumber = eip3529Enabled ? LondonTestBlockNumber : LondonTestBlockNumber - 1;

            (Block block, Transaction transaction) = PrepareTx(blockNumber, 100000, Bytes.FromHexString(codeHex));

            transaction.GasPrice = 20.GWei();
            TestAllTracerWithOutput tracer = CreateTracer();

            _processor.Execute(transaction, block.Header, tracer);

            Assert.AreEqual(refund, tracer.Refund);
            AssertGas(tracer, gasUsed + GasCostOf.Transaction - Math.Min((gasUsed + GasCostOf.Transaction) / (eip3529Enabled ? RefundHelper.MaxRefundQuotientEIP3529 : RefundHelper.MaxRefundQuotient), refund));
        }
コード例 #4
0
        public void Records_get_correct_accessed_addresses()
        {
            byte[] code = Prepare.EvmCode
                          .Call(TestItem.AddressC, 50000)
                          .Op(Instruction.STOP)
                          .Done;

            TestState.Commit(Berlin.Instance);

            (AccessTxTracer tracer, _, _) = ExecuteAndTraceAccessCall(SenderRecipientAndMiner.Default, code);

            IEnumerable <Address> addressesAccessed = tracer.AccessList.Data.Keys;
            IEnumerable <Address> expected          = new[] {
                SenderRecipientAndMiner.Default.Sender, SenderRecipientAndMiner.Default.Recipient, TestItem.AddressC
            };

            Assert.IsNotEmpty(addressesAccessed);
            addressesAccessed.Should().BeEquivalentTo(expected);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        private (Block block, Transaction transaction) PrepareTx(long blockNumber, long gasLimit, byte[] code)
        {
            TestState.CreateAccount(Sender, 100.Ether());
            TestState.CreateAccount(Recipient, 100.Ether());
            Keccak codeHash = TestState.UpdateCode(code);

            TestState.UpdateCodeHash(TestItem.AddressB, codeHash, SpecProvider.GenesisSpec);

            TestState.Commit(SpecProvider.GenesisSpec);

            Transaction transaction = Build.A.Transaction
                                      .WithGasLimit(gasLimit)
                                      .WithGasPrice(1)
                                      .To(TestItem.AddressB)
                                      .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, blockNumber)
                                      .TestObject;

            Block block = BuildBlock(blockNumber);

            return(block, transaction);
        }
コード例 #7
0
        protected (Block block, Transaction transaction) PrepareTx(long blockNumber, long gasLimit, byte[] code, byte[] input, UInt256 value, 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);

            Transaction transaction = Build.A.Transaction
                                      .WithGasLimit(gasLimit)
                                      .WithGasPrice(1)
                                      .WithData(input)
                                      .WithValue(value)
                                      .To(senderRecipientAndMiner.Recipient)
                                      .SignedAndResolved(_ethereumEcdsa, senderRecipientAndMiner.SenderKey)
                                      .TestObject;

            Block block = BuildBlock(blockNumber, senderRecipientAndMiner);

            return(block, transaction);
        }
コード例 #8
0
        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);
        }
コード例 #9
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);
        }
コード例 #10
0
        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));
        }