37
37
import org .hyperledger .besu .datatypes .Wei ;
38
38
import org .hyperledger .besu .datatypes .parameters .UnsignedLongParameter ;
39
39
import org .hyperledger .besu .ethereum .GasLimitCalculator ;
40
+ import org .hyperledger .besu .ethereum .api .ApiConfiguration ;
40
41
import org .hyperledger .besu .ethereum .api .jsonrpc .internal .parameters .JsonCallParameter .JsonCallParameterBuilder ;
41
42
import org .hyperledger .besu .ethereum .chain .Blockchain ;
42
43
import org .hyperledger .besu .ethereum .core .BlobTestFixture ;
@@ -93,8 +94,9 @@ public class TransactionSimulatorTest {
93
94
Address .fromHexString ("0x0000000000000000000000000000000000000000" );
94
95
private static final long GAS_CAP = 500000L ;
95
96
private static final long TRANSFER_GAS_LIMIT = 21000L ;
96
- private TransactionSimulator transactionSimulator ;
97
+ private TransactionSimulator uncappedTransactionSimulator ;
97
98
private TransactionSimulator cappedTransactionSimulator ;
99
+ private TransactionSimulator defaultCappedTransactionSimulator ;
98
100
99
101
@ Mock private Blockchain blockchain ;
100
102
@ Mock private WorldStateArchive worldStateArchive ;
@@ -107,12 +109,22 @@ public class TransactionSimulatorTest {
107
109
@ BeforeEach
108
110
public void setUp () {
109
111
final var miningConfiguration = MiningConfiguration .newDefault ().setCoinbase (Address .ZERO );
110
- this .transactionSimulator =
112
+ // rpc gas cap 0 means unlimited
113
+ this .uncappedTransactionSimulator =
111
114
new TransactionSimulator (
112
115
blockchain , worldStateArchive , protocolSchedule , miningConfiguration , 0 );
116
+ // capped at a lower limit
113
117
this .cappedTransactionSimulator =
114
118
new TransactionSimulator (
115
119
blockchain , worldStateArchive , protocolSchedule , miningConfiguration , GAS_CAP );
120
+ // capped at default limit
121
+ this .defaultCappedTransactionSimulator =
122
+ new TransactionSimulator (
123
+ blockchain ,
124
+ worldStateArchive ,
125
+ protocolSchedule ,
126
+ miningConfiguration ,
127
+ ApiConfiguration .DEFAULT_GAS_CAP );
116
128
}
117
129
118
130
@ Test
@@ -174,7 +186,7 @@ public void shouldReturnEmptyWhenBlockDoesNotExist() {
174
186
when (blockchain .getBlockHeader (eq (1L ))).thenReturn (Optional .empty ());
175
187
176
188
final Optional <TransactionSimulatorResult > result =
177
- transactionSimulator .process (legacyTransactionCallParameterBuilder ().build (), 1L );
189
+ uncappedTransactionSimulator .process (legacyTransactionCallParameterBuilder ().build (), 1L );
178
190
179
191
assertThat (result .isPresent ()).isFalse ();
180
192
}
@@ -203,7 +215,7 @@ public void shouldReturnSuccessfulResultWhenProcessingIsSuccessful() {
203
215
mockProcessorStatusForTransaction (expectedTransaction , Status .SUCCESSFUL );
204
216
205
217
final Optional <TransactionSimulatorResult > result =
206
- transactionSimulator .process (callParameter , 1L );
218
+ uncappedTransactionSimulator .process (callParameter , 1L );
207
219
208
220
assertThat (result .get ().isSuccessful ()).isTrue ();
209
221
verifyTransactionWasProcessed (expectedTransaction );
@@ -234,12 +246,12 @@ public void simulateOnPendingBlockWorks() {
234
246
mockProcessorStatusForTransaction (expectedTransaction , Status .SUCCESSFUL );
235
247
236
248
final Optional <TransactionSimulatorResult > result =
237
- transactionSimulator .processOnPending (
249
+ uncappedTransactionSimulator .processOnPending (
238
250
callParameter ,
239
251
Optional .empty (),
240
252
TransactionValidationParams .transactionSimulator (),
241
253
NO_TRACING ,
242
- transactionSimulator .simulatePendingBlockHeader ());
254
+ uncappedTransactionSimulator .simulatePendingBlockHeader ());
243
255
244
256
assertThat (result .get ().isSuccessful ()).isTrue ();
245
257
verifyTransactionWasProcessed (expectedTransaction );
@@ -269,7 +281,7 @@ public void shouldSetGasPriceToZeroWhenExceedingBalanceAllowed() {
269
281
.build ();
270
282
mockProcessorStatusForTransaction (expectedTransaction , Status .SUCCESSFUL );
271
283
272
- transactionSimulator .process (
284
+ uncappedTransactionSimulator .process (
273
285
callParameter ,
274
286
ImmutableTransactionValidationParams .builder ().isAllowExceedingBalance (true ).build (),
275
287
NO_TRACING ,
@@ -306,7 +318,7 @@ public void shouldSetFeePerGasToZeroWhenExceedingBalanceAllowed() {
306
318
307
319
mockProcessorStatusForTransaction (expectedTransaction , Status .SUCCESSFUL );
308
320
309
- transactionSimulator .process (
321
+ uncappedTransactionSimulator .process (
310
322
callParameter ,
311
323
ImmutableTransactionValidationParams .builder ().isAllowExceedingBalance (true ).build (),
312
324
NO_TRACING ,
@@ -340,7 +352,7 @@ public void shouldNotSetGasPriceToZeroWhenExceedingBalanceIsNotAllowed() {
340
352
341
353
mockProcessorStatusForTransaction (expectedTransaction , Status .SUCCESSFUL );
342
354
343
- transactionSimulator .process (
355
+ uncappedTransactionSimulator .process (
344
356
callParameter ,
345
357
ImmutableTransactionValidationParams .builder ().isAllowExceedingBalance (false ).build (),
346
358
NO_TRACING ,
@@ -376,7 +388,7 @@ public void shouldNotSetFeePerGasToZeroWhenExceedingBalanceIsNotAllowed() {
376
388
.build ();
377
389
mockProcessorStatusForTransaction (expectedTransaction , Status .SUCCESSFUL );
378
390
379
- transactionSimulator .process (
391
+ uncappedTransactionSimulator .process (
380
392
callParameter ,
381
393
ImmutableTransactionValidationParams .builder ().isAllowExceedingBalance (false ).build (),
382
394
NO_TRACING ,
@@ -409,7 +421,7 @@ public void shouldUseDefaultValuesWhenMissingOptionalFields() {
409
421
.build ();
410
422
mockProcessorStatusForTransaction (expectedTransaction , Status .SUCCESSFUL );
411
423
412
- transactionSimulator .process (callParameter , 1L );
424
+ uncappedTransactionSimulator .process (callParameter , 1L );
413
425
414
426
verifyTransactionWasProcessed (expectedTransaction );
415
427
}
@@ -438,7 +450,7 @@ public void shouldUseZeroNonceWhenAccountDoesNotExist() {
438
450
.build ();
439
451
mockProcessorStatusForTransaction (expectedTransaction , Status .SUCCESSFUL );
440
452
441
- transactionSimulator .process (callParameter , 1L );
453
+ uncappedTransactionSimulator .process (callParameter , 1L );
442
454
443
455
verifyTransactionWasProcessed (expectedTransaction );
444
456
}
@@ -472,7 +484,7 @@ public void shouldUseSpecifiedNonceWhenProvided() {
472
484
.build ();
473
485
mockProcessorStatusForTransaction (expectedTransaction , Status .SUCCESSFUL );
474
486
475
- transactionSimulator .process (callParameter , 1L );
487
+ uncappedTransactionSimulator .process (callParameter , 1L );
476
488
verifyTransactionWasProcessed (expectedTransaction );
477
489
}
478
490
@@ -501,7 +513,7 @@ public void shouldReturnFailureResultWhenProcessingFails() {
501
513
mockProcessorStatusForTransaction (expectedTransaction , Status .FAILED );
502
514
503
515
final Optional <TransactionSimulatorResult > result =
504
- transactionSimulator .process (callParameter , 1L );
516
+ uncappedTransactionSimulator .process (callParameter , 1L );
505
517
506
518
assertThat (result .get ().isSuccessful ()).isFalse ();
507
519
verifyTransactionWasProcessed (expectedTransaction );
@@ -512,7 +524,8 @@ public void shouldReturnEmptyWhenBlockDoesNotExistByHash() {
512
524
when (blockchain .getBlockHeader (eq (Hash .ZERO ))).thenReturn (Optional .empty ());
513
525
514
526
final Optional <TransactionSimulatorResult > result =
515
- transactionSimulator .process (legacyTransactionCallParameterBuilder ().build (), Hash .ZERO );
527
+ uncappedTransactionSimulator .process (
528
+ legacyTransactionCallParameterBuilder ().build (), Hash .ZERO );
516
529
517
530
assertThat (result .isPresent ()).isFalse ();
518
531
}
@@ -542,7 +555,7 @@ public void shouldReturnSuccessfulResultWhenProcessingIsSuccessfulByHash() {
542
555
mockProcessorStatusForTransaction (expectedTransaction , Status .SUCCESSFUL );
543
556
544
557
final Optional <TransactionSimulatorResult > result =
545
- transactionSimulator .process (callParameter , blockHeader .getBlockHash ());
558
+ uncappedTransactionSimulator .process (callParameter , blockHeader .getBlockHash ());
546
559
547
560
assertThat (result .get ().isSuccessful ()).isTrue ();
548
561
verifyTransactionWasProcessed (expectedTransaction );
@@ -572,7 +585,7 @@ public void shouldUseDefaultValuesWhenMissingOptionalFieldsByHash() {
572
585
.build ();
573
586
mockProcessorStatusForTransaction (expectedTransaction , Status .SUCCESSFUL );
574
587
575
- transactionSimulator .process (callParameter , blockHeader .getBlockHash ());
588
+ uncappedTransactionSimulator .process (callParameter , blockHeader .getBlockHash ());
576
589
577
590
verifyTransactionWasProcessed (expectedTransaction );
578
591
}
@@ -601,7 +614,7 @@ public void shouldUseZeroNonceWhenAccountDoesNotExistByHash() {
601
614
.build ();
602
615
mockProcessorStatusForTransaction (expectedTransaction , Status .SUCCESSFUL );
603
616
604
- transactionSimulator .process (callParameter , blockHeader .getBlockHash ());
617
+ uncappedTransactionSimulator .process (callParameter , blockHeader .getBlockHash ());
605
618
606
619
verifyTransactionWasProcessed (expectedTransaction );
607
620
}
@@ -631,7 +644,7 @@ public void shouldReturnFailureResultWhenProcessingFailsByHash() {
631
644
mockProcessorStatusForTransaction (expectedTransaction , Status .FAILED );
632
645
633
646
final Optional <TransactionSimulatorResult > result =
634
- transactionSimulator .process (callParameter , blockHeader .getBlockHash ());
647
+ uncappedTransactionSimulator .process (callParameter , blockHeader .getBlockHash ());
635
648
636
649
assertThat (result .get ().isSuccessful ()).isFalse ();
637
650
verifyTransactionWasProcessed (expectedTransaction );
@@ -662,7 +675,7 @@ public void shouldReturnSuccessfulResultWhenEip1559TransactionProcessingIsSucces
662
675
mockProcessorStatusForTransaction (expectedTransaction , Status .SUCCESSFUL );
663
676
664
677
final Optional <TransactionSimulatorResult > result =
665
- transactionSimulator .process (callParameter , 1L );
678
+ uncappedTransactionSimulator .process (callParameter , 1L );
666
679
667
680
assertThat (result .get ().isSuccessful ()).isTrue ();
668
681
verifyTransactionWasProcessed (expectedTransaction );
@@ -735,7 +748,7 @@ public void shouldUseProvidedGasLimitWhenBelowRpcCapGas() {
735
748
}
736
749
737
750
@ Test
738
- public void shouldUseRpcGasCapWhenGasLimitNoPresent () {
751
+ public void shouldUseRpcGasCapWhenGasLimitNotPresent () {
739
752
// generate call parameters that do not specify a gas limit,
740
753
// expect the rpc gas cap to be used for simulation
741
754
@@ -769,6 +782,41 @@ public void shouldUseRpcGasCapWhenGasLimitNoPresent() {
769
782
verifyTransactionWasProcessed (expectedTransaction );
770
783
}
771
784
785
+ @ Test
786
+ public void shouldUseDefaultRpcGasCapWhenGasLimitNotPresent () {
787
+ // generate call parameters that do not specify a gas limit,
788
+ // expect the default rpc gas cap to be used for simulation
789
+
790
+ final CallParameter callParameter =
791
+ eip1559TransactionCallParameterBuilder ().withGas (-1L ).build ();
792
+
793
+ mockBlockchainAndWorldState (callParameter );
794
+ mockProtocolSpecForProcessWithWorldUpdater ();
795
+
796
+ final Transaction expectedTransaction =
797
+ Transaction .builder ()
798
+ .type (TransactionType .EIP1559 )
799
+ .chainId (BigInteger .ONE )
800
+ .nonce (1L )
801
+ .gasLimit (callParameter .getGasLimit ())
802
+ .maxFeePerGas (callParameter .getMaxFeePerGas ().orElseThrow ())
803
+ .maxPriorityFeePerGas (callParameter .getMaxPriorityFeePerGas ().orElseThrow ())
804
+ .to (callParameter .getTo ())
805
+ .sender (callParameter .getFrom ())
806
+ .value (callParameter .getValue ())
807
+ .payload (callParameter .getPayload ())
808
+ .signature (FAKE_SIGNATURE )
809
+ .gasLimit (ApiConfiguration .DEFAULT_GAS_CAP )
810
+ .build ();
811
+
812
+ // call process with original transaction
813
+ defaultCappedTransactionSimulator .process (
814
+ callParameter , TransactionValidationParams .transactionSimulator (), NO_TRACING , 1L );
815
+
816
+ // expect transaction with the original gas limit to be processed
817
+ verifyTransactionWasProcessed (expectedTransaction );
818
+ }
819
+
772
820
@ Test
773
821
public void shouldReturnSuccessfulResultWhenBlobTransactionProcessingIsSuccessful () {
774
822
final CallParameter callParameter = blobTransactionCallParameter ();
@@ -780,7 +828,7 @@ public void shouldReturnSuccessfulResultWhenBlobTransactionProcessingIsSuccessfu
780
828
mockProcessorStatusForTransaction (expectedTransaction , Status .SUCCESSFUL );
781
829
782
830
final Optional <TransactionSimulatorResult > result =
783
- transactionSimulator .process (callParameter , 1L );
831
+ uncappedTransactionSimulator .process (callParameter , 1L );
784
832
785
833
assertThat (result .get ().isSuccessful ()).isTrue ();
786
834
verifyTransactionWasProcessed (expectedTransaction );
@@ -797,7 +845,7 @@ public void shouldReturnFailureResultWhenBlobTransactionProcessingFails() {
797
845
mockProcessorStatusForTransaction (expectedTransaction , Status .FAILED );
798
846
799
847
final Optional <TransactionSimulatorResult > result =
800
- transactionSimulator .process (callParameter , 1L );
848
+ uncappedTransactionSimulator .process (callParameter , 1L );
801
849
802
850
assertThat (result .get ().isSuccessful ()).isFalse ();
803
851
verifyTransactionWasProcessed (expectedTransaction );
@@ -980,7 +1028,7 @@ public void shouldSimulateLegacyTransactionWhenBaseFeeNotZero() {
980
1028
mockProcessorStatusForTransaction (expectedTransaction , Status .SUCCESSFUL );
981
1029
982
1030
final Optional <TransactionSimulatorResult > result =
983
- transactionSimulator .process (callParameter , 1L );
1031
+ uncappedTransactionSimulator .process (callParameter , 1L );
984
1032
985
1033
verifyTransactionWasProcessed (expectedTransaction );
986
1034
assertThat (result .get ().isSuccessful ()).isTrue ();
0 commit comments