diff --git a/src/Nethermind/Ethereum.VM.Test/VMTestBase.cs b/src/Nethermind/Ethereum.VM.Test/VMTestBase.cs index d443ea23eef..21e5a05caa4 100644 --- a/src/Nethermind/Ethereum.VM.Test/VMTestBase.cs +++ b/src/Nethermind/Ethereum.VM.Test/VMTestBase.cs @@ -193,7 +193,7 @@ protected void RunTest(VirtualMachineTest test) } } - EvmState state = new EvmState((long)test.Execution.Gas, environment, ExecutionType.Transaction, true, false); + EvmState state = new EvmState((long)test.Execution.Gas, environment, ExecutionType.Transaction, true, 0, 0, false); _storageProvider.Commit(); _stateProvider.Commit(Olympic.Instance); diff --git a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs index a2703a6fb15..69360713104 100644 --- a/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/TransactionProcessorTests.cs @@ -18,6 +18,7 @@ using FluentAssertions; using Nethermind.Core; using Nethermind.Core.Attributes; +using Nethermind.Core.Eip2930; using Nethermind.Core.Extensions; using Nethermind.Core.Specs; using Nethermind.Specs; @@ -183,12 +184,23 @@ public void Can_handle_quick_fail_on_invalid_nonce(bool withStateDiff, bool with [TestCase(true, false)] [TestCase(false, true)] [TestCase(false, false)] - public void Can_handle_quick_fail_on_not_enough_balance(bool withStateDiff, bool withTrace) + public void Can_handle_quick_fail_on_not_enough_balance_on_intrinsic_gas(bool withStateDiff, bool withTrace) { - Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, _isEip155Enabled).WithGasLimit(100000).TestObject; - tx.Value = 2.Ether(); + AccessListBuilder accessListBuilder = new(); + foreach (Address address in TestItem.Addresses) + { + accessListBuilder.AddAddress(address); + } + + Transaction tx = Build.A.Transaction + .WithGasLimit(GasCostOf.Transaction * 2) + .WithAccessList(accessListBuilder.ToAccessList()) + .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, _isEip155Enabled) + .TestObject; - Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject; + tx.Value = 1.Ether() - 3 * GasCostOf.Transaction; + + Block block = Build.A.Block.WithNumber(MainnetSpecProvider.BerlinBlockNumber).WithTransactions(tx).TestObject; BlockReceiptsTracer tracer = BuildTracer(block, tx, withStateDiff, withTrace); Execute(tracer, tx, block); @@ -196,6 +208,26 @@ public void Can_handle_quick_fail_on_not_enough_balance(bool withStateDiff, bool Assert.AreEqual(StatusCode.Failure, tracer.TxReceipts[0].StatusCode); } + [TestCase(true, true)] + [TestCase(true, false)] + [TestCase(false, true)] + [TestCase(false, false)] + public void Can_handle_quick_fail_on_not_enough_balance_on_reserved_gas_payment(bool withStateDiff, bool withTrace) + { + Transaction tx = Build.A.Transaction + .WithGasLimit(GasCostOf.Transaction * 2) + .SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, _isEip155Enabled) + .TestObject; + + tx.Value = 1.Ether() - GasCostOf.Transaction; + + Block block = Build.A.Block.WithNumber(MainnetSpecProvider.BerlinBlockNumber).WithTransactions(tx).TestObject; + + BlockReceiptsTracer tracer = BuildTracer(block, tx, withStateDiff, withTrace); + Execute(tracer, tx, block); + + Assert.AreEqual(StatusCode.Failure, tracer.TxReceipts[0].StatusCode); + } [TestCase(true, true)] [TestCase(true, false)] @@ -209,7 +241,7 @@ public void Can_handle_quick_fail_when_balance_is_lower_than_fee_cap_times_gas(b .WithType(TxType.EIP1559) .WithGasLimit(100000).TestObject; - Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject; + Block block = Build.A.Block.WithNumber(MainnetSpecProvider.LondonBlockNumber).WithTransactions(tx).TestObject; BlockReceiptsTracer tracer = BuildTracer(block, tx, withStateDiff, withTrace); Execute(tracer, tx, block); diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index 0851674ec1c..2b3f96b3ee4 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -217,14 +217,14 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra if (notSystemTransaction) { UInt256 senderBalance = _stateProvider.GetBalance(caller); - if (!restore && ((ulong) intrinsicGas * gasPrice + value > senderBalance || senderReservedGasPayment > senderBalance)) + if (!restore && ((ulong) intrinsicGas * gasPrice + value > senderBalance || senderReservedGasPayment + value > senderBalance)) { TraceLogInvalidTx(transaction, $"INSUFFICIENT_SENDER_BALANCE: ({caller})_BALANCE = {senderBalance}"); QuickFail(transaction, block, txTracer, eip658NotEnabled, "insufficient sender balance"); return; } - if (!restore && transaction.IsEip1559 && !transaction.IsServiceTransaction && senderBalance < (UInt256)transaction.GasLimit * transaction.MaxFeePerGas) + if (!restore && spec.IsEip1559Enabled && !transaction.IsServiceTransaction && senderBalance < (UInt256)transaction.GasLimit * transaction.MaxFeePerGas + value) { TraceLogInvalidTx(transaction, $"INSUFFICIENT_MAX_FEE_PER_GAS_FOR_SENDER_BALANCE: ({caller})_BALANCE = {senderBalance}, MAX_FEE_PER_GAS: {transaction.MaxFeePerGas}"); QuickFail(transaction, block, txTracer, eip658NotEnabled, "insufficient MaxFeePerGas for sender balance");