public void Load_self_destruct() { TestState.CreateAccount(TestItem.PrivateKeyA.Address, 100.Ether()); TestState.Commit(SpecProvider.GenesisSpec); TestState.CommitTree(0); byte[] initByteCode = 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; Address contractAddress = ContractAddress.From(TestItem.PrivateKeyA.Address, 0); byte[] byteCode1 = Prepare.EvmCode .Call(contractAddress, 100000) .Op(Instruction.STOP).Done; byte[] byteCode2 = Prepare.EvmCode .Call(contractAddress, 100000) .Op(Instruction.STOP).Done; long gasLimit = 1000000; EthereumEcdsa ecdsa = new(1, LimboLogs.Instance); Transaction initTx = Build.A.Transaction.WithCode(initByteCode).WithGasLimit(gasLimit).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; Transaction tx1 = Build.A.Transaction.WithCode(byteCode1).WithGasLimit(gasLimit).WithNonce(1).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; Transaction tx2 = Build.A.Transaction.WithCode(byteCode2).WithGasLimit(gasLimit).WithNonce(2).SignedAndResolved(ecdsa, TestItem.PrivateKeyA).TestObject; Block block = Build.A.Block.WithNumber(MainnetSpecProvider.MuirGlacierBlockNumber).WithTransactions(initTx, tx1, tx2).WithGasLimit(2 * gasLimit).TestObject; ParityLikeTxTracer initTracer = new(block, initTx, ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); _processor.Execute(initTx, block.Header, initTracer); AssertStorage(new StorageCell(contractAddress, 1), 0); ParityLikeTxTracer tracer1 = new(block, tx1, ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); _processor.Execute(tx1, block.Header, tracer1); AssertStorage(new StorageCell(contractAddress, 1), 1); ParityLikeTxTracer tracer2 = new(block, tx2, ParityTraceTypes.Trace | ParityTraceTypes.StateDiff); _processor.Execute(tx2, block.Header, tracer2); AssertStorage(new StorageCell(contractAddress, 1), 0); }
public void Throws_on_theoretical_contract_crash() { var contractAddress = ContractAddress.From(_senderPublicKey.ToKvmAddress(), 0); _stateProvider.CreateAccount(contractAddress, 1000.Kat()); var codeHash = _stateProvider.UpdateCode(Bytes.FromHexString("0x01")); _stateProvider.UpdateCodeHash(contractAddress, codeHash, _specProvider.GenesisSpec); _stateProvider.Commit(_specProvider.GenesisSpec); var delta = EntryUtils.PrepareSingleContractEntryDelta(null, _senderPublicKey, 0, "0x60016000526001601FF300"); delta.PublicEntries[0].GasLimit = 1_000_000L; delta.PublicEntries[0].ReceiverAddress = ByteString.Empty; delta.PublicEntries[0].Signature = delta.PublicEntries[0] .GenerateSignature(_cryptoContext, _senderPrivateKey, _signingContext); var tracer = Substitute.For <ITxTracer>(); tracer.IsTracingReceipt.Returns(true); _executor.Execute(delta, tracer); tracer.Received().MarkAsFailed(contractAddress, 1_000_000L, Arg.Any <byte[]>(), null); }
public void Create_returns_code_hash() { byte[] deployedCode = { 1, 2, 3 }; Keccak deployedCodeHash = Keccak.Compute(deployedCode); byte[] initCode = Prepare.EvmCode .ForInitOf(deployedCode).Done; byte[] createCode = Prepare.EvmCode .Create(initCode, 0).Done; TestState.CreateAccount(TestItem.AddressC, 1.Ether()); Keccak createCodeHash = TestState.UpdateCode(createCode); TestState.UpdateCodeHash(TestItem.AddressC, createCodeHash, Spec); byte[] code = Prepare.EvmCode .Call(TestItem.AddressC, 50000) .PushData(ContractAddress.From(TestItem.AddressC, 0)) .Op(Instruction.EXTCODEHASH) .PushData(0) .Op(Instruction.SSTORE) .Done; Execute(code); AssertStorage(0, deployedCodeHash); }
public async Task Tree_tracker_insert_leaves([ValueSource(nameof(InsertLeavesTestCases))] InsertLeavesTest test) { var address = TestItem.Addresses[0]; var result = await InitializeTestRpc(address); var testRpc = result.TestRpc; BaselineTree baselineTree = BuildATree(); var fromContractAdress = ContractAddress.From(address, 0); var baselineTreeHelper = new BaselineTreeHelper(testRpc.LogFinder, _baselineDb, _metadataBaselineDb, LimboNoErrorLogger.Instance); new BaselineTreeTracker(fromContractAdress, baselineTree, testRpc.BlockProcessor, baselineTreeHelper, testRpc.BlockFinder, LimboNoErrorLogger.Instance); var contract = new MerkleTreeSHAContract(_abiEncoder, fromContractAdress); UInt256 nonce = 1L; for (int i = 0; i < test.ExpectedTreeCounts.Length; i++) { nonce = await InsertLeavesFromArray(test.LeavesInTransactionsAndBlocks[i], nonce, testRpc, contract, address); await testRpc.AddBlock(); Assert.AreEqual(test.ExpectedTreeCounts[i], baselineTree.Count); } }
public async Task deploy_bytecode_validates_input(string bytecode) { var spec = new SingleReleaseSpecProvider(ConstantinopleFix.Instance, 1); TestRpcBlockchain testRpc = await TestRpcBlockchain.ForTest(SealEngineType.NethDev).Build(spec); testRpc.TestWallet.UnlockAccount(TestItem.Addresses[0], new SecureString()); await testRpc.AddFunds(TestItem.Addresses[0], 1.Ether()); BaselineModule baselineModule = CreateBaselineModule(testRpc); var result = await baselineModule.baseline_deployBytecode( TestItem.Addresses[0], bytecode); // invalid input result.Data.Should().Be(null); result.ErrorCode.Should().Be(ErrorCodes.InvalidInput); result.Result.Error.Should().NotBeNull(); result.Result.ResultType.Should().Be(ResultType.Failure); await testRpc.AddBlock(); testRpc.BlockTree.Head.Number.Should().Be(5); testRpc.BlockTree.Head.Transactions.Should().NotContain(tx => tx.IsContractCreation); var code = testRpc.StateReader .GetCode(testRpc.BlockTree.Head.StateRoot, ContractAddress.From(TestItem.Addresses[0], 0)); code.Should().BeEmpty(); }
public void Create_and_revert_returns_zero() { byte[] deployedCode = { 1, 2, 3 }; byte[] initCode = Prepare.EvmCode .PushData(deployedCode.PadRight(32)) .PushData(0) .Op(Instruction.MSTORE) .PushData(3) .PushData(0) .Op(Instruction.RETURN) .Done; byte[] createCode = Prepare.EvmCode .Create(initCode, 0) .Op(Instruction.REVERT).Done; TestState.CreateAccount(TestItem.AddressC, 1.Ether()); Keccak createCodeHash = TestState.UpdateCode(createCode); TestState.UpdateCodeHash(TestItem.AddressC, createCodeHash, Spec); byte[] code = Prepare.EvmCode .Call(TestItem.AddressC, 50000) .PushData(ContractAddress.From(TestItem.AddressC, 0)) .Op(Instruction.EXTCODEHASH) .PushData(0) .Op(Instruction.SSTORE) .Done; Execute(code); AssertStorage(0, Keccak.Zero); }
public void Test_out_of_gas_non_existing_account() { 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()); <-- non-existing 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.AccountExists(expectedAddress).Should().BeFalse(); }
public void Test() { 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; TestState.CreateAccount(TestItem.AddressC, 1.Ether()); Keccak createCodeHash = TestState.UpdateCode(createCode); TestState.UpdateCodeHash(TestItem.AddressC, createCodeHash, Spec); byte[] code = Prepare.EvmCode .Call(TestItem.AddressC, 50000) .Done; Execute(code); Address expectedAddress = ContractAddress.From(TestItem.AddressC, salt.PadLeft(32).AsSpan(), initCode.AsSpan()); AssertEip1014(expectedAddress, deployedCode); }
public void Test_out_of_gas_existing_account() { 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()); 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()); AssertEip1014(expectedAddress, Bytes.Empty); }
public async Task deploy_bytecode_deploys_the_contract() { var spec = new SingleReleaseSpecProvider(ConstantinopleFix.Instance, 1); using TestRpcBlockchain testRpc = await TestRpcBlockchain.ForTest <BaseLineRpcBlockchain>(SealEngineType.NethDev).Build(spec); testRpc.TestWallet.UnlockAccount(TestItem.Addresses[0], new SecureString()); BaselineModule baselineModule = CreateBaselineModule(testRpc); var result = await baselineModule.baseline_deployBytecode( TestItem.Addresses[0], File.ReadAllText("testBytecode")); result.Data.Should().NotBe(null); result.ErrorCode.Should().Be(0); result.Result.Error.Should().BeNull(); result.Result.ResultType.Should().Be(ResultType.Success); await testRpc.AddBlock(); testRpc.BlockTree.Head.Number.Should().Be(2); testRpc.BlockTree.Head.Transactions.Should().Contain(tx => tx.IsContractCreation); var code = testRpc.StateReader .GetCode(testRpc.BlockTree.Head.StateRoot, ContractAddress.From(TestItem.Addresses[0], 0)); code.Should().NotBeEmpty(); }
public async Task deploy_deploys_the_contract() { var spec = new SingleReleaseSpecProvider(ConstantinopleFix.Instance, 1); TestRpcBlockchain testRpc = await TestRpcBlockchain.ForTest(SealEngineType.NethDev).Build(spec); testRpc.TestWallet.UnlockAccount(TestItem.Addresses[0], new SecureString()); await testRpc.AddFunds(TestItem.Addresses[0], 1.Ether()); DepositModule depositModule = new DepositModule( testRpc.TxPoolBridge, testRpc.LogFinder, new DepositConfig() { DepositContractAddress = TestItem.AddressA.ToString() }, LimboLogs.Instance); var result = await depositModule.deposit_deploy(TestItem.Addresses[0]); result.Data.Should().NotBe(null); result.ErrorCode.Should().Be(0); result.Result.Error.Should().BeNull(); result.Result.ResultType.Should().Be(ResultType.Success); await testRpc.AddBlock(); testRpc.BlockTree.Head.Number.Should().Be(5); testRpc.BlockTree.Head.Transactions.Should().Contain(tx => tx.IsContractCreation); var code = testRpc.StateReader .GetCode(testRpc.BlockTree.Head.StateRoot, ContractAddress.From(TestItem.Addresses[0], 0)); code.Should().NotBeEmpty(); }
public void Can_estimate_with_single_call() { byte[] initByteCode = Prepare.EvmCode .ForInitOf(Bytes.FromHexString("6000")).Done; Address contractAddress = ContractAddress.From(TestItem.PrivateKeyA.Address, 0); byte[] byteCode = Prepare.EvmCode .Call(contractAddress, 46179).Done; long gasLimit = 100000; Transaction initTx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, 1).WithInit(initByteCode).WithGasLimit(gasLimit).TestObject; Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, 1).WithInit(byteCode).WithGasLimit(gasLimit).WithNonce(1).TestObject; Block block = Build.A.Block.WithNumber(MainNetSpecProvider.MuirGlacierBlockNumber).WithTransactions(tx).WithGasLimit(2 * gasLimit).TestObject; IntrinsicGasCalculator gasCalculator = new IntrinsicGasCalculator(); long intrinsic = gasCalculator.Calculate(tx, MuirGlacier.Instance); _transactionProcessor.Execute(initTx, block.Header, NullTxTracer.Instance); EstimateGasTracer tracer = new EstimateGasTracer(); _transactionProcessor.CallAndRestore(tx, block.Header, tracer); long actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; actualIntrinsic.Should().Be(53000); tracer.AdditionalGasRequired.Should().Be(1); tracer.GasSpent.Should().Be(53724); long estimate = tracer.GasSpent + tracer.AdditionalGasRequired; estimate.Should().Be(53725); }
public async Task deploy_deploys_the_contract() { var spec = new SingleReleaseSpecProvider(ConstantinopleFix.Instance, 1); TestRpcBlockchain testRpc = await TestRpcBlockchain.ForTest(SealEngineType.NethDev).Build(spec); testRpc.TestWallet.UnlockAccount(TestItem.Addresses[0], new SecureString()); await testRpc.AddFunds(TestItem.Addresses[0], 1.Ether()); BaselineModule baselineModule = new BaselineModule( testRpc.TxSender, testRpc.StateReader, testRpc.LogFinder, testRpc.BlockTree, _abiEncoder, _fileSystem, new MemDb(), LimboLogs.Instance); var result = await baselineModule.baseline_deploy(TestItem.Addresses[0], "MerkleTreeSHA"); result.Data.Should().NotBe(null); result.ErrorCode.Should().Be(0); result.Result.Error.Should().BeNull(); result.Result.ResultType.Should().Be(ResultType.Success); await testRpc.AddBlock(); testRpc.BlockTree.Head.Number.Should().Be(5); testRpc.BlockTree.Head.Transactions.Should().Contain(tx => tx.IsContractCreation); var code = testRpc.StateReader .GetCode(testRpc.BlockTree.Head.StateRoot, ContractAddress.From(TestItem.Addresses[0], 0)); code.Should().NotBeEmpty(); }
private (Address sender, Address recipient) ExtractSenderAndRecipient(PublicEntry entry) { var sender = entry.SenderAddress.ToAddress(); var recipient = entry.ReceiverAddress.ToAddress(); if (entry.IsValidDeploymentEntry) { recipient = ContractAddress.From(sender, _stateProvider.GetNonce(sender)); } return(sender, recipient); }
private void RecoverReceiptData(IReleaseSpec releaseSpec, TxReceipt receipt, Block block, Transaction transaction, int transactionIndex, long gasUsedBefore) { receipt.BlockHash = block.Hash; receipt.BlockNumber = block.Number; receipt.TxHash = transaction.Hash; receipt.Index = transactionIndex; receipt.Sender = transaction.SenderAddress ?? _ecdsa.RecoverAddress(transaction, !releaseSpec.ValidateChainId); receipt.Recipient = transaction.IsContractCreation ? null : transaction.To; // how would it be in CREATE2? receipt.ContractAddress = transaction.IsContractCreation ? ContractAddress.From(receipt.Sender, transaction.Nonce) : null; receipt.GasUsed = receipt.GasUsedTotal - gasUsedBefore; if (receipt.StatusCode != StatusCode.Success) { receipt.StatusCode = receipt.Logs.Length == 0 ? StatusCode.Failure : StatusCode.Success; } }
public void Newly_created_empty_account_returns_empty_data_hash() { byte[] code = Prepare.EvmCode .Create(Bytes.Empty, 0) .PushData(ContractAddress.From(Recipient, 0)) .Op(Instruction.EXTCODEHASH) .PushData(0) .Op(Instruction.SSTORE) .Done; Execute(code); // todo: so far EIP does not define whether it should be zero or empty data AssertStorage(0, Keccak.OfAnEmptyString); Assert.True(TestState.AccountExists(ContractAddress.From(Recipient, 0)), "did not test the right thing - it was not a newly created empty account scenario"); }
private async Task <ScenarioBuilder> DeployContractAsync() { await ExecuteAntecedentIfNeeded(); _contractAddress = ContractAddress.From(_address, 0L); byte[] bytecode = await GetContractBytecode("BadContract"); Transaction tx = new(); tx.Value = 0; tx.Data = bytecode; tx.GasLimit = 1000000; tx.GasPrice = 20.GWei(); tx.SenderAddress = _address; await _testRpcBlockchain.TxSender.SendTransaction(tx, TxHandlingOptions.ManagedNonce | TxHandlingOptions.PersistentBroadcast); return(this); }
public async Task Tree_tracker_reorganization([ValueSource(nameof(ReorganizationTestCases))] ReorganizedInsertLeafTest test) { Address address = TestItem.Addresses[0]; (TestRpcBlockchain TestRpc, BaselineModule BaselineModule)result = await InitializeTestRpc(address); TestRpcBlockchain testRpc = result.TestRpc; BaselineTree baselineTree = BuildATree(); Address contractAddress = ContractAddress.From(address, 0L); BaselineTreeHelper baselineTreeHelper = new (testRpc.LogFinder, _baselineDb, _metadataBaselineDb, LimboNoErrorLogger.Instance); _ = new BaselineTreeTracker(contractAddress, baselineTree, testRpc.BlockProcessor, baselineTreeHelper, testRpc.BlockFinder, LimboNoErrorLogger.Instance); MerkleTreeSHAContract contract = new (_abiEncoder, contractAddress); for (int i = 0; i < test.LeavesInBlocksCounts.Length; i++) { InsertLeafFromArray(test.LeavesInTransactionsAndBlocks[i], testRpc, contract, address); await testRpc.AddBlock(); Assert.AreEqual(test.LeavesInBlocksCounts[i], baselineTree.Count); } int initBlocksCount = 4; int allBlocksCount = initBlocksCount + test.LeavesInBlocksCounts.Length; TestBlockProducer testRpcBlockProducer = (TestBlockProducer)testRpc.BlockProducer; Block lastProducedBlock = null; testRpcBlockProducer.BlockProduced += (o, e) => lastProducedBlock = e.Block; testRpcBlockProducer.BlockParent = testRpc.BlockTree.FindHeader(allBlocksCount); InsertLeafFromArray(test.LeavesInMiddleOfReorganization, testRpc, contract, address); await testRpc.AddBlock(false); testRpcBlockProducer.BlockParent = lastProducedBlock.Header; InsertLeafFromArray(test.LeavesInAfterReorganization, testRpc, contract, address); await testRpc.AddBlock(); Assert.AreEqual(test.FinalLeavesCount, baselineTree.Count); }
public async Task Tree_tracker_reorganization([ValueSource(nameof(ReorganizationTestCases))] ReorganizedInsertLeafTest test) { var address = TestItem.Addresses[0]; var result = await InitializeTestRpc(address); var testRpc = result.TestRpc; BaselineTree baselineTree = BuildATree(); var fromContractAdress = ContractAddress.From(address, 0L); var baselineTreeHelper = new BaselineTreeHelper(testRpc.LogFinder, _baselineDb, _metadataBaselineDb, LimboNoErrorLogger.Instance); new BaselineTreeTracker(fromContractAdress, baselineTree, testRpc.BlockProcessor, baselineTreeHelper, testRpc.BlockFinder, LimboNoErrorLogger.Instance); var contract = new MerkleTreeSHAContract(_abiEncoder, fromContractAdress); UInt256 nonce = 1L; for (int i = 0; i < test.LeavesInBlocksCounts.Length; i++) { nonce = await InsertLeafFromArray(test.LeavesInTransactionsAndBlocks[i], nonce, testRpc, contract, address); await testRpc.AddBlock(); Assert.AreEqual(test.LeavesInBlocksCounts[i], baselineTree.Count); } var initBlocksCount = 4; var allBlocksCount = initBlocksCount + test.LeavesInBlocksCounts.Length; testRpc.BlockProducer.BlockParent = testRpc.BlockTree.FindHeader(allBlocksCount); nonce = 1L; nonce = await InsertLeafFromArray(test.LeavesInMiddleOfReorganization, nonce, testRpc, contract, address); await testRpc.AddBlock(false); testRpc.BlockProducer.BlockParent = testRpc.BlockProducer.LastProducedBlock.Header; await InsertLeafFromArray(test.LeavesInAfterReorganization, nonce, testRpc, contract, address); await testRpc.AddBlock(); Assert.AreEqual(test.FinalLeavesCount, baselineTree.Count); }
public void Can_self_destruct() { var delta = EntryUtils.PrepareSingleContractEntryDelta(null, _senderPublicKey, 0, "0x730001020304050607080910111213141516171819ff"); delta.PublicEntries[0].GasLimit = 1_000_000L; delta.PublicEntries[0].ReceiverAddress = ByteString.Empty; delta.PublicEntries[0].Signature = delta.PublicEntries[0] .GenerateSignature(_cryptoContext, _senderPrivateKey, _signingContext); var tracer = Substitute.For <ITxTracer>(); tracer.IsTracingReceipt.Returns(true); _executor.Execute(delta, tracer); var contractAddress = ContractAddress.From(_senderPublicKey.ToKvmAddress(), 0); tracer.Received().MarkAsSuccess(contractAddress, 34343, Arg.Any <byte[]>(), Arg.Any <LogEntry[]>()); }
public void Fails_when_not_enough_gas_for_code_deposit() { var delta = EntryUtils.PrepareSingleContractEntryDelta(null, _senderPublicKey, 0, "0x60016000526001601FF300"); delta.PublicEntries[0].GasLimit = 53369; delta.PublicEntries[0].ReceiverAddress = ByteString.Empty; delta.PublicEntries[0].Signature = delta.PublicEntries[0] .GenerateSignature(_cryptoContext, _senderPrivateKey, _signingContext); var tracer = Substitute.For <ITxTracer>(); tracer.IsTracingReceipt.Returns(true); _executor.Execute(delta, tracer); var contractAddress = ContractAddress.From(_senderPublicKey.ToKvmAddress(), 0); tracer.Received().MarkAsFailed(contractAddress, 53369, Arg.Any <byte[]>(), null); }
public void Can_deploy_code_read_only() { var delta = EntryUtils.PrepareSingleContractEntryDelta(null, _senderPublicKey, 0, "0x60016000526001601FF300"); delta.PublicEntries[0].GasLimit = 1_000_000L; delta.PublicEntries[0].ReceiverAddress = ByteString.Empty; delta.PublicEntries[0].Signature = delta.PublicEntries[0] .GenerateSignature(_cryptoContext, _senderPrivateKey, _signingContext); var tracer = Substitute.For <ITxTracer>(); tracer.IsTracingReceipt.Returns(true); _executor.CallAndReset(delta, tracer); var contractAddress = ContractAddress.From(_senderPublicKey.ToKvmAddress(), 0); tracer.Received().MarkAsSuccess(contractAddress, 53370, Arg.Any <byte[]>(), Arg.Any <LogEntry[]>()); }
public void Does_not_crash_on_kvm_error() { // here we test a case when we deploy a contract where constructor throws invalid opcode EVM error // 0xfe is a bad opcode that immediately causes an EVM error var delta = EntryUtils.PrepareSingleContractEntryDelta(null, _senderPublicKey, 0, "0xfe"); delta.PublicEntries[0].GasLimit = 1_000_000L; delta.PublicEntries[0].Signature = delta.PublicEntries[0] .GenerateSignature(_cryptoContext, _senderPrivateKey, _signingContext); var tracer = Substitute.For <ITxTracer>(); tracer.IsTracingReceipt.Returns(true); _executor.Execute(delta, tracer); var contractAddress = ContractAddress.From(_senderPublicKey.ToKvmAddress(), 0); tracer.Received().MarkAsFailed(contractAddress, 1_000_000L, Arg.Any <byte[]>(), "BadInstruction"); }
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 Regression_mainnet_226522() { _blockNumber = 1; Address deployed = ContractAddress.From(TestItem.AddressC, 0); StorageCell storageCell = new StorageCell(deployed, 1); byte[] deployedCode = new byte[106]; // cost is * 200 byte[] initCode = Prepare.EvmCode .PushData(1) .PushData(1) .Op(Instruction.SSTORE) .PushData(0) .PushData(1) .Op(Instruction.SSTORE) // here we reset storage so we would get refund of 15000 gas .ForInitOf(deployedCode).Done; byte[] createCode = Prepare.EvmCode .Create(initCode, 0) .PushData(0) .Op(Instruction.SSTORE) .Done; TestState.CreateAccount(TestItem.AddressC, 1.Ether()); Keccak createCodeHash = TestState.UpdateCode(createCode); TestState.UpdateCodeHash(TestItem.AddressC, createCodeHash, Spec); byte[] code = Prepare.EvmCode .Call(TestItem.AddressC, 32000 + 20003 + 20000 + 5000 + 500 + 0) // not enough .Done; var receipt = Execute(code); byte[] result = Storage.Get(storageCell); Assert.AreEqual(new byte[] { 0 }, result, "storage reverted"); Assert.AreEqual(83199, receipt.GasSpent, "with refund"); byte[] returnData = Storage.Get(new StorageCell(TestItem.AddressC, 0)); Assert.AreEqual(deployed.Bytes, returnData, "address returned"); }
public void Does_not_crash_on_kvm_exception() { // here we test a case when we deploy a contract where constructor throws StackUnderflowException // 0x01 is the ADD opcode which requires two items on the stack and stack is empty here // added here for full coverage as the errors (EVM) are handled differently in some cases (via .NET exceptions) var delta = EntryUtils.PrepareSingleContractEntryDelta(null, _senderPublicKey, 0, "0x01"); delta.PublicEntries[0].GasLimit = 1_000_000L; delta.PublicEntries[0].Signature = delta.PublicEntries[0] .GenerateSignature(_cryptoContext, _senderPrivateKey, _signingContext); var tracer = Substitute.For <ITxTracer>(); tracer.IsTracingReceipt.Returns(true); _executor.Execute(delta, tracer); var contractAddress = ContractAddress.From(_senderPublicKey.ToKvmAddress(), 0); tracer.Received().MarkAsFailed(contractAddress, 1_000_000L, Arg.Any <byte[]>(), "StackUnderflow"); }
private void QuickFail(Transaction tx, BlockHeader block, ITxTracer txTracer, bool eip658NotEnabled, string?reason) { block.GasUsed += tx.GasLimit; Address recipient = tx.To ?? ContractAddress.From( tx.SenderAddress ?? Address.Zero, _stateProvider.GetNonce(tx.SenderAddress ?? Address.Zero)); if (txTracer.IsTracingReceipt) { Keccak?stateRoot = null; if (eip658NotEnabled) { _stateProvider.RecalculateStateRoot(); stateRoot = _stateProvider.StateRoot; } txTracer.MarkAsFailed(recipient, tx.GasLimit, Array.Empty <byte>(), reason ?? "invalid", stateRoot); } }
public async Task can_deposit_32eth() { var spec = new SingleReleaseSpecProvider(ConstantinopleFix.Instance, 1); TestRpcBlockchain testRpc = await TestRpcBlockchain.ForTest(SealEngineType.NethDev).Build(spec); testRpc.TestWallet.UnlockAccount(TestItem.Addresses[0], new SecureString()); await testRpc.AddFunds(TestItem.Addresses[0], 33.Ether()); DepositModule depositModule = new DepositModule( testRpc.TxPoolBridge, testRpc.LogFinder, new DepositConfig(), LimboLogs.Instance); await depositModule.deposit_deploy(TestItem.Addresses[0]); await testRpc.AddBlock(); var contractAddress = ContractAddress.From(TestItem.Addresses[0], 0); await depositModule.deposit_setContractAddress(contractAddress); var result = await depositModule.deposit_make( TestItem.Addresses[0], new byte[48], new byte[32], new byte[96]); result.Data.Should().NotBe(null); result.ErrorCode.Should().Be(0); result.Result.Error.Should().BeNull(); result.Result.ResultType.Should().Be(ResultType.Success); await testRpc.AddBlock(); testRpc.BlockTree.Head.Transactions.Should().Contain(tx => !tx.IsContractCreation); /* if status is 1 then it means that no revert has been made */ testRpc.ReceiptStorage.Get(testRpc.BlockTree.Head)[0].StatusCode.Should().Be(1); }
public async Task can_getLogs() { var spec = new SingleReleaseSpecProvider(ConstantinopleFix.Instance, 1); TestRpcBlockchain testRpc = await TestRpcBlockchain.ForTest(SealEngineType.NethDev).Build(spec); testRpc.TestWallet.UnlockAccount(TestItem.Addresses[0], new SecureString()); await testRpc.AddFunds(TestItem.Addresses[0], 33.Ether()); DepositModule depositModule = new DepositModule( testRpc.TxPoolBridge, testRpc.LogFinder, new DepositConfig() { DepositContractAddress = TestItem.AddressA.ToString() }, LimboLogs.Instance); await depositModule.deposit_deploy(TestItem.Addresses[0]); await testRpc.AddBlock(); var contractAddress = ContractAddress.From(TestItem.Addresses[0], 0); await depositModule.deposit_setContractAddress(contractAddress); await depositModule.deposit_make( TestItem.Addresses[0], GetNonZeroBytes(48), GetNonZeroBytes(32), GetNonZeroBytes(96)); await testRpc.AddBlock(); var all = depositModule.deposit_getAll(); all.Result.Data.Length.Should().Be(1); ulong amount = BinaryPrimitives.ReadUInt64LittleEndian(all.Result.Data[0].Amount); ((BigInteger)amount).Should().Be((BigInteger)32.Ether() / (BigInteger)1.GWei()); }
public void Can_estimate_with_destroy_refund_and_below_intrinsic() { byte[] initByteCode = Prepare.EvmCode.ForInitOf(Prepare.EvmCode.PushData(Address.Zero).Op(Instruction.SELFDESTRUCT).Done).Done; Address contractAddress = ContractAddress.From(TestItem.PrivateKeyA.Address, 0); byte[] byteCode = Prepare.EvmCode .Call(contractAddress, 46179) .Op(Instruction.STOP).Done; long gasLimit = 100000; Transaction initTx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, _isEip155Enabled).WithInit(initByteCode).WithGasLimit(gasLimit).TestObject; Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, _isEip155Enabled).WithInit(byteCode).WithGasLimit(gasLimit).WithNonce(1).TestObject; Block block = Build.A.Block.WithNumber(MainnetSpecProvider.MuirGlacierBlockNumber).WithTransactions(tx).WithGasLimit(2 * gasLimit).TestObject; IntrinsicGasCalculator gasCalculator = new IntrinsicGasCalculator(); long intrinsic = gasCalculator.Calculate(tx, MuirGlacier.Instance); _transactionProcessor.Execute(initTx, block.Header, NullTxTracer.Instance); EstimateGasTracer tracer = new EstimateGasTracer(); GethLikeTxTracer gethTracer = new GethLikeTxTracer(GethTraceOptions.Default); _transactionProcessor.CallAndRestore(tx, block.Header, tracer); _transactionProcessor.CallAndRestore(tx, block.Header, gethTracer); TestContext.WriteLine(new EthereumJsonSerializer().Serialize(gethTracer.BuildResult(), true)); long actualIntrinsic = tx.GasLimit - tracer.IntrinsicGasAt; actualIntrinsic.Should().Be(intrinsic); tracer.CalculateAdditionalGasRequired(tx).Should().Be(24080); tracer.GasSpent.Should().Be(35228L); long estimate = tracer.CalculateEstimate(tx); estimate.Should().Be(59308); ConfirmEnoughEstimate(tx, block, estimate); }