Skip to content

Commit 88a871c

Browse files
fab-10Bhanu Pulluri
authored and
Bhanu Pulluri
committed
Fix the simulation of txs with future nonce (hyperledger#8215)
Signed-off-by: Fabio Di Fabio <[email protected]> Signed-off-by: Bhanu Pulluri <[email protected]>
1 parent f988b9e commit 88a871c

File tree

13 files changed

+357
-36
lines changed

13 files changed

+357
-36
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
- Extend simulate transaction on pending block plugin API [#8174](https://github.com/hyperledger/besu/pull/8174)
1515

1616
### Bug fixes
17-
17+
- Fix the simulation of txs with a future nonce [#8215](https://github.com/hyperledger/besu/pull/8215)
1818

1919
## 25.1.0
2020

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/graphql/internal/pojoadapter/PendingStateAdapter.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata;
2222
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction;
2323
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool;
24-
import org.hyperledger.besu.ethereum.mainnet.ImmutableTransactionValidationParams;
2524
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
2625
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
2726
import org.hyperledger.besu.ethereum.transaction.CallParameter;
@@ -163,14 +162,9 @@ public Optional<CallResult> getCall(final DataFetchingEnvironment environment) {
163162
final CallParameter param =
164163
new CallParameter(from, to, gasParam, gasPriceParam, valueParam, data);
165164

166-
ImmutableTransactionValidationParams.Builder transactionValidationParams =
167-
ImmutableTransactionValidationParams.builder()
168-
.from(TransactionValidationParams.transactionSimulator());
169-
transactionValidationParams.isAllowExceedingBalance(true);
170-
171165
return transactionSimulator.process(
172166
param,
173-
transactionValidationParams.build(),
167+
TransactionValidationParams.transactionSimulatorAllowExceedingBalanceAndFutureNonce(),
174168
OperationTracer.NO_TRACING,
175169
(mutableWorldState, transactionSimulatorResult) ->
176170
transactionSimulatorResult.map(

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractEstimateGas.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,8 @@ protected static TransactionValidationParams getTransactionValidationParams(
210210
final boolean isAllowExceedingBalance = !callParams.isMaybeStrict().orElse(Boolean.FALSE);
211211

212212
return isAllowExceedingBalance
213-
? TransactionValidationParams.transactionSimulatorAllowExceedingBalance()
214-
: TransactionValidationParams.transactionSimulator();
213+
? TransactionValidationParams.transactionSimulatorAllowExceedingBalanceAndFutureNonce()
214+
: TransactionValidationParams.transactionSimulatorAllowFutureNonce();
215215
}
216216

217217
@VisibleForTesting

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@
3939
import java.util.Optional;
4040

4141
public class DebugTraceCall extends AbstractTraceCall {
42+
private static final TransactionValidationParams TRANSACTION_VALIDATION_PARAMS =
43+
ImmutableTransactionValidationParams.builder()
44+
.from(TransactionValidationParams.transactionSimulator())
45+
.isAllowFutureNonce(true)
46+
.isAllowExceedingBalance(true)
47+
.allowUnderpriced(true)
48+
.build();
4249

4350
public DebugTraceCall(
4451
final BlockchainQueries blockchainQueries,
@@ -103,10 +110,6 @@ protected PreCloseStateHandler<Object> getSimulatorResultHandler(
103110

104111
@Override
105112
protected TransactionValidationParams buildTransactionValidationParams() {
106-
return ImmutableTransactionValidationParams.builder()
107-
.from(TransactionValidationParams.transactionSimulator())
108-
.isAllowExceedingBalance(true)
109-
.allowUnderpriced(true)
110-
.build();
113+
return TRANSACTION_VALIDATION_PARAMS;
111114
}
112115
}

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCall.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,8 @@ private TransactionValidationParams buildTransactionValidationParams(
169169
isAllowExceedingBalance = !callParams.isMaybeStrict().orElse(Boolean.FALSE);
170170
}
171171
return isAllowExceedingBalance
172-
? TransactionValidationParams.transactionSimulatorAllowExceedingBalance()
173-
: TransactionValidationParams.transactionSimulator();
172+
? TransactionValidationParams.transactionSimulatorAllowExceedingBalanceAndFutureNonce()
173+
: TransactionValidationParams.transactionSimulatorAllowFutureNonce();
174174
}
175175

176176
private boolean isAllowExceedingBalanceAutoSelection(

ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthCallTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,7 @@ private void internalAutoSelectIsAllowedExceedingBalance(
514514
ImmutableTransactionValidationParams.builder()
515515
.from(TransactionValidationParams.transactionSimulator())
516516
.isAllowExceedingBalance(isAllowedExceedingBalance)
517+
.isAllowFutureNonce(true)
517518
.build();
518519

519520
verify(transactionSimulator)

ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/EthEstimateGasTest.java

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public void shouldReturnErrorWhenTransientLegacyTransactionProcessorReturnsEmpty
140140
final JsonRpcRequestContext request =
141141
ethEstimateGasRequest(defaultLegacyTransactionCallParameter(Wei.ZERO));
142142
when(transactionSimulator.process(
143-
eq(modifiedLegacyTransactionCallParameter(Wei.ZERO)),
143+
eq(modifiedLegacyTransactionCallParameter(Wei.ZERO, Optional.empty())),
144144
eq(Optional.empty()), // no account overrides
145145
any(TransactionValidationParams.class),
146146
any(OperationTracer.class),
@@ -193,11 +193,26 @@ public void shouldUseGasPriceParameterWhenIsPresent() {
193193
assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse);
194194
}
195195

196+
@Test
197+
public void shouldUseNonceParameterWhenIsPresent() {
198+
final Wei gasPrice = Wei.of(1000);
199+
final long nonce = 0L;
200+
final JsonRpcRequestContext request =
201+
ethEstimateGasRequest(
202+
eip1559TransactionCallParameter(Optional.of(gasPrice), Optional.of(nonce)));
203+
getMockTransactionSimulatorResult(
204+
true, 1L, gasPrice, Optional.empty(), latestBlockHeader, Optional.of(nonce));
205+
206+
final JsonRpcResponse expectedResponse = new JsonRpcSuccessResponse(null, Quantity.create(1L));
207+
assertThat(method.response(request)).usingRecursiveComparison().isEqualTo(expectedResponse);
208+
}
209+
196210
@Test
197211
public void shouldNotErrorWhenGasPricePresentForEip1559Transaction() {
198212
final Wei gasPrice = Wei.of(1000);
199213
final JsonRpcRequestContext request =
200-
ethEstimateGasRequest(eip1559TransactionCallParameter(Optional.of(gasPrice)));
214+
ethEstimateGasRequest(
215+
eip1559TransactionCallParameter(Optional.of(gasPrice), Optional.empty()));
201216
mockTransientProcessorResultGasEstimate(
202217
1L, true, gasPrice, Optional.empty(), latestBlockHeader);
203218

@@ -379,9 +394,11 @@ public void shouldIgnoreSenderBalanceAccountWhenStrictModeDisabled() {
379394

380395
verify(transactionSimulator)
381396
.process(
382-
eq(modifiedLegacyTransactionCallParameter(Wei.ZERO)),
397+
eq(modifiedLegacyTransactionCallParameter(Wei.ZERO, Optional.empty())),
383398
eq(Optional.empty()), // no account overrides
384-
eq(TransactionValidationParams.transactionSimulatorAllowExceedingBalance()),
399+
eq(
400+
TransactionValidationParams
401+
.transactionSimulatorAllowExceedingBalanceAndFutureNonceParams),
385402
any(OperationTracer.class),
386403
eq(latestBlockHeader));
387404
}
@@ -396,9 +413,9 @@ public void shouldNotIgnoreSenderBalanceAccountWhenStrictModeEnabled() {
396413

397414
verify(transactionSimulator)
398415
.process(
399-
eq(modifiedLegacyTransactionCallParameter(Wei.ZERO)),
416+
eq(modifiedLegacyTransactionCallParameter(Wei.ZERO, Optional.empty())),
400417
eq(Optional.empty()), // no account overrides
401-
eq(TransactionValidationParams.transactionSimulator()),
418+
eq(TransactionValidationParams.transactionSimulatorAllowFutureNonce()),
402419
any(OperationTracer.class),
403420
eq(latestBlockHeader));
404421
}
@@ -456,7 +473,8 @@ private void mockTransientProcessorResultTxInvalidReason(
456473
final String validationFailedErrorMessage,
457474
final BlockHeader blockHeader) {
458475
final TransactionSimulatorResult mockTxSimResult =
459-
getMockTransactionSimulatorResult(false, 0, Wei.ZERO, Optional.empty(), blockHeader);
476+
getMockTransactionSimulatorResult(
477+
false, 0, Wei.ZERO, Optional.empty(), blockHeader, Optional.empty());
460478
when(mockTxSimResult.getValidationResult())
461479
.thenReturn(
462480
validationFailedErrorMessage == null
@@ -493,7 +511,7 @@ private void mockTransientProcessorResultGasEstimate(
493511
final Optional<Bytes> revertReason,
494512
final BlockHeader blockHeader) {
495513
getMockTransactionSimulatorResult(
496-
isSuccessful, estimateGas, gasPrice, revertReason, blockHeader);
514+
isSuccessful, estimateGas, gasPrice, revertReason, blockHeader, Optional.empty());
497515
}
498516

499517
@SuppressWarnings("ReferenceEquality")
@@ -502,11 +520,12 @@ private TransactionSimulatorResult getMockTransactionSimulatorResult(
502520
final long estimateGas,
503521
final Wei gasPrice,
504522
final Optional<Bytes> revertReason,
505-
final BlockHeader blockHeader) {
523+
final BlockHeader blockHeader,
524+
final Optional<Long> maybeNonce) {
506525
final TransactionSimulatorResult mockTxSimResult = mock(TransactionSimulatorResult.class);
507526
if (blockHeader == pendingBlockHeader) {
508527
when(transactionSimulator.processOnPending(
509-
eq(modifiedLegacyTransactionCallParameter(gasPrice)),
528+
eq(modifiedLegacyTransactionCallParameter(gasPrice, maybeNonce)),
510529
eq(Optional.empty()), // no account overrides
511530
any(TransactionValidationParams.class),
512531
any(OperationTracer.class),
@@ -521,7 +540,7 @@ private TransactionSimulatorResult getMockTransactionSimulatorResult(
521540
.thenReturn(Optional.of(mockTxSimResult));
522541
} else {
523542
when(transactionSimulator.process(
524-
eq(modifiedLegacyTransactionCallParameter(gasPrice)),
543+
eq(modifiedLegacyTransactionCallParameter(gasPrice, maybeNonce)),
525544
eq(Optional.empty()), // no account overrides
526545
any(TransactionValidationParams.class),
527546
any(OperationTracer.class),
@@ -536,7 +555,7 @@ private TransactionSimulatorResult getMockTransactionSimulatorResult(
536555
.thenReturn(Optional.of(mockTxSimResult));
537556
// for testing different combination of gasPrice params
538557
when(transactionSimulator.process(
539-
eq(modifiedEip1559TransactionCallParameter(Optional.of(gasPrice))),
558+
eq(modifiedEip1559TransactionCallParameter(Optional.of(gasPrice), maybeNonce)),
540559
eq(Optional.empty()), // no account overrides
541560
any(TransactionValidationParams.class),
542561
any(OperationTracer.class),
@@ -569,7 +588,8 @@ private JsonCallParameter legacyTransactionCallParameter(
569588
.build();
570589
}
571590

572-
private CallParameter modifiedLegacyTransactionCallParameter(final Wei gasPrice) {
591+
private CallParameter modifiedLegacyTransactionCallParameter(
592+
final Wei gasPrice, final Optional<Long> maybeNonce) {
573593
return new CallParameter(
574594
Address.fromHexString("0x0"),
575595
Address.fromHexString("0x0"),
@@ -580,14 +600,15 @@ private CallParameter modifiedLegacyTransactionCallParameter(final Wei gasPrice)
580600
Wei.ZERO,
581601
Bytes.EMPTY,
582602
Optional.empty(),
583-
Optional.empty());
603+
maybeNonce);
584604
}
585605

586606
private CallParameter eip1559TransactionCallParameter() {
587-
return eip1559TransactionCallParameter(Optional.empty());
607+
return eip1559TransactionCallParameter(Optional.empty(), Optional.empty());
588608
}
589609

590-
private JsonCallParameter eip1559TransactionCallParameter(final Optional<Wei> maybeGasPrice) {
610+
private JsonCallParameter eip1559TransactionCallParameter(
611+
final Optional<Wei> maybeGasPrice, final Optional<Long> maybeNonce) {
591612
return new JsonCallParameter.JsonCallParameterBuilder()
592613
.withFrom(Address.fromHexString("0x0"))
593614
.withTo(Address.fromHexString("0x0"))
@@ -597,14 +618,16 @@ private JsonCallParameter eip1559TransactionCallParameter(final Optional<Wei> ma
597618
.withValue(Wei.ZERO)
598619
.withInput(Bytes.EMPTY)
599620
.withStrict(false)
621+
.withNonce(maybeNonce.map(UnsignedLongParameter::new).orElse(null))
600622
.build();
601623
}
602624

603625
private CallParameter modifiedEip1559TransactionCallParameter() {
604-
return modifiedEip1559TransactionCallParameter(Optional.empty());
626+
return modifiedEip1559TransactionCallParameter(Optional.empty(), Optional.empty());
605627
}
606628

607-
private CallParameter modifiedEip1559TransactionCallParameter(final Optional<Wei> gasPrice) {
629+
private CallParameter modifiedEip1559TransactionCallParameter(
630+
final Optional<Wei> gasPrice, final Optional<Long> maybeNonce) {
608631
return new CallParameter(
609632
Address.fromHexString("0x0"),
610633
Address.fromHexString("0x0"),
@@ -615,7 +638,7 @@ private CallParameter modifiedEip1559TransactionCallParameter(final Optional<Wei
615638
Wei.ZERO,
616639
Bytes.EMPTY,
617640
Optional.empty(),
618-
Optional.empty());
641+
maybeNonce);
619642
}
620643

621644
private JsonRpcRequestContext ethEstimateGasRequest(final CallParameter callParameter) {

0 commit comments

Comments
 (0)