Add pending block header to TransactionEvaluationContext (#7483)

Add pending block header to TransactionEvaluationContext plugin API, so PluginTransactionSelector can access info of the pending block.

---
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
Co-authored-by: Usman Saleem <usman@usmans.info>
pull/7493/head
Fabio Di Fabio 3 months ago committed by GitHub
parent c24dea8474
commit 19e1a9aaf6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 2
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockSelectionContext.java
  3. 7
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/BlockTransactionSelector.java
  4. 12
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/TransactionEvaluationContext.java
  5. 6
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlockSizeTransactionSelector.java
  6. 2
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/MinPriorityFeePerGasTransactionSelector.java
  7. 17
      ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/MinPriorityFeePerGasTransactionSelectorTest.java
  8. 16
      ethereum/blockcreation/src/test/java/org/hyperledger/besu/ethereum/blockcreation/txselection/selectors/BlobSizeTransactionSelectorTest.java
  9. 2
      plugin-api/build.gradle
  10. 8
      plugin-api/src/main/java/org/hyperledger/besu/plugin/services/txselection/TransactionEvaluationContext.java

@ -9,6 +9,7 @@
### Additions and Improvements ### Additions and Improvements
- Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461) - Add 'inbound' field to admin_peers JSON-RPC Call [#7461](https://github.com/hyperledger/besu/pull/7461)
- Add pending block header to `TransactionEvaluationContext` plugin API [#7483](https://github.com/hyperledger/besu/pull/7483)
### Bug fixes ### Bug fixes
- Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318) - Fix tracing in precompiled contracts when halting for out of gas [#7318](https://github.com/hyperledger/besu/issues/7318)

@ -29,7 +29,7 @@ public record BlockSelectionContext(
GasCalculator gasCalculator, GasCalculator gasCalculator,
GasLimitCalculator gasLimitCalculator, GasLimitCalculator gasLimitCalculator,
BlockHashProcessor blockHashProcessor, BlockHashProcessor blockHashProcessor,
ProcessableBlockHeader processableBlockHeader, ProcessableBlockHeader pendingBlockHeader,
FeeMarket feeMarket, FeeMarket feeMarket,
Wei blobGasPrice, Wei blobGasPrice,
Address miningBeneficiary, Address miningBeneficiary,

@ -263,9 +263,10 @@ public class BlockTransactionSelector {
.getTransactionPriceCalculator() .getTransactionPriceCalculator()
.price( .price(
pendingTransaction.getTransaction(), pendingTransaction.getTransaction(),
blockSelectionContext.processableBlockHeader().getBaseFee()); blockSelectionContext.pendingBlockHeader().getBaseFee());
return new TransactionEvaluationContext( return new TransactionEvaluationContext(
blockSelectionContext.pendingBlockHeader(),
pendingTransaction, pendingTransaction,
Stopwatch.createStarted(), Stopwatch.createStarted(),
transactionGasPriceInBlock, transactionGasPriceInBlock,
@ -330,10 +331,10 @@ public class BlockTransactionSelector {
private TransactionProcessingResult processTransaction( private TransactionProcessingResult processTransaction(
final PendingTransaction pendingTransaction, final WorldUpdater worldStateUpdater) { final PendingTransaction pendingTransaction, final WorldUpdater worldStateUpdater) {
final BlockHashLookup blockHashLookup = final BlockHashLookup blockHashLookup =
new CachingBlockHashLookup(blockSelectionContext.processableBlockHeader(), blockchain); new CachingBlockHashLookup(blockSelectionContext.pendingBlockHeader(), blockchain);
return transactionProcessor.processTransaction( return transactionProcessor.processTransaction(
worldStateUpdater, worldStateUpdater,
blockSelectionContext.processableBlockHeader(), blockSelectionContext.pendingBlockHeader(),
pendingTransaction.getTransaction(), pendingTransaction.getTransaction(),
blockSelectionContext.miningBeneficiary(), blockSelectionContext.miningBeneficiary(),
pluginOperationTracer, pluginOperationTracer,

@ -17,23 +17,26 @@ package org.hyperledger.besu.ethereum.blockcreation.txselection;
import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction; import org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction;
import org.hyperledger.besu.plugin.data.ProcessableBlockHeader;
import com.google.common.base.Stopwatch; import com.google.common.base.Stopwatch;
public class TransactionEvaluationContext public class TransactionEvaluationContext
implements org.hyperledger.besu.plugin.services.txselection.TransactionEvaluationContext< implements org.hyperledger.besu.plugin.services.txselection.TransactionEvaluationContext<
PendingTransaction> { PendingTransaction> {
private final org.hyperledger.besu.ethereum.eth.transactions.PendingTransaction private final ProcessableBlockHeader pendingBlockHeader;
pendingTransaction; private final PendingTransaction pendingTransaction;
private final Stopwatch evaluationTimer; private final Stopwatch evaluationTimer;
private final Wei transactionGasPrice; private final Wei transactionGasPrice;
private final Wei minGasPrice; private final Wei minGasPrice;
public TransactionEvaluationContext( public TransactionEvaluationContext(
final ProcessableBlockHeader pendingBlockHeader,
final PendingTransaction pendingTransaction, final PendingTransaction pendingTransaction,
final Stopwatch evaluationTimer, final Stopwatch evaluationTimer,
final Wei transactionGasPrice, final Wei transactionGasPrice,
final Wei minGasPrice) { final Wei minGasPrice) {
this.pendingBlockHeader = pendingBlockHeader;
this.pendingTransaction = pendingTransaction; this.pendingTransaction = pendingTransaction;
this.evaluationTimer = evaluationTimer; this.evaluationTimer = evaluationTimer;
this.transactionGasPrice = transactionGasPrice; this.transactionGasPrice = transactionGasPrice;
@ -44,6 +47,11 @@ public class TransactionEvaluationContext
return pendingTransaction.getTransaction(); return pendingTransaction.getTransaction();
} }
@Override
public ProcessableBlockHeader getPendingBlockHeader() {
return pendingBlockHeader;
}
@Override @Override
public PendingTransaction getPendingTransaction() { public PendingTransaction getPendingTransaction() {
return pendingTransaction; return pendingTransaction;

@ -91,7 +91,7 @@ public class BlockSizeTransactionSelector extends AbstractTransactionSelector {
final TransactionSelectionResults transactionSelectionResults) { final TransactionSelectionResults transactionSelectionResults) {
return transaction.getGasLimit() return transaction.getGasLimit()
> context.processableBlockHeader().getGasLimit() > context.pendingBlockHeader().getGasLimit()
- transactionSelectionResults.getCumulativeGasUsed(); - transactionSelectionResults.getCumulativeGasUsed();
} }
@ -104,7 +104,7 @@ public class BlockSizeTransactionSelector extends AbstractTransactionSelector {
*/ */
private boolean blockOccupancyAboveThreshold( private boolean blockOccupancyAboveThreshold(
final TransactionSelectionResults transactionSelectionResults) { final TransactionSelectionResults transactionSelectionResults) {
final long gasAvailable = context.processableBlockHeader().getGasLimit(); final long gasAvailable = context.pendingBlockHeader().getGasLimit();
final long gasUsed = transactionSelectionResults.getCumulativeGasUsed(); final long gasUsed = transactionSelectionResults.getCumulativeGasUsed();
final long gasRemaining = gasAvailable - gasUsed; final long gasRemaining = gasAvailable - gasUsed;
@ -129,7 +129,7 @@ public class BlockSizeTransactionSelector extends AbstractTransactionSelector {
* @return True if the block is full, false otherwise. * @return True if the block is full, false otherwise.
*/ */
private boolean blockFull(final TransactionSelectionResults transactionSelectionResults) { private boolean blockFull(final TransactionSelectionResults transactionSelectionResults) {
final long gasAvailable = context.processableBlockHeader().getGasLimit(); final long gasAvailable = context.pendingBlockHeader().getGasLimit();
final long gasUsed = transactionSelectionResults.getCumulativeGasUsed(); final long gasUsed = transactionSelectionResults.getCumulativeGasUsed();
final long gasRemaining = gasAvailable - gasUsed; final long gasRemaining = gasAvailable - gasUsed;

@ -68,7 +68,7 @@ public class MinPriorityFeePerGasTransactionSelector extends AbstractTransaction
Wei priorityFeePerGas = Wei priorityFeePerGas =
pendingTransaction pendingTransaction
.getTransaction() .getTransaction()
.getEffectivePriorityFeePerGas(context.processableBlockHeader().getBaseFee()); .getEffectivePriorityFeePerGas(context.pendingBlockHeader().getBaseFee());
return priorityFeePerGas.lessThan(context.miningParameters().getMinPriorityFeePerGas()); return priorityFeePerGas.lessThan(context.miningParameters().getMinPriorityFeePerGas());
} }

@ -33,11 +33,16 @@ import org.hyperledger.besu.plugin.data.TransactionSelectionResult;
import com.google.common.base.Stopwatch; import com.google.common.base.Stopwatch;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class MinPriorityFeePerGasTransactionSelectorTest { public class MinPriorityFeePerGasTransactionSelectorTest {
private AbstractTransactionSelector transactionSelector; private AbstractTransactionSelector transactionSelector;
private final int minPriorityFeeParameter = 7; private final int minPriorityFeeParameter = 7;
@Mock private ProcessableBlockHeader pendingBlockHeader;
@BeforeEach @BeforeEach
public void initialize() { public void initialize() {
@ -45,15 +50,7 @@ public class MinPriorityFeePerGasTransactionSelectorTest {
MiningParameters.newDefault().setMinPriorityFeePerGas(Wei.of(minPriorityFeeParameter)); MiningParameters.newDefault().setMinPriorityFeePerGas(Wei.of(minPriorityFeeParameter));
BlockSelectionContext context = BlockSelectionContext context =
new BlockSelectionContext( new BlockSelectionContext(
miningParameters, miningParameters, null, null, null, pendingBlockHeader, null, null, null, null);
null,
null,
null,
mock(ProcessableBlockHeader.class),
null,
null,
null,
null);
transactionSelector = new MinPriorityFeePerGasTransactionSelector(context); transactionSelector = new MinPriorityFeePerGasTransactionSelector(context);
} }
@ -100,6 +97,6 @@ public class MinPriorityFeePerGasTransactionSelectorTest {
when(pendingTransaction.getTransaction()).thenReturn(transaction); when(pendingTransaction.getTransaction()).thenReturn(transaction);
when(transaction.getEffectivePriorityFeePerGas(any())).thenReturn(Wei.of(priorityFeePerGas)); when(transaction.getEffectivePriorityFeePerGas(any())).thenReturn(Wei.of(priorityFeePerGas));
return new TransactionEvaluationContext( return new TransactionEvaluationContext(
pendingTransaction, Stopwatch.createStarted(), Wei.ONE, Wei.ONE); pendingBlockHeader, pendingTransaction, Stopwatch.createStarted(), Wei.ONE, Wei.ONE);
} }
} }

@ -76,7 +76,9 @@ class BlobSizeTransactionSelectorTest {
final var nonBlobTx = createEIP1559PendingTransaction(); final var nonBlobTx = createEIP1559PendingTransaction();
final var txEvaluationContext = new TransactionEvaluationContext(nonBlobTx, null, null, null); final var txEvaluationContext =
new TransactionEvaluationContext(
blockSelectionContext.pendingBlockHeader(), nonBlobTx, null, null, null);
final var result = final var result =
selector.evaluateTransactionPreProcessing(txEvaluationContext, selectionResults); selector.evaluateTransactionPreProcessing(txEvaluationContext, selectionResults);
@ -94,7 +96,9 @@ class BlobSizeTransactionSelectorTest {
final var firstBlobTx = createBlobPendingTransaction(MAX_BLOBS); final var firstBlobTx = createBlobPendingTransaction(MAX_BLOBS);
final var txEvaluationContext = new TransactionEvaluationContext(firstBlobTx, null, null, null); final var txEvaluationContext =
new TransactionEvaluationContext(
blockSelectionContext.pendingBlockHeader(), firstBlobTx, null, null, null);
when(selectionResults.getCumulativeBlobGasUsed()).thenReturn(0L); when(selectionResults.getCumulativeBlobGasUsed()).thenReturn(0L);
@ -112,7 +116,9 @@ class BlobSizeTransactionSelectorTest {
final var firstBlobTx = createBlobPendingTransaction(1); final var firstBlobTx = createBlobPendingTransaction(1);
final var txEvaluationContext = new TransactionEvaluationContext(firstBlobTx, null, null, null); final var txEvaluationContext =
new TransactionEvaluationContext(
blockSelectionContext.pendingBlockHeader(), firstBlobTx, null, null, null);
when(selectionResults.getCumulativeBlobGasUsed()).thenReturn(MAX_BLOB_GAS); when(selectionResults.getCumulativeBlobGasUsed()).thenReturn(MAX_BLOB_GAS);
@ -132,7 +138,9 @@ class BlobSizeTransactionSelectorTest {
final var firstBlobTx = createBlobPendingTransaction(MAX_BLOBS); final var firstBlobTx = createBlobPendingTransaction(MAX_BLOBS);
final var txEvaluationContext = new TransactionEvaluationContext(firstBlobTx, null, null, null); final var txEvaluationContext =
new TransactionEvaluationContext(
blockSelectionContext.pendingBlockHeader(), firstBlobTx, null, null, null);
when(selectionResults.getCumulativeBlobGasUsed()).thenReturn(MAX_BLOB_GAS - 1); when(selectionResults.getCumulativeBlobGasUsed()).thenReturn(MAX_BLOB_GAS - 1);

@ -70,7 +70,7 @@ Calculated : ${currentHash}
tasks.register('checkAPIChanges', FileStateChecker) { tasks.register('checkAPIChanges', FileStateChecker) {
description = "Checks that the API for the Plugin-API project does not change without deliberate thought" description = "Checks that the API for the Plugin-API project does not change without deliberate thought"
files = sourceSets.main.allJava.files files = sourceSets.main.allJava.files
knownHash = '6Hy3eaCpnxehyDO3smSAr1i2DsB2q/V37/m8POycikI=' knownHash = '2tFIKwEd8T5I37ywbFnVcMwTR8HiiCC6gO1Chd3hZp8='
} }
check.dependsOn('checkAPIChanges') check.dependsOn('checkAPIChanges')

@ -16,6 +16,7 @@ package org.hyperledger.besu.plugin.services.txselection;
import org.hyperledger.besu.datatypes.PendingTransaction; import org.hyperledger.besu.datatypes.PendingTransaction;
import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.plugin.data.ProcessableBlockHeader;
import com.google.common.base.Stopwatch; import com.google.common.base.Stopwatch;
@ -27,6 +28,13 @@ import com.google.common.base.Stopwatch;
*/ */
public interface TransactionEvaluationContext<PT extends PendingTransaction> { public interface TransactionEvaluationContext<PT extends PendingTransaction> {
/**
* Gets the pending block header
*
* @return the pending block header
*/
ProcessableBlockHeader getPendingBlockHeader();
/** /**
* Gets the pending transaction. * Gets the pending transaction.
* *

Loading…
Cancel
Save