Make tracer in block building block aware (#6135)

Signed-off-by: stefan.pingel@consensys.net <stefan.pingel@consensys.net>
pull/6148/head
Stefan Pingel 12 months ago committed by GitHub
parent 228424215c
commit f42f8c1122
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 39
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockCreator.java
  2. 18
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java
  3. 4
      ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/AbstractBlockTransactionSelectorTest.java
  4. 11
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetTransactionProcessor.java
  5. 25
      evm/src/main/java/org/hyperledger/besu/evm/tracing/StandardJsonTracer.java
  6. 2
      plugin-api/build.gradle
  7. 8
      plugin-api/src/main/java/org/hyperledger/besu/plugin/services/tracer/BlockAwareOperationTracer.java
  8. 6
      plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/PluginTransactionSelector.java

@ -24,6 +24,7 @@ import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.blockcreation.txselection.BlockTransactionSelector;
import org.hyperledger.besu.ethereum.blockcreation.txselection.TransactionSelectionResults;
import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.AllAcceptingTransactionSelector;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockBody;
import org.hyperledger.besu.ethereum.core.BlockHeader;
@ -56,6 +57,9 @@ import org.hyperledger.besu.evm.account.MutableAccount;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import org.hyperledger.besu.plugin.services.exception.StorageException;
import org.hyperledger.besu.plugin.services.securitymodule.SecurityModuleException;
import org.hyperledger.besu.plugin.services.tracer.BlockAwareOperationTracer;
import org.hyperledger.besu.plugin.services.txselection.PluginTransactionSelector;
import org.hyperledger.besu.plugin.services.txselection.PluginTransactionSelectorFactory;
import java.math.BigInteger;
import java.util.List;
@ -183,13 +187,26 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
disposableWorldState.updater(), timestamp, bytes32));
throwIfStopped();
final PluginTransactionSelector pluginTransactionSelector =
protocolContext
.getTransactionSelectorFactory()
.map(PluginTransactionSelectorFactory::create)
.orElseGet(() -> AllAcceptingTransactionSelector.INSTANCE);
final BlockAwareOperationTracer operationTracer =
pluginTransactionSelector.getOperationTracer();
operationTracer.traceStartBlock(processableBlockHeader);
final TransactionSelectionResults transactionResults =
selectTransactions(
processableBlockHeader,
disposableWorldState,
maybeTransactions,
miningBeneficiary,
newProtocolSpec);
newProtocolSpec,
pluginTransactionSelector);
transactionResults.logSelectionStats();
@ -261,14 +278,13 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
final Optional<List<Withdrawal>> withdrawals =
withdrawalsCanBeProcessed ? maybeWithdrawals : Optional.empty();
final Block block =
new Block(
blockHeader,
new BlockBody(
transactionResults.getSelectedTransactions(),
ommers,
withdrawals,
maybeDeposits));
final BlockBody blockBody =
new BlockBody(
transactionResults.getSelectedTransactions(), ommers, withdrawals, maybeDeposits);
final Block block = new Block(blockHeader, blockBody);
operationTracer.traceEndBlock(blockHeader, blockBody);
return new BlockCreationResult(block, transactionResults);
} catch (final SecurityModuleException ex) {
throw new IllegalStateException("Failed to create block signature", ex);
@ -316,7 +332,8 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
final MutableWorldState disposableWorldState,
final Optional<List<Transaction>> transactions,
final Address miningBeneficiary,
final ProtocolSpec protocolSpec)
final ProtocolSpec protocolSpec,
final PluginTransactionSelector pluginTransactionSelector)
throws RuntimeException {
final MainnetTransactionProcessor transactionProcessor = protocolSpec.getTransactionProcessor();
@ -343,7 +360,7 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
protocolSpec.getFeeMarket(),
protocolSpec.getGasCalculator(),
protocolSpec.getGasLimitCalculator(),
protocolContext.getTransactionSelectorFactory());
pluginTransactionSelector);
if (transactions.isPresent()) {
return selector.evaluateTransactions(transactions.get());

@ -18,7 +18,6 @@ import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.GasLimitCalculator;
import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.AbstractTransactionSelector;
import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.AllAcceptingTransactionSelector;
import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.BlobPriceTransactionSelector;
import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.BlockSizeTransactionSelector;
import org.hyperledger.besu.ethereum.blockcreation.txselection.selectors.MinPriorityFeePerGasTransactionSelector;
@ -40,14 +39,12 @@ import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.vm.BlockHashLookup;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
import org.hyperledger.besu.evm.tracing.OperationTracer;
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
import org.hyperledger.besu.plugin.data.TransactionSelectionResult;
import org.hyperledger.besu.plugin.services.tracer.BlockAwareOperationTracer;
import org.hyperledger.besu.plugin.services.txselection.PluginTransactionSelector;
import org.hyperledger.besu.plugin.services.txselection.PluginTransactionSelectorFactory;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CancellationException;
import java.util.function.Supplier;
@ -87,7 +84,7 @@ public class BlockTransactionSelector {
new TransactionSelectionResults();
private final List<AbstractTransactionSelector> transactionSelectors;
private final PluginTransactionSelector pluginTransactionSelector;
private final OperationTracer pluginOperationTracer;
private final BlockAwareOperationTracer pluginOperationTracer;
public BlockTransactionSelector(
final MiningParameters miningParameters,
@ -103,7 +100,7 @@ public class BlockTransactionSelector {
final FeeMarket feeMarket,
final GasCalculator gasCalculator,
final GasLimitCalculator gasLimitCalculator,
final Optional<PluginTransactionSelectorFactory> transactionSelectorFactory) {
final PluginTransactionSelector pluginTransactionSelector) {
this.transactionProcessor = transactionProcessor;
this.blockchain = blockchain;
this.worldState = worldState;
@ -120,11 +117,8 @@ public class BlockTransactionSelector {
miningBeneficiary,
transactionPool);
transactionSelectors = createTransactionSelectors(blockSelectionContext);
pluginTransactionSelector =
transactionSelectorFactory
.map(PluginTransactionSelectorFactory::create)
.orElse(AllAcceptingTransactionSelector.INSTANCE);
pluginOperationTracer = pluginTransactionSelector.getOperationTracer();
this.pluginTransactionSelector = pluginTransactionSelector;
this.pluginOperationTracer = pluginTransactionSelector.getOperationTracer();
}
private List<AbstractTransactionSelector> createTransactionSelectors(
@ -151,7 +145,9 @@ public class BlockTransactionSelector {
.setMessage("Transaction pool stats {}")
.addArgument(blockSelectionContext.transactionPool().logStats())
.log();
blockSelectionContext.transactionPool().selectTransactions(this::evaluateTransaction);
LOG.atTrace()
.setMessage("Transaction selection result {}")
.addArgument(transactionSelectionResults::toTraceLog)

@ -876,7 +876,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
getFeeMarket(),
new LondonGasCalculator(),
GasLimitCalculator.constant(),
Optional.empty());
AllAcceptingTransactionSelector.INSTANCE);
return selector;
}
@ -902,7 +902,7 @@ public abstract class AbstractBlockTransactionSelectorTest {
getFeeMarket(),
new LondonGasCalculator(),
GasLimitCalculator.constant(),
Optional.of(transactionSelectorFactory));
transactionSelectorFactory.create());
return selector;
}

@ -355,6 +355,8 @@ public class MainnetTransactionProcessor {
contextVariablesBuilder.put(KEY_PRIVATE_METADATA_UPDATER, privateMetadataUpdater);
}
operationTracer.traceStartTransaction(worldUpdater, transaction);
final MessageFrame.Builder commonMessageFrameBuilder =
MessageFrame.builder()
.maxStackSize(maxStackSize)
@ -451,6 +453,15 @@ public class MainnetTransactionProcessor {
.log();
final long gasUsedByTransaction = transaction.getGasLimit() - initialFrame.getRemainingGas();
operationTracer.traceEndTransaction(
worldUpdater,
transaction,
initialFrame.getState() == MessageFrame.State.COMPLETED_SUCCESS,
initialFrame.getOutputData(),
initialFrame.getLogs(),
gasUsedByTransaction,
0L);
// update the coinbase
final var coinbase = worldState.getOrCreate(miningBeneficiary);
final long usedGas = transaction.getGasLimit() - refundedGas;

@ -18,13 +18,9 @@ package org.hyperledger.besu.evm.tracing;
import static com.google.common.base.Strings.padStart;
import org.hyperledger.besu.datatypes.Transaction;
import org.hyperledger.besu.evm.frame.ExceptionalHaltReason;
import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.internal.Words;
import org.hyperledger.besu.evm.log.Log;
import org.hyperledger.besu.evm.operation.Operation;
import org.hyperledger.besu.evm.worldstate.WorldView;
import java.io.PrintStream;
import java.io.PrintWriter;
@ -256,25 +252,4 @@ public class StandardJsonTracer implements OperationTracer {
final MessageFrame frame, final Optional<ExceptionalHaltReason> haltReason) {
// precompile calls are not part of the standard trace
}
@Override
public void traceEndTransaction(
final WorldView _worldView,
final Transaction _tx,
final boolean _status,
final Bytes output,
final List<Log> _logs,
final long gasUsed,
final long timeNs) {
final StringBuilder sb = new StringBuilder(1024);
sb.append("{");
if (!output.isEmpty()) {
sb.append("\"output\":\"").append(output.toShortHexString()).append("\",");
} else {
sb.append("\"output\":\"\",");
}
sb.append("\"gasUsed\":\"").append(Words.longBytes(gasUsed).toShortHexString()).append("\",");
sb.append("\"time\":").append(timeNs).append("}");
out.println(sb);
}
}

@ -69,7 +69,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 = 'YYrWGQIwp1sgEmwx2DcfjiskFO8euGGKeWh7Lq1F+24='
knownHash = 'n4WfeMvltN4XWGtztd8ABjSU2TLiI3tk5yABivkgsFA='
}
check.dependsOn('checkAPIChanges')

@ -17,6 +17,7 @@ package org.hyperledger.besu.plugin.services.tracer;
import org.hyperledger.besu.evm.tracing.OperationTracer;
import org.hyperledger.besu.plugin.data.BlockBody;
import org.hyperledger.besu.plugin.data.BlockHeader;
import org.hyperledger.besu.plugin.data.ProcessableBlockHeader;
/**
* An extended operation tracer that can trace the start and end of a block.
@ -47,6 +48,13 @@ public interface BlockAwareOperationTracer extends OperationTracer {
*/
default void traceEndBlock(final BlockHeader blockHeader, final BlockBody blockBody) {}
/**
* When building a block this API is called at the start of the process
*
* @param processableBlockHeader the processable header
*/
default void traceStartBlock(final ProcessableBlockHeader processableBlockHeader) {}
@Override
default boolean isExtendedTracing() {
return true;

@ -16,10 +16,10 @@
package org.hyperledger.besu.plugin.services.txselection;
import org.hyperledger.besu.datatypes.PendingTransaction;
import org.hyperledger.besu.evm.tracing.OperationTracer;
import org.hyperledger.besu.plugin.Unstable;
import org.hyperledger.besu.plugin.data.TransactionProcessingResult;
import org.hyperledger.besu.plugin.data.TransactionSelectionResult;
import org.hyperledger.besu.plugin.services.tracer.BlockAwareOperationTracer;
/** Interface for the transaction selector */
@Unstable
@ -31,8 +31,8 @@ public interface PluginTransactionSelector {
*
* @return OperationTracer to be used to trace candidate transactions
*/
default OperationTracer getOperationTracer() {
return OperationTracer.NO_TRACING;
default BlockAwareOperationTracer getOperationTracer() {
return BlockAwareOperationTracer.NO_TRACING;
}
/**

Loading…
Cancel
Save