16
16
17
17
import static org .assertj .core .api .Assertions .assertThat ;
18
18
import static org .mockito .ArgumentMatchers .any ;
19
+ import static org .mockito .Mockito .doAnswer ;
19
20
import static org .mockito .Mockito .when ;
20
21
21
22
import org .hyperledger .besu .datatypes .Address ;
23
+ import org .hyperledger .besu .datatypes .Hash ;
24
+ import org .hyperledger .besu .datatypes .Wei ;
22
25
import org .hyperledger .besu .ethereum .chain .Blockchain ;
23
26
import org .hyperledger .besu .ethereum .core .ProcessableBlockHeader ;
24
27
import org .hyperledger .besu .ethereum .core .Transaction ;
25
28
import org .hyperledger .besu .ethereum .core .feemarket .CoinbaseFeePriceCalculator ;
26
29
import org .hyperledger .besu .ethereum .mainnet .feemarket .FeeMarket ;
27
30
import org .hyperledger .besu .ethereum .transaction .TransactionInvalidReason ;
28
31
import org .hyperledger .besu .ethereum .vm .BlockHashLookup ;
32
+ import org .hyperledger .besu .evm .account .EvmAccount ;
33
+ import org .hyperledger .besu .evm .account .MutableAccount ;
34
+ import org .hyperledger .besu .evm .frame .MessageFrame ;
29
35
import org .hyperledger .besu .evm .gascalculator .GasCalculator ;
36
+ import org .hyperledger .besu .evm .gascalculator .LondonGasCalculator ;
30
37
import org .hyperledger .besu .evm .processor .AbstractMessageProcessor ;
31
38
import org .hyperledger .besu .evm .worldstate .WorldUpdater ;
32
39
33
- import org .junit .Before ;
40
+ import java .util .Optional ;
41
+ import java .util .concurrent .atomic .AtomicBoolean ;
42
+
43
+ import org .apache .tuweni .bytes .Bytes ;
34
44
import org .junit .Test ;
35
45
import org .junit .runner .RunWith ;
36
46
import org .mockito .ArgumentCaptor ;
@@ -42,9 +52,7 @@ public class MainnetTransactionProcessorTest {
42
52
43
53
private static final int MAX_STACK_SIZE = 1024 ;
44
54
45
- private MainnetTransactionProcessor transactionProcessor ;
46
-
47
- @ Mock private GasCalculator gasCalculator ;
55
+ private final GasCalculator gasCalculator = new LondonGasCalculator ();
48
56
@ Mock private MainnetTransactionValidator transactionValidator ;
49
57
@ Mock private AbstractMessageProcessor contractCreationProcessor ;
50
58
@ Mock private AbstractMessageProcessor messageCallProcessor ;
@@ -55,18 +63,78 @@ public class MainnetTransactionProcessorTest {
55
63
@ Mock private Transaction transaction ;
56
64
@ Mock private BlockHashLookup blockHashLookup ;
57
65
58
- @ Before
59
- public void before () {
60
- transactionProcessor =
61
- new MainnetTransactionProcessor (
62
- gasCalculator ,
63
- transactionValidator ,
64
- contractCreationProcessor ,
65
- messageCallProcessor ,
66
- false ,
67
- MAX_STACK_SIZE ,
68
- FeeMarket .legacy (),
69
- CoinbaseFeePriceCalculator .frontier ());
66
+ @ Mock private EvmAccount senderAccount ;
67
+ @ Mock private MutableAccount mutableSenderAccount ;
68
+
69
+ MainnetTransactionProcessor createTransactionProcessor (final boolean warmCoinbase ) {
70
+ return new MainnetTransactionProcessor (
71
+ gasCalculator ,
72
+ transactionValidator ,
73
+ contractCreationProcessor ,
74
+ messageCallProcessor ,
75
+ false ,
76
+ warmCoinbase ,
77
+ MAX_STACK_SIZE ,
78
+ FeeMarket .legacy (),
79
+ CoinbaseFeePriceCalculator .frontier ());
80
+ }
81
+
82
+ @ Test
83
+ public void shouldWarmCoinbaseIfRequested () {
84
+ Optional <Address > toAddresss =
85
+ Optional .of (Address .fromHexString ("0x2222222222222222222222222222222222222222" ));
86
+ when (transaction .getTo ()).thenReturn (toAddresss );
87
+ Address senderAddress = Address .fromHexString ("0x5555555555555555555555555555555555555555" );
88
+ Address coinbaseAddress = Address .fromHexString ("0x4242424242424242424242424242424242424242" );
89
+
90
+ when (senderAccount .getMutable ()).thenReturn (mutableSenderAccount );
91
+ when (transaction .getHash ()).thenReturn (Hash .EMPTY );
92
+ when (transaction .getPayload ()).thenReturn (Bytes .EMPTY );
93
+ when (transaction .getSender ()).thenReturn (senderAddress );
94
+ when (transaction .getValue ()).thenReturn (Wei .ZERO );
95
+ when (transactionValidator .validate (any (), any (), any ())).thenReturn (ValidationResult .valid ());
96
+ when (transactionValidator .validateForSender (any (), any (), any ()))
97
+ .thenReturn (ValidationResult .valid ());
98
+ when (worldState .getOrCreate (any ())).thenReturn (senderAccount );
99
+ when (worldState .getOrCreateSenderAccount (any ())).thenReturn (senderAccount );
100
+ when (worldState .updater ()).thenReturn (worldState );
101
+
102
+ AtomicBoolean coinbaseWarmed = new AtomicBoolean (false );
103
+ doAnswer (
104
+ invocation -> {
105
+ MessageFrame messageFrame = invocation .getArgument (0 );
106
+ coinbaseWarmed .set (messageFrame .warmUpAddress (coinbaseAddress ));
107
+ messageFrame .getMessageFrameStack ().pop ();
108
+ return null ;
109
+ })
110
+ .when (messageCallProcessor )
111
+ .process (any (), any ());
112
+
113
+ var transactionProcessor = createTransactionProcessor (true );
114
+ transactionProcessor .processTransaction (
115
+ blockchain ,
116
+ worldState ,
117
+ blockHeader ,
118
+ transaction ,
119
+ coinbaseAddress ,
120
+ blockHashLookup ,
121
+ false ,
122
+ ImmutableTransactionValidationParams .builder ().build ());
123
+
124
+ assertThat (coinbaseWarmed ).isTrue ();
125
+
126
+ transactionProcessor = createTransactionProcessor (false );
127
+ transactionProcessor .processTransaction (
128
+ blockchain ,
129
+ worldState ,
130
+ blockHeader ,
131
+ transaction ,
132
+ coinbaseAddress ,
133
+ blockHashLookup ,
134
+ false ,
135
+ ImmutableTransactionValidationParams .builder ().build ());
136
+
137
+ assertThat (coinbaseWarmed ).isFalse ();
70
138
}
71
139
72
140
@ Test
@@ -77,6 +145,8 @@ public void shouldCallTransactionValidatorWithExpectedTransactionValidationParam
77
145
final TransactionValidationParams expectedValidationParams =
78
146
ImmutableTransactionValidationParams .builder ().build ();
79
147
148
+ var transactionProcessor = createTransactionProcessor (false );
149
+
80
150
transactionProcessor .processTransaction (
81
151
blockchain ,
82
152
worldState ,
0 commit comments