mirror of
https://github.com/vacp2p/linea-besu.git
synced 2026-01-08 15:13:58 -05:00
Simulation - Expose BlockHashLookup to BlockSimulatorService (#8267)
Signed-off-by: Gabriel-Trintinalia <gabriel.trintinalia@consensys.net>
This commit is contained in:
committed by
GitHub
parent
cbabf87766
commit
72a4e4a0a3
@@ -60,7 +60,11 @@ public class BlockSimulatorServiceImpl implements BlockSimulationService {
|
||||
this.blockchain = blockchain;
|
||||
blockSimulator =
|
||||
new BlockSimulator(
|
||||
worldStateArchive, protocolSchedule, transactionSimulator, miningConfiguration);
|
||||
worldStateArchive,
|
||||
protocolSchedule,
|
||||
transactionSimulator,
|
||||
miningConfiguration,
|
||||
blockchain);
|
||||
this.worldStateArchive = worldStateArchive;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.hyperledger.besu.datatypes.Hash;
|
||||
import org.hyperledger.besu.datatypes.StateOverride;
|
||||
import org.hyperledger.besu.datatypes.StateOverrideMap;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
||||
import org.hyperledger.besu.ethereum.core.Block;
|
||||
import org.hyperledger.besu.ethereum.core.BlockBody;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
@@ -44,6 +45,7 @@ import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
|
||||
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
import org.hyperledger.besu.evm.account.MutableAccount;
|
||||
import org.hyperledger.besu.evm.blockhash.BlockHashLookup;
|
||||
import org.hyperledger.besu.evm.tracing.OperationTracer;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
|
||||
import org.hyperledger.besu.plugin.data.BlockOverrides;
|
||||
@@ -69,16 +71,19 @@ public class BlockSimulator {
|
||||
private final WorldStateArchive worldStateArchive;
|
||||
private final ProtocolSchedule protocolSchedule;
|
||||
private final MiningConfiguration miningConfiguration;
|
||||
private final Blockchain blockchain;
|
||||
|
||||
public BlockSimulator(
|
||||
final WorldStateArchive worldStateArchive,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final TransactionSimulator transactionSimulator,
|
||||
final MiningConfiguration miningConfiguration) {
|
||||
final MiningConfiguration miningConfiguration,
|
||||
final Blockchain blockchain) {
|
||||
this.worldStateArchive = worldStateArchive;
|
||||
this.protocolSchedule = protocolSchedule;
|
||||
this.miningConfiguration = miningConfiguration;
|
||||
this.transactionSimulator = transactionSimulator;
|
||||
this.blockchain = blockchain;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,8 +154,12 @@ public class BlockSimulator {
|
||||
MiningBeneficiaryCalculator miningBeneficiaryCalculator =
|
||||
getMiningBeneficiaryCalculator(blockOverrides, newProtocolSpec);
|
||||
|
||||
BlockHashLookup blockHashLookup =
|
||||
createBlockHashLookup(blockOverrides, newProtocolSpec, blockHeader);
|
||||
|
||||
List<TransactionSimulatorResult> transactionSimulatorResults =
|
||||
processTransactions(blockHeader, blockStateCall, ws, miningBeneficiaryCalculator);
|
||||
processTransactions(
|
||||
blockHeader, blockStateCall, ws, miningBeneficiaryCalculator, blockHashLookup);
|
||||
|
||||
return finalizeBlock(
|
||||
blockHeader, blockStateCall, ws, newProtocolSpec, transactionSimulatorResults);
|
||||
@@ -161,7 +170,8 @@ public class BlockSimulator {
|
||||
final BlockHeader blockHeader,
|
||||
final BlockStateCall blockStateCall,
|
||||
final MutableWorldState ws,
|
||||
final MiningBeneficiaryCalculator miningBeneficiaryCalculator) {
|
||||
final MiningBeneficiaryCalculator miningBeneficiaryCalculator,
|
||||
final BlockHashLookup blockHashLookup) {
|
||||
|
||||
List<TransactionSimulatorResult> transactionSimulations = new ArrayList<>();
|
||||
|
||||
@@ -176,7 +186,8 @@ public class BlockSimulator {
|
||||
OperationTracer.NO_TRACING,
|
||||
blockHeader,
|
||||
transactionUpdater,
|
||||
miningBeneficiaryCalculator);
|
||||
miningBeneficiaryCalculator,
|
||||
blockHashLookup);
|
||||
|
||||
if (transactionSimulatorResult.isEmpty()) {
|
||||
throw new BlockSimulationException("Transaction simulator result is empty");
|
||||
@@ -409,4 +420,28 @@ public class BlockSimulator {
|
||||
return blockHeaderFunctions.parseExtraData(header);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BlockHashLookup for the block simulation. If a BlockHashLookup is provided in the
|
||||
* BlockOverrides, it is used. Otherwise, the default BlockHashLookup is created.
|
||||
*
|
||||
* @param blockOverrides The BlockOverrides to use.
|
||||
* @param newProtocolSpec The ProtocolSpec for the block.
|
||||
* @param blockHeader The block header for the simulation.
|
||||
* @return The BlockHashLookup for the block simulation.
|
||||
*/
|
||||
private BlockHashLookup createBlockHashLookup(
|
||||
final BlockOverrides blockOverrides,
|
||||
final ProtocolSpec newProtocolSpec,
|
||||
final BlockHeader blockHeader) {
|
||||
return blockOverrides
|
||||
.getBlockHashLookup()
|
||||
.<BlockHashLookup>map(
|
||||
blockHashLookup -> (frame, blockNumber) -> blockHashLookup.apply(blockNumber))
|
||||
.orElseGet(
|
||||
() ->
|
||||
newProtocolSpec
|
||||
.getBlockHashProcessor()
|
||||
.createBlockHashLookup(blockchain, blockHeader));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ import org.hyperledger.besu.ethereum.vm.DebugOperationTracer;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
import org.hyperledger.besu.evm.account.Account;
|
||||
import org.hyperledger.besu.evm.account.MutableAccount;
|
||||
import org.hyperledger.besu.evm.blockhash.BlockHashLookup;
|
||||
import org.hyperledger.besu.evm.tracing.OperationTracer;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
|
||||
|
||||
@@ -353,7 +354,8 @@ public class TransactionSimulator {
|
||||
final OperationTracer operationTracer,
|
||||
final BlockHeader header,
|
||||
final WorldUpdater updater,
|
||||
final MiningBeneficiaryCalculator miningBeneficiaryCalculator) {
|
||||
final MiningBeneficiaryCalculator miningBeneficiaryCalculator,
|
||||
final BlockHashLookup blockHashLookup) {
|
||||
|
||||
final Address miningBeneficiary = miningBeneficiaryCalculator.calculateBeneficiary(header);
|
||||
|
||||
@@ -364,7 +366,8 @@ public class TransactionSimulator {
|
||||
operationTracer,
|
||||
header,
|
||||
updater,
|
||||
miningBeneficiary);
|
||||
miningBeneficiary,
|
||||
blockHashLookup);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@@ -377,7 +380,31 @@ public class TransactionSimulator {
|
||||
final WorldUpdater updater,
|
||||
final Address miningBeneficiary) {
|
||||
final ProtocolSpec protocolSpec = protocolSchedule.getByBlockHeader(processableHeader);
|
||||
final BlockHashLookup blockHashLookup =
|
||||
protocolSpec.getBlockHashProcessor().createBlockHashLookup(blockchain, processableHeader);
|
||||
return processWithWorldUpdater(
|
||||
callParams,
|
||||
maybeStateOverrides,
|
||||
transactionValidationParams,
|
||||
operationTracer,
|
||||
processableHeader,
|
||||
updater,
|
||||
miningBeneficiary,
|
||||
blockHashLookup);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Optional<TransactionSimulatorResult> processWithWorldUpdater(
|
||||
final CallParameter callParams,
|
||||
final Optional<StateOverrideMap> maybeStateOverrides,
|
||||
final TransactionValidationParams transactionValidationParams,
|
||||
final OperationTracer operationTracer,
|
||||
final ProcessableBlockHeader processableHeader,
|
||||
final WorldUpdater updater,
|
||||
final Address miningBeneficiary,
|
||||
final BlockHashLookup blockHashLookup) {
|
||||
|
||||
final ProtocolSpec protocolSpec = protocolSchedule.getByBlockHeader(processableHeader);
|
||||
final Address senderAddress =
|
||||
callParams.getFrom() != null ? callParams.getFrom() : DEFAULT_FROM;
|
||||
|
||||
@@ -448,9 +475,7 @@ public class TransactionSimulator {
|
||||
blockHeaderToProcess,
|
||||
transaction,
|
||||
miningBeneficiary,
|
||||
protocolSpec
|
||||
.getBlockHashProcessor()
|
||||
.createBlockHashLookup(blockchain, blockHeaderToProcess),
|
||||
blockHashLookup,
|
||||
false,
|
||||
transactionValidationParams,
|
||||
operationTracer,
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.hyperledger.besu.datatypes.StateOverrideMap;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.datatypes.parameters.UnsignedLongParameter;
|
||||
import org.hyperledger.besu.ethereum.GasLimitCalculator;
|
||||
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
|
||||
import org.hyperledger.besu.ethereum.core.Difficulty;
|
||||
@@ -42,6 +43,7 @@ import org.hyperledger.besu.ethereum.mainnet.MiningBeneficiaryCalculator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
|
||||
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
|
||||
import org.hyperledger.besu.ethereum.mainnet.blockhash.BlockHashProcessor;
|
||||
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
|
||||
import org.hyperledger.besu.ethereum.trie.diffbased.common.provider.WorldStateQueryParams;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
@@ -74,6 +76,8 @@ public class BlockSimulatorTest {
|
||||
@Mock private TransactionSimulator transactionSimulator;
|
||||
@Mock private MiningConfiguration miningConfiguration;
|
||||
@Mock private MutableWorldState mutableWorldState;
|
||||
@Mock private Blockchain blockchain;
|
||||
|
||||
private BlockHeader blockHeader;
|
||||
|
||||
private BlockSimulator blockSimulator;
|
||||
@@ -82,7 +86,11 @@ public class BlockSimulatorTest {
|
||||
public void setUp() {
|
||||
blockSimulator =
|
||||
new BlockSimulator(
|
||||
worldStateArchive, protocolSchedule, transactionSimulator, miningConfiguration);
|
||||
worldStateArchive,
|
||||
protocolSchedule,
|
||||
transactionSimulator,
|
||||
miningConfiguration,
|
||||
blockchain);
|
||||
blockHeader = BlockHeaderBuilder.createDefault().buildBlockHeader();
|
||||
ProtocolSpec protocolSpec = mock(ProtocolSpec.class);
|
||||
when(miningConfiguration.getCoinbase())
|
||||
@@ -94,6 +102,7 @@ public class BlockSimulatorTest {
|
||||
when(protocolSpec.getGasLimitCalculator()).thenReturn(gasLimitCalculator);
|
||||
when(gasLimitCalculator.nextGasLimit(anyLong(), anyLong(), anyLong())).thenReturn(1L);
|
||||
when(protocolSpec.getFeeMarket()).thenReturn(mock(FeeMarket.class));
|
||||
when(protocolSpec.getBlockHashProcessor()).thenReturn(mock(BlockHashProcessor.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -135,7 +144,14 @@ public class BlockSimulatorTest {
|
||||
.thenReturn(Optional.of("Invalid Transaction"));
|
||||
|
||||
when(transactionSimulator.processWithWorldUpdater(
|
||||
any(), any(), any(), any(), any(), any(), any(MiningBeneficiaryCalculator.class)))
|
||||
any(),
|
||||
any(),
|
||||
any(),
|
||||
any(),
|
||||
any(),
|
||||
any(),
|
||||
any(MiningBeneficiaryCalculator.class),
|
||||
any()))
|
||||
.thenReturn(Optional.of(transactionSimulatorResult));
|
||||
|
||||
BlockSimulationException exception =
|
||||
@@ -154,7 +170,14 @@ public class BlockSimulatorTest {
|
||||
BlockStateCall blockStateCall = new BlockStateCall(List.of(callParameter), null, null, true);
|
||||
|
||||
when(transactionSimulator.processWithWorldUpdater(
|
||||
any(), any(), any(), any(), any(), any(), any(MiningBeneficiaryCalculator.class)))
|
||||
any(),
|
||||
any(),
|
||||
any(),
|
||||
any(),
|
||||
any(),
|
||||
any(),
|
||||
any(MiningBeneficiaryCalculator.class),
|
||||
any()))
|
||||
.thenReturn(Optional.empty());
|
||||
|
||||
BlockSimulationException exception =
|
||||
|
||||
@@ -71,7 +71,7 @@ Calculated : ${currentHash}
|
||||
tasks.register('checkAPIChanges', FileStateChecker) {
|
||||
description = "Checks that the API for the Plugin-API project does not change without deliberate thought"
|
||||
files = sourceSets.main.allJava.files
|
||||
knownHash = 'U/zVfjqq/stLY920xHh1N26KU+KoAdgEiV2nPWIFRIs='
|
||||
knownHash = 'I2IrN2aLU610031Vw8xNr3hcT8/wb25pDrclwZUggE4='
|
||||
}
|
||||
check.dependsOn('checkAPIChanges')
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.hyperledger.besu.datatypes.parameters.UnsignedLongParameter;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
@@ -39,6 +40,7 @@ public class BlockOverrides {
|
||||
private final Optional<BigInteger> difficulty;
|
||||
private final Optional<Bytes> extraData;
|
||||
private final Optional<Hash> mixHashOrPrevRandao;
|
||||
private final Optional<Function<Long, Hash>> blockHashLookup;
|
||||
|
||||
/**
|
||||
* Constructs a new BlockOverrides instance.
|
||||
@@ -81,6 +83,7 @@ public class BlockOverrides {
|
||||
this.difficulty = difficulty;
|
||||
this.extraData = extraData;
|
||||
this.mixHashOrPrevRandao = mixHashOrPrevRandao;
|
||||
this.blockHashLookup = Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,6 +104,7 @@ public class BlockOverrides {
|
||||
this.difficulty = Optional.ofNullable(builder.difficulty);
|
||||
this.extraData = Optional.ofNullable(builder.extraData);
|
||||
this.mixHashOrPrevRandao = Optional.ofNullable(builder.mixHashOrPrevRandao);
|
||||
this.blockHashLookup = Optional.ofNullable(builder.blockHashLookup);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -211,6 +215,15 @@ public class BlockOverrides {
|
||||
return mixHashOrPrevRandao;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the block hash lookup.
|
||||
*
|
||||
* @return the optional block hash lookup
|
||||
*/
|
||||
public Optional<Function<Long, Hash>> getBlockHashLookup() {
|
||||
return blockHashLookup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Builder instance.
|
||||
*
|
||||
@@ -234,6 +247,7 @@ public class BlockOverrides {
|
||||
private BigInteger difficulty;
|
||||
private Bytes extraData;
|
||||
private Hash mixHashOrPrevRandao;
|
||||
private Function<Long, Hash> blockHashLookup;
|
||||
|
||||
/** Constructs a new Builder instance. */
|
||||
public Builder() {}
|
||||
@@ -370,6 +384,17 @@ public class BlockOverrides {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the block hash lookup.
|
||||
*
|
||||
* @param blockHashLookup the block hash lookup to set
|
||||
* @return the builder instance
|
||||
*/
|
||||
public Builder blockHashLookup(final Function<Long, Hash> blockHashLookup) {
|
||||
this.blockHashLookup = blockHashLookup;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new BlockOverrides instance.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user