use of org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor in project besu by hyperledger.
the class BlockReplay method performActionWithBlock.
private <T> Optional<T> performActionWithBlock(final BlockHeader header, final BlockBody body, final BlockAction<T> action) {
if (header == null) {
return Optional.empty();
}
if (body == null) {
return Optional.empty();
}
final ProtocolSpec protocolSpec = protocolSchedule.getByBlockNumber(header.getNumber());
final MainnetTransactionProcessor transactionProcessor = protocolSpec.getTransactionProcessor();
final BlockHeader previous = blockchain.getBlockHeader(header.getParentHash()).orElse(null);
if (previous == null) {
return Optional.empty();
}
final MutableWorldState mutableWorldState = worldStateArchive.getMutable(previous.getStateRoot(), previous.getHash(), false).orElse(null);
if (mutableWorldState == null) {
return Optional.empty();
}
return action.perform(body, header, blockchain, mutableWorldState, transactionProcessor);
}
use of org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor in project besu by hyperledger.
the class AbstractBlockCreator method selectTransactions.
private BlockTransactionSelector.TransactionSelectionResults selectTransactions(final ProcessableBlockHeader processableBlockHeader, final MutableWorldState disposableWorldState, final Optional<List<Transaction>> transactions, final Address miningBeneficiary) throws RuntimeException {
final MainnetTransactionProcessor transactionProcessor = protocolSpec.getTransactionProcessor();
final AbstractBlockProcessor.TransactionReceiptFactory transactionReceiptFactory = protocolSpec.getTransactionReceiptFactory();
final BlockTransactionSelector selector = new BlockTransactionSelector(transactionProcessor, protocolContext.getBlockchain(), disposableWorldState, pendingTransactions, processableBlockHeader, transactionReceiptFactory, minTransactionGasPrice, minBlockOccupancyRatio, isCancelled::get, miningBeneficiary, protocolSpec.getFeeMarket());
if (transactions.isPresent()) {
return selector.evaluateTransactions(transactions.get());
} else {
return selector.buildTransactionListForBlock();
}
}
use of org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor in project besu by hyperledger.
the class TransactionSimulator method processWithWorldUpdater.
@Nonnull
public Optional<TransactionSimulatorResult> processWithWorldUpdater(final CallParameter callParams, final TransactionValidationParams transactionValidationParams, final OperationTracer operationTracer, final BlockHeader header, final WorldUpdater updater) {
final ProtocolSpec protocolSpec = protocolSchedule.getByBlockNumber(header.getNumber());
final Address senderAddress = callParams.getFrom() != null ? callParams.getFrom() : DEFAULT_FROM;
BlockHeader blockHeaderToProcess = header;
if (transactionValidationParams.isAllowExceedingBalance() && header.getBaseFee().isPresent()) {
blockHeaderToProcess = BlockHeaderBuilder.fromHeader(header).baseFee(Wei.ZERO).blockHeaderFunctions(protocolSpec.getBlockHeaderFunctions()).buildBlockHeader();
}
final Account sender = updater.get(senderAddress);
final long nonce = sender != null ? sender.getNonce() : 0L;
final long gasLimit = callParams.getGasLimit() >= 0 ? 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.getByBlockNumber(blockHeaderToProcess.getNumber()).getTransactionProcessor();
final Optional<Transaction> maybeTransaction = buildTransaction(callParams, transactionValidationParams, header, senderAddress, nonce, gasLimit, value, payload);
if (maybeTransaction.isEmpty()) {
return Optional.empty();
}
final Transaction transaction = maybeTransaction.get();
final TransactionProcessingResult result = transactionProcessor.processTransaction(blockchain, updater, blockHeaderToProcess, transaction, protocolSpec.getMiningBeneficiaryCalculator().calculateBeneficiary(blockHeaderToProcess), new BlockHashLookup(blockHeaderToProcess, blockchain), false, transactionValidationParams, operationTracer);
// If GoQuorum privacy enabled, and value = zero, get max gas possible for a PMT hash.
// It is possible to have a data field that has a lower intrinsic value than the PMT hash.
// This means a potential over-estimate of gas, but the tx, if sent with this gas, will not
// fail.
final boolean goQuorumCompatibilityMode = transactionProcessor.getTransactionValidator().getGoQuorumCompatibilityMode();
if (goQuorumCompatibilityMode && value.isZero()) {
final long privateGasEstimateAndState = protocolSpec.getGasCalculator().getMaximumTransactionCost(64);
if (privateGasEstimateAndState > result.getEstimateGasUsedByTransaction()) {
// modify the result to have the larger estimate
final TransactionProcessingResult resultPmt = TransactionProcessingResult.successful(result.getLogs(), privateGasEstimateAndState, result.getGasRemaining(), result.getOutput(), result.getValidationResult());
return Optional.of(new TransactionSimulatorResult(transaction, resultPmt));
}
}
return Optional.of(new TransactionSimulatorResult(transaction, result));
}
use of org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor in project besu by hyperledger.
the class BlockTransactionSelectorTest method emptyPendingTransactionsResultsInEmptyVettingResult.
@Test
public void emptyPendingTransactionsResultsInEmptyVettingResult() {
final ProtocolSchedule protocolSchedule = FixedDifficultyProtocolSchedule.create(GenesisConfigFile.development().getConfigOptions(), EvmConfiguration.DEFAULT);
final MainnetTransactionProcessor mainnetTransactionProcessor = protocolSchedule.getByBlockNumber(0).getTransactionProcessor();
// The block should fit 5 transactions only
final ProcessableBlockHeader blockHeader = createBlockWithGasLimit(5000);
final Address miningBeneficiary = AddressHelpers.ofValue(1);
final BlockTransactionSelector selector = new BlockTransactionSelector(mainnetTransactionProcessor, blockchain, worldState, pendingTransactions, blockHeader, this::createReceipt, Wei.ZERO, 0.8, this::isCancelled, miningBeneficiary, FeeMarket.legacy());
final BlockTransactionSelector.TransactionSelectionResults results = selector.buildTransactionListForBlock();
assertThat(results.getTransactions().size()).isEqualTo(0);
assertThat(results.getReceipts().size()).isEqualTo(0);
assertThat(results.getCumulativeGasUsed()).isEqualTo(0);
}
use of org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor in project besu by hyperledger.
the class StateTestSubCommand method traceTestSpecs.
private void traceTestSpecs(final String test, final List<GeneralStateTestCaseEipSpec> specs) {
Log4j2ConfiguratorUtil.setLevel("org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder", Level.OFF);
final var referenceTestProtocolSchedules = ReferenceTestProtocolSchedules.create();
Log4j2ConfiguratorUtil.setLevel("org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder", null);
final // You should have picked Mercy.
OperationTracer tracer = parentCommand.showJsonResults ? new StandardJsonTracer(output, !parentCommand.noMemory) : OperationTracer.NO_TRACING;
for (final GeneralStateTestCaseEipSpec spec : specs) {
final BlockHeader blockHeader = spec.getBlockHeader();
final WorldState initialWorldState = spec.getInitialWorldState();
final Transaction transaction = spec.getTransaction();
final ObjectNode summaryLine = objectMapper.createObjectNode();
if (transaction == null) {
// Check the world state root hash.
summaryLine.put("test", test);
summaryLine.put("fork", spec.getFork());
summaryLine.put("d", spec.getDataIndex());
summaryLine.put("g", spec.getGasIndex());
summaryLine.put("v", spec.getValueIndex());
summaryLine.put("pass", spec.getExpectException() != null);
summaryLine.put("validationError", "Transaction had out-of-bounds parameters");
} else {
final MutableWorldState worldState = new DefaultMutableWorldState(initialWorldState);
// `TransactionProcessor`, so these tests are skipped.
if (transaction.getGasLimit() > blockHeader.getGasLimit() - blockHeader.getGasUsed()) {
return;
}
final String forkName = fork == null ? spec.getFork() : fork;
final ProtocolSchedule protocolSchedule = referenceTestProtocolSchedules.getByName(forkName);
if (protocolSchedule == null) {
throw new UnsupportedForkException(forkName);
}
final MainnetTransactionProcessor processor = protocolSchedule.getByBlockNumber(0).getTransactionProcessor();
final WorldUpdater worldStateUpdater = worldState.updater();
final ReferenceTestBlockchain blockchain = new ReferenceTestBlockchain(blockHeader.getNumber());
final Stopwatch timer = Stopwatch.createStarted();
final TransactionProcessingResult result = processor.processTransaction(blockchain, worldStateUpdater, blockHeader, transaction, blockHeader.getCoinbase(), new BlockHashLookup(blockHeader, blockchain), false, TransactionValidationParams.processingBlock(), tracer);
timer.stop();
if (shouldClearEmptyAccounts(spec.getFork())) {
final Account coinbase = worldStateUpdater.getOrCreate(spec.getBlockHeader().getCoinbase());
if (coinbase != null && coinbase.isEmpty()) {
worldStateUpdater.deleteAccount(coinbase.getAddress());
}
final Account sender = worldStateUpdater.getAccount(transaction.getSender());
if (sender != null && sender.isEmpty()) {
worldStateUpdater.deleteAccount(sender.getAddress());
}
}
worldStateUpdater.commit();
summaryLine.put("output", result.getOutput().toUnprefixedHexString());
final UInt256 gasUsed = UInt256.valueOf(transaction.getGasLimit() - result.getGasRemaining());
summaryLine.put("gasUsed", StandardJsonTracer.shortNumber(gasUsed));
summaryLine.put("time", timer.elapsed(TimeUnit.NANOSECONDS));
// Check the world state root hash.
summaryLine.put("test", test);
summaryLine.put("fork", spec.getFork());
summaryLine.put("d", spec.getDataIndex());
summaryLine.put("g", spec.getGasIndex());
summaryLine.put("v", spec.getValueIndex());
summaryLine.put("postHash", worldState.rootHash().toHexString());
final List<Log> logs = result.getLogs();
final Hash actualLogsHash = Hash.hash(RLP.encode(out -> out.writeList(logs, Log::writeTo)));
summaryLine.put("postLogsHash", actualLogsHash.toHexString());
summaryLine.put("pass", spec.getExpectException() == null && worldState.rootHash().equals(spec.getExpectedRootHash()) && actualLogsHash.equals(spec.getExpectedLogsHash()));
if (result.isInvalid()) {
summaryLine.put("validationError", result.getValidationResult().getErrorMessage());
} else if (spec.getExpectException() != null) {
summaryLine.put("validationError", "Exception '" + spec.getExpectException() + "' was expected but did not occur");
}
}
output.println(summaryLine);
}
}
Aggregations