Allow frontier simulation when Base Fee is present (#7965)

Signed-off-by: Gabriel-Trintinalia <gabriel.trintinalia@consensys.net>
This commit is contained in:
Gabriel-Trintinalia
2024-12-06 19:07:50 +11:00
committed by GitHub
parent 13fd24f064
commit a3592a71b1
4 changed files with 90 additions and 14 deletions

View File

@@ -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

View File

@@ -137,6 +137,7 @@ public class EthEstimateGasIntegrationTest {
.withChainId(BLOCKCHAIN.getChainId().add(BigInteger.ONE))
.withFrom(Address.fromHexString("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"))
.withTo(Address.fromHexString("0x8888f1f195afa192cfee860698584c030f4c9db1"))
.withMaxFeePerGas(Wei.ONE)
.withValue(Wei.ONE)
.build();

View File

@@ -296,9 +296,6 @@ public class TransactionSimulator {
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();
@@ -322,8 +319,6 @@ public class TransactionSimulator {
senderAddress,
nonce,
simulationGasCap,
value,
payload,
blobGasPrice);
if (maybeTransaction.isEmpty()) {
return Optional.empty();
@@ -404,9 +399,11 @@ public class TransactionSimulator {
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)
@@ -437,18 +434,21 @@ public class TransactionSimulator {
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();
}
if (shouldSetBlobGasPrice(callParams)) {
transactionBuilder.maxFeePerBlobGas(maxFeePerBlobGas);
}
transactionBuilder.guessType();
if (transactionBuilder.getTransactionType().supportsBlob()) {
transactionBuilder.maxFeePerBlobGas(maxFeePerBlobGas);
}
if (transactionBuilder.getTransactionType().requiresChainId()) {
callParams
.getChainId()
@@ -489,4 +489,39 @@ public class TransactionSimulator {
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();
}
}

View File

@@ -912,4 +912,43 @@ public class TransactionSimulatorTest {
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();
}
}