public void Throws_on_theoretical_contract_crash() { var contractAddress = Address.OfContract(_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 Fails_on_wrong_nonce() { var delta = EntryUtils.PrepareSingleContractEntryDelta(_recipient, _senderPublicKey, 0, "0x", 1); 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(_recipient.ToKvmAddress(), 21000, Bytes.Empty, "invalid"); }
public void Can_add_gas_to_existing_balance() { var delta = EntryUtils.PrepareSingleContractEntryDelta(_recipient, _senderPublicKey, 0); delta.PublicEntries[0].GasPrice = 1.ToUint256ByteString(); 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().MarkAsSuccess(_recipient.ToKvmAddress(), 21000, Bytes.Empty, Arg.Any <LogEntry[]>()); }
public void Fails_when_tx_beyond_delta_gas_limit() { var delta = EntryUtils.PrepareSingleContractEntryDelta(_recipient, _senderPublicKey, 0); delta.PublicEntries[0].GasLimit = 10_000_000; 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(_recipient.ToKvmAddress(), 10_000_000, Bytes.Empty, "invalid"); }
public void Fails_when_gas_limit_below_data_intrinsic_cost() { var delta = EntryUtils.PrepareSingleContractEntryDelta(_recipient, _senderPublicKey, 0, "0x0102"); delta.PublicEntries[0].GasLimit = 21001; // just above 21000 but not paying for data 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(_recipient.ToKvmAddress(), 21001, Bytes.Empty, "invalid"); }
public void Fails_on_insufficient_balance() { var delta = EntryUtils.PrepareSingleContractEntryDelta(_recipient, _poorSender, 0); // when gas price is non-zero then sender needs to have a non-zero balance to pay for the gas cost delta.PublicEntries[0].GasPrice = 1.ToUint256ByteString(); 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(_recipient.ToKvmAddress(), 21000, Bytes.Empty, "invalid"); }
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 = Address.OfContract(_senderPublicKey.ToKvmAddress(), 0); tracer.Received().MarkAsFailed(contractAddress, 1_000_000L, Arg.Any <byte[]>(), "Error"); }
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.CallAndRestore(delta, tracer); var contractAddress = Address.OfContract(_senderPublicKey.ToKvmAddress(), 0); tracer.Received().MarkAsSuccess(contractAddress, 53370, 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 = Address.OfContract(_senderPublicKey.ToKvmAddress(), 0); tracer.Received().MarkAsFailed(contractAddress, 53369, Arg.Any <byte[]>(), null); }
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 = Address.OfContract(_senderPublicKey.ToKvmAddress(), 0); tracer.Received().MarkAsSuccess(contractAddress, 34343, Arg.Any <byte[]>(), Arg.Any <LogEntry[]>()); }
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 = Address.OfContract(_senderPublicKey.ToKvmAddress(), 0); tracer.Received().MarkAsFailed(contractAddress, 1_000_000L, Arg.Any <byte[]>(), "Error"); }
public void Update_storage_root_on_contract_clash() { var contractAddress = Address.OfContract(_senderPublicKey.ToKvmAddress(), 0); _stateProvider.CreateAccount(contractAddress, 1000.Kat()); _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().MarkAsSuccess(contractAddress, 53370, Arg.Any <byte[]>(), Arg.Any <LogEntry[]>()); }