Skip to content

Commit

Permalink
Support rpc pending block tag when estimating gas (#7951)
Browse files Browse the repository at this point in the history
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
  • Loading branch information
fab-10 authored Dec 6, 2024
1 parent a3592a7 commit f8e93bf
Show file tree
Hide file tree
Showing 30 changed files with 611 additions and 351 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- Fast Sync

### Additions and Improvements
- Proper support for `pending` block tag when calling `eth_estimateGas` and `eth_createAccessList` [#7951](https://github.com/hyperledger/besu/pull/7951)

### Bug fixes
- Correct default parameters for frontier transactions in `eth_call` and `eth_estimateGas` [#7965](https://github.com/hyperledger/besu/pull/7965)
Expand Down Expand Up @@ -68,7 +69,6 @@
- Add histogram to Prometheus metrics system [#7944](https://github.com/hyperledger/besu/pull/7944)
- Improve newPayload and FCU logs [#7961](https://github.com/hyperledger/besu/pull/7961)


### Bug fixes
- Fix registering new metric categories from plugins [#7825](https://github.com/hyperledger/besu/pull/7825)
- Fix CVE-2024-47535 [7878](https://github.com/hyperledger/besu/pull/7878)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,9 +396,14 @@ TransactionSimulator provideTransactionSimulator(
final Blockchain blockchain,
final WorldStateArchive worldStateArchive,
final ProtocolSchedule protocolSchedule,
final MiningConfiguration miningConfiguration,
final ApiConfiguration apiConfiguration) {
return new TransactionSimulator(
blockchain, worldStateArchive, protocolSchedule, apiConfiguration.getGasCap());
blockchain,
worldStateArchive,
protocolSchedule,
miningConfiguration,
apiConfiguration.getGasCap());
}

@Provides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,11 @@ public BesuController build() {

transactionSimulator =
new TransactionSimulator(
blockchain, worldStateArchive, protocolSchedule, apiConfiguration.getGasCap());
blockchain,
worldStateArchive,
protocolSchedule,
miningConfiguration,
apiConfiguration.getGasCap());

final var consensusContext =
createConsensusContext(blockchain, worldStateArchive, protocolSchedule);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Transaction;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.mainnet.ImmutableTransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
Expand All @@ -35,11 +34,6 @@
/** TransactionSimulationServiceImpl */
@Unstable
public class TransactionSimulationServiceImpl implements TransactionSimulationService {
private static final TransactionValidationParams SIMULATOR_ALLOWING_EXCEEDING_BALANCE =
ImmutableTransactionValidationParams.builder()
.from(TransactionValidationParams.transactionSimulator())
.isAllowExceedingBalance(true)
.build();
private Blockchain blockchain;
private TransactionSimulator transactionSimulator;

Expand All @@ -57,46 +51,50 @@ public void init(final Blockchain blockchain, final TransactionSimulator transac
this.transactionSimulator = transactionSimulator;
}

@Override
public Optional<TransactionSimulationResult> simulate(
final Transaction transaction,
final Hash blockHash,
final OperationTracer operationTracer,
final boolean isAllowExceedingBalance) {
return simulate(
transaction, Optional.empty(), blockHash, operationTracer, isAllowExceedingBalance);
}

@Override
public Optional<TransactionSimulationResult> simulate(
final Transaction transaction,
final Optional<AccountOverrideMap> maybeAccountOverrides,
final Hash blockHash,
final Optional<Hash> maybeBlockHash,
final OperationTracer operationTracer,
final boolean isAllowExceedingBalance) {

final CallParameter callParameter = CallParameter.fromTransaction(transaction);

final var maybeBlockHeader =
blockchain.getBlockHeader(blockHash).or(() -> blockchain.getBlockHeaderSafe(blockHash));
if (maybeBlockHash.isPresent()) {
final Hash blockHash = maybeBlockHash.get();

final var maybeBlockHeader =
blockchain.getBlockHeader(blockHash).or(() -> blockchain.getBlockHeaderSafe(blockHash));

if (maybeBlockHeader.isEmpty()) {
return Optional.of(
new TransactionSimulationResult(
transaction,
TransactionProcessingResult.invalid(
ValidationResult.invalid(TransactionInvalidReason.BLOCK_NOT_FOUND))));
}

if (maybeBlockHeader.isEmpty()) {
return Optional.of(
new TransactionSimulationResult(
transaction,
TransactionProcessingResult.invalid(
ValidationResult.invalid(TransactionInvalidReason.BLOCK_NOT_FOUND))));
return transactionSimulator
.process(
callParameter,
isAllowExceedingBalance
? TransactionValidationParams.transactionSimulatorAllowExceedingBalance()
: TransactionValidationParams.transactionSimulator(),
operationTracer,
maybeBlockHeader.get())
.map(res -> new TransactionSimulationResult(transaction, res.result()));
}

return transactionSimulator
.process(
.processOnPending(
callParameter,
maybeAccountOverrides,
isAllowExceedingBalance
? SIMULATOR_ALLOWING_EXCEEDING_BALANCE
? TransactionValidationParams.transactionSimulatorAllowExceedingBalance()
: TransactionValidationParams.transactionSimulator(),
operationTracer,
maybeBlockHeader.get())
transactionSimulator.simulatePendingBlockHeader())
.map(res -> new TransactionSimulationResult(transaction, res.result()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public void extraDataCreatedOnEpochBlocksContainsValidators() {
}

@Test
public void extraDataForNonEpochBlocksDoesNotContainValidaors() {
public void extraDataForNonEpochBlocksDoesNotContainValidators() {
final Bytes vanityData = generateRandomVanityData();

final MiningConfiguration miningConfiguration = createMiningConfiguration(vanityData);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ private static ControllerAndState createControllerAndFinalState(
final boolean useFixedBaseFee,
final List<QbftFork> qbftForks) {

final MiningConfiguration miningParams =
final MiningConfiguration miningConfiguration =
ImmutableMiningConfiguration.builder()
.mutableInitValues(
MutableInitValues.builder()
Expand Down Expand Up @@ -445,7 +445,8 @@ private static ControllerAndState createControllerAndFinalState(

final BftValidatorOverrides validatorOverrides = convertBftForks(qbftForks);
final TransactionSimulator transactionSimulator =
new TransactionSimulator(blockChain, worldStateArchive, protocolSchedule, 0L);
new TransactionSimulator(
blockChain, worldStateArchive, protocolSchedule, miningConfiguration, 0L);

final BlockValidatorProvider blockValidatorProvider =
BlockValidatorProvider.forkingValidatorProvider(
Expand Down Expand Up @@ -496,7 +497,7 @@ private static ControllerAndState createControllerAndFinalState(
protocolContext,
protocolSchedule,
forksSchedule,
miningParams,
miningConfiguration,
localAddress,
BFT_EXTRA_DATA_ENCODER,
ethScheduler);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package org.hyperledger.besu.consensus.qbft.validator;

import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.mainnet.ImmutableTransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.transaction.CallParameter;
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
Expand Down Expand Up @@ -94,10 +93,7 @@ private Optional<TransactionSimulatorResult> callFunction(
final CallParameter callParams =
new CallParameter(null, contractAddress, -1, null, null, payload);
final TransactionValidationParams transactionValidationParams =
ImmutableTransactionValidationParams.builder()
.from(TransactionValidationParams.transactionSimulator())
.isAllowExceedingBalance(true)
.build();
TransactionValidationParams.transactionSimulatorAllowExceedingBalance();
return transactionSimulator.process(
callParams, transactionValidationParams, OperationTracer.NO_TRACING, blockNumber);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,13 @@ public JsonRpcTestMethodsFactory(final BlockchainImporter importer) {
final BlockImporter blockImporter = protocolSpec.getBlockImporter();
blockImporter.importBlock(context, block, HeaderValidationMode.FULL);
}
final var miningConfiguration = MiningConfiguration.newDefault();
this.blockchainQueries =
new BlockchainQueries(
protocolSchedule, blockchain, stateArchive, MiningConfiguration.newDefault());
new BlockchainQueries(protocolSchedule, blockchain, stateArchive, miningConfiguration);

this.transactionSimulator =
new TransactionSimulator(blockchain, stateArchive, protocolSchedule, 0L);
new TransactionSimulator(
blockchain, stateArchive, protocolSchedule, miningConfiguration, 0L);
}

public JsonRpcTestMethodsFactory(
Expand All @@ -115,15 +116,14 @@ public JsonRpcTestMethodsFactory(
this.stateArchive = stateArchive;
this.context = context;
this.protocolSchedule = importer.getProtocolSchedule();
final var miningConfiguration = MiningConfiguration.newDefault();
this.blockchainQueries =
new BlockchainQueries(
importer.getProtocolSchedule(),
blockchain,
stateArchive,
MiningConfiguration.newDefault());
importer.getProtocolSchedule(), blockchain, stateArchive, miningConfiguration);
this.synchronizer = mock(Synchronizer.class);
this.transactionSimulator =
new TransactionSimulator(blockchain, stateArchive, protocolSchedule, 0L);
new TransactionSimulator(
blockchain, stateArchive, protocolSchedule, miningConfiguration, 0L);
}

public JsonRpcTestMethodsFactory(
Expand All @@ -138,14 +138,13 @@ public JsonRpcTestMethodsFactory(
this.context = context;
this.synchronizer = synchronizer;
this.protocolSchedule = importer.getProtocolSchedule();
final var miningConfiguration = MiningConfiguration.newDefault();
this.blockchainQueries =
new BlockchainQueries(
importer.getProtocolSchedule(),
blockchain,
stateArchive,
MiningConfiguration.newDefault());
importer.getProtocolSchedule(), blockchain, stateArchive, miningConfiguration);
this.transactionSimulator =
new TransactionSimulator(blockchain, stateArchive, protocolSchedule, 0L);
new TransactionSimulator(
blockchain, stateArchive, protocolSchedule, miningConfiguration, 0L);
}

public BlockchainQueries getBlockchainQueries() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.LogWithMetadata;
import org.hyperledger.besu.ethereum.mainnet.ImmutableTransactionValidationParams;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
Expand Down Expand Up @@ -359,14 +358,9 @@ private Optional<CallResult> executeCall(final DataFetchingEnvironment environme
data,
Optional.empty());

ImmutableTransactionValidationParams.Builder transactionValidationParams =
ImmutableTransactionValidationParams.builder()
.from(TransactionValidationParams.transactionSimulator());
transactionValidationParams.isAllowExceedingBalance(true);

return transactionSimulator.process(
param,
transactionValidationParams.build(),
TransactionValidationParams.transactionSimulatorAllowExceedingBalance(),
OperationTracer.NO_TRACING,
(mutableWorldState, transactionSimulatorResult) ->
transactionSimulatorResult.map(
Expand Down
Loading

0 comments on commit f8e93bf

Please sign in to comment.