-
Notifications
You must be signed in to change notification settings - Fork 726
Expand file tree
/
Copy pathTransactionProcessorWarmupTests.cs
More file actions
83 lines (74 loc) · 3.63 KB
/
Copy pathTransactionProcessorWarmupTests.cs
File metadata and controls
83 lines (74 loc) · 3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// SPDX-FileCopyrightText: 2026 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only
using System;
using Nethermind.Blockchain;
using Nethermind.Core;
using Nethermind.Core.Extensions;
using Nethermind.Core.Specs;
using Nethermind.Core.Test;
using Nethermind.Core.Test.Builders;
using Nethermind.Crypto;
using Nethermind.Evm.State;
using Nethermind.Evm.Tracing;
using Nethermind.Evm.TransactionProcessing;
using Nethermind.Int256;
using Nethermind.Logging;
using Nethermind.Specs;
using Nethermind.Specs.Forks;
using NUnit.Framework;
namespace Nethermind.Evm.Test;
public class TransactionProcessorWarmupTests
{
private ISpecProvider _specProvider = null!;
private IEthereumEcdsa _ethereumEcdsa = null!;
private ITransactionProcessor _transactionProcessor = null!;
private IWorldState _stateProvider = null!;
private IDisposable _worldStateCloser = null!;
[SetUp]
public void Setup()
{
_specProvider = new TestSpecProvider(Prague.Instance);
_stateProvider = TestWorldStateFactory.CreateForTest();
_worldStateCloser = _stateProvider.BeginScope(IWorldState.PreGenesis);
EthereumCodeInfoRepository codeInfoRepository = new(_stateProvider);
EthereumVirtualMachine virtualMachine = new(new TestBlockhashProvider(_specProvider), _specProvider, LimboLogs.Instance);
_transactionProcessor = new EthereumTransactionProcessor(BlobBaseFeeCalculator.Instance, _specProvider, _stateProvider, virtualMachine, codeInfoRepository, LimboLogs.Instance);
_ethereumEcdsa = new EthereumEcdsa(_specProvider.ChainId);
}
[TearDown]
public void TearDown() => _worldStateCloser?.Dispose();
// Warmup must take the real execution path: no-op fee/nonce handling made same-sender
// warm sequences run with undebited balances and unbumped nonces, so deploy chains
// computed wrong CREATE addresses and warmed the wrong state.
[Test]
public void Warmup_InTheThrowawayScope_DebitsFeesAndBumpsTheNonce()
{
_stateProvider.CreateAccount(TestItem.AddressA, 1.Ether);
_stateProvider.Commit(_specProvider.GenesisSpec);
_stateProvider.CommitTree(0);
Transaction tx = Build.A.Transaction
.WithGasPrice(1)
.WithMaxFeePerGas(1)
.WithTo(TestItem.AddressB)
.WithValue(100.GWei)
.WithGasLimit(100_000)
.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA)
.TestObject;
Block block = Build.A.Block
.WithNumber(long.MaxValue)
.WithTimestamp(MainnetSpecProvider.PragueBlockTimestamp)
.WithTransactions(tx)
.WithGasLimit(10_000_000)
.TestObject;
UInt256 balanceBefore = _stateProvider.GetBalance(TestItem.AddressA);
_transactionProcessor.SetBlockExecutionContext(new BlockExecutionContext(block.Header, _specProvider.GetSpec(block.Header)));
TransactionResult result = _transactionProcessor.Warmup(tx, NullTxTracer.Instance);
Assert.That(result.TransactionExecuted, Is.True, "precondition: the warm execution ran");
Assert.That(_stateProvider.GetNonce(TestItem.AddressA), Is.EqualTo(1UL),
"a warm execution must bump the nonce so a same-sender successor warms the right state");
Assert.That(_stateProvider.GetBalance(TestItem.AddressA), Is.EqualTo(balanceBefore - 100.GWei - 21_000),
"a warm execution must debit value and gas so successors see real balances");
Assert.That(tx.BlockGasUsed, Is.EqualTo(100_000UL),
"warmup must never mutate the shared transaction object: the getter must still fall back to the gas limit");
}
}