Skip to content

Commit

Permalink
Allow frontier simulation when Base Fee is present (#7965)
Browse files Browse the repository at this point in the history
Signed-off-by: Gabriel-Trintinalia <gabriel.trintinalia@consensys.net>
  • Loading branch information
Gabriel-Trintinalia authored Dec 6, 2024
1 parent 13fd24f commit a3592a7
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
### Additions and Improvements

### Bug fixes
- Correct default parameters for frontier transactions in `eth_call` and `eth_estimateGas` [#7965](https://github.com/hyperledger/besu/pull/7965)

## 24.12.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ public void shouldReturnErrorWithInvalidChainId() {
.withChainId(BLOCKCHAIN.getChainId().add(BigInteger.ONE))
.withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"))
.withTo(Address.fromHexString("0x8888f1f195afa192cfee860698584c030f4c9db1"))
.withMaxFeePerGas(Wei.ONE)
.withValue(Wei.ONE)
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,9 +296,6 @@ public Optional<TransactionSimulatorResult> processWithWorldUpdater(
final long simulationGasCap =
calculateSimulationGasCap(callParams.getGasLimit(), blockHeaderToProcess.getGasLimit());

final Wei value = callParams.getValue() != null ? callParams.getValue() : Wei.ZERO;
final Bytes payload = callParams.getPayload() != null ? callParams.getPayload() : Bytes.EMPTY;

final MainnetTransactionProcessor transactionProcessor =
protocolSchedule.getByBlockHeader(blockHeaderToProcess).getTransactionProcessor();

Expand All @@ -322,8 +319,6 @@ public Optional<TransactionSimulatorResult> processWithWorldUpdater(
senderAddress,
nonce,
simulationGasCap,
value,
payload,
blobGasPrice);
if (maybeTransaction.isEmpty()) {
return Optional.empty();
Expand Down Expand Up @@ -404,9 +399,11 @@ private Optional<Transaction> buildTransaction(
final Address senderAddress,
final long nonce,
final long gasLimit,
final Wei value,
final Bytes payload,
final Wei blobGasPrice) {

final Wei value = callParams.getValue() != null ? callParams.getValue() : Wei.ZERO;
final Bytes payload = callParams.getPayload() != null ? callParams.getPayload() : Bytes.EMPTY;

final Transaction.Builder transactionBuilder =
Transaction.builder()
.nonce(nonce)
Expand Down Expand Up @@ -437,18 +434,21 @@ private Optional<Transaction> buildTransaction(
maxPriorityFeePerGas = callParams.getMaxPriorityFeePerGas().orElse(gasPrice);
maxFeePerBlobGas = callParams.getMaxFeePerBlobGas().orElse(blobGasPrice);
}
if (header.getBaseFee().isEmpty()) {

if (shouldSetGasPrice(callParams, header)) {
transactionBuilder.gasPrice(gasPrice);
} else if (protocolSchedule.getChainId().isPresent()) {
}

if (shouldSetMaxFeePerGas(callParams, header)) {
transactionBuilder.maxFeePerGas(maxFeePerGas).maxPriorityFeePerGas(maxPriorityFeePerGas);
} else {
return Optional.empty();
}

transactionBuilder.guessType();
if (transactionBuilder.getTransactionType().supportsBlob()) {
if (shouldSetBlobGasPrice(callParams)) {
transactionBuilder.maxFeePerBlobGas(maxFeePerBlobGas);
}

transactionBuilder.guessType();

if (transactionBuilder.getTransactionType().requiresChainId()) {
callParams
.getChainId()
Expand Down Expand Up @@ -489,4 +489,39 @@ public Optional<Boolean> doesAddressExist(

return Optional.of(worldState.get(address) != null);
}

private boolean shouldSetGasPrice(final CallParameter callParams, final BlockHeader header) {
if (header.getBaseFee().isEmpty()) {
return true;
}

// if maxPriorityFeePerGas and maxFeePerGas are not set, use gasPrice
return callParams.getMaxPriorityFeePerGas().isEmpty() && callParams.getMaxFeePerGas().isEmpty();
}

private boolean shouldSetMaxFeePerGas(final CallParameter callParams, final BlockHeader header) {
if (protocolSchedule.getChainId().isEmpty()) {
return false;
}

if (header.getBaseFee().isEmpty()) {
return false;
}

if (shouldSetBlobGasPrice(callParams)) {
return true;
}

// only set maxFeePerGas and maxPriorityFeePerGas if they are present, otherwise transaction
// will be considered EIP-1559 transaction even if the simulation is for a legacy transaction
return callParams.getMaxPriorityFeePerGas().isPresent()
|| callParams.getMaxFeePerGas().isPresent();
}

private boolean shouldSetBlobGasPrice(final CallParameter callParams) {
if (protocolSchedule.getChainId().isEmpty()) {
return false;
}
return callParams.getBlobVersionedHashes().isPresent();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -912,4 +912,43 @@ private CallParameter blobTransactionCallParameter(
Optional.of(maxFeePerBlobGas),
Optional.of(bwc.getVersionedHashes()));
}

@Test
public void shouldSimulateLegacyTransactionWhenBaseFeeNotZero() {
// tests that the transaction simulator will simulate a legacy transaction when the base fee is
// not zero
// and the transaction is a legacy transaction

final CallParameter callParameter = legacyTransactionCallParameter();

final BlockHeader blockHeader =
blockHeaderTestFixture
.number(1L)
.stateRoot(Hash.ZERO)
.baseFeePerGas(Wei.of(7))
.buildHeader();

mockBlockchainForBlockHeader(blockHeader);
mockWorldStateForAccount(blockHeader, callParameter.getFrom(), 1L);

final Transaction expectedTransaction =
Transaction.builder()
.type(TransactionType.FRONTIER)
.nonce(1L)
.gasPrice(callParameter.getGasPrice())
.gasLimit(blockHeader.getGasLimit())
.to(callParameter.getTo())
.sender(callParameter.getFrom())
.value(callParameter.getValue())
.payload(callParameter.getPayload())
.signature(FAKE_SIGNATURE)
.build();
mockProcessorStatusForTransaction(expectedTransaction, Status.SUCCESSFUL);

final Optional<TransactionSimulatorResult> result =
transactionSimulator.process(callParameter, 1L);

verifyTransactionWasProcessed(expectedTransaction);
assertThat(result.get().isSuccessful()).isTrue();
}
}

0 comments on commit a3592a7

Please sign in to comment.