Skip to content

Conversation

daniellehrner
Copy link
Contributor

@daniellehrner daniellehrner commented Mar 28, 2025

PR description

We need to count the zero bytes of the transaction payload to calculate the intrinsic gas cost. Right now we do this up to 3 times:

  1. When we receive a tx and add it to the tx pool
  2. At the start of the transaction processing when we validate a tx
  3. When we calculate and deduct the intrinsic gas cost during tx processing

This PR caches the number of zero bytes in the tx object, which avoids recounting them and should be more efficient.

Thanks for sending a pull request! Have you done the following?

  • Checked out our contribution guidelines?
  • Considered documentation and added the doc-change-required label to this PR if updates are required.
  • Considered the changelog and included an update if required.
  • For database changes (e.g. KeyValueSegmentIdentifier) considered compatibility and performed forwards and backwards compatibility tests

Locally, you can run these tests to catch failures early:

  • spotless: ./gradlew spotlessApply
  • unit tests: ./gradlew build
  • acceptance tests: ./gradlew acceptanceTest
  • integration tests: ./gradlew integrationTest
  • reference tests: ./gradlew ethereum:referenceTests:referenceTests

@daniellehrner daniellehrner force-pushed the feat/cache_payload_zero_bytes branch 3 times, most recently from d9c570e to 53c554e Compare April 1, 2025 15:16
@daniellehrner daniellehrner requested a review from Copilot April 1, 2025 15:41
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This pull request implements caching for the number of zero bytes in the transaction payload by introducing a dedicated Payload class and updating gas calculation and transaction processing methods accordingly. Key changes include:

  • Updating gas calculator methods (transactionIntrinsicGasCost and transactionFloorCost) to accept an explicit payloadZeroBytes parameter.
  • Replacing direct use of Bytes payload in Transaction with a new Payload object that caches its zero byte count.
  • Adjusting tests and API calls to use the new method signatures and improved payload handling.

Reviewed Changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
evm/src/test/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculatorTest.java Updated floor cost tests to pass an explicit payloadZeroBytes argument.
evm/src/test/java/org/hyperledger/besu/evm/gascalculator/FrontierGasCalculatorTest.java Modified tests to use the new gas cost method signatures.
evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java Refactored transactionFloorCost to include payloadZeroBytes.
evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java Updated interface signatures for intrinsic and floor gas cost methods.
evm/src/main/java/org/hyperledger/besu/evm/gascalculator/FrontierGasCalculator.java Adjusted intrinsic gas cost calculations with the new transaction method signature.
ethereum/referencetests/.../TransactionTest.java Updated tests to use the revised transactionIntrinsicGasCost method.
ethereum/evmtool/.../T8nExecutor.java and EvmToolCommand.java Updated gas cost calls to pass the new parameters.
ethereum/core/.../Transaction.java Replaced the raw payload with a Payload object and updated related methods.
ethereum/core/.../Payload.java Introduced the Payload class for caching and computing zero byte counts.
ethereum/api/.../PluginEeaSendRawTransaction.java Updated usage to create an unsigned transaction using the new payload handling.
datatypes/src/main/java/org/hyperledger/besu/datatypes/Transaction.java Extended the Transaction interface to expose payload and zero byte count.

@@ -1296,7 +1297,7 @@ public Builder copiedFrom(final Transaction toCopy) {
this.to = toCopy.to;
this.value = toCopy.value;
this.signature = toCopy.signature;
this.payload = toCopy.payload;
this.payload = toCopy.payload.getPayload();
Copy link
Preview

Copilot AI Apr 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Directly copying the payload bytes bypasses the caching mechanism provided by the Payload class. Consider preserving the Payload object by copying or reusing the entire Payload instance instead.

Suggested change
this.payload = toCopy.payload.getPayload();
this.payload = toCopy.payload;

Copilot uses AI. Check for mistakes.

Signed-off-by: daniellehrner <daniel.lehrner@consensys.net>
Signed-off-by: daniellehrner <daniel.lehrner@consensys.net>
Signed-off-by: daniellehrner <daniel.lehrner@consensys.net>
Signed-off-by: daniellehrner <daniel.lehrner@consensys.net>
@daniellehrner daniellehrner force-pushed the feat/cache_payload_zero_bytes branch from 53c554e to a279d84 Compare April 2, 2025 10:37
@daniellehrner daniellehrner marked this pull request as ready for review April 2, 2025 10:38
@hyperledger hyperledger deleted a comment from Copilot AI Apr 2, 2025
Copy link
Contributor

@garyschulte garyschulte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just some comments and suggestions

Comment on lines +64 to +71
private long computeZeroBytes() {
int zeros = 0;
for (int i = 0; i < payloadBytes.size(); i++) {
if (payloadBytes.get(i) == 0) {
zeros += 1;
}
}
return zeros;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if/how we can determine this is using simd under-the-hood. Non-blocking just curious. @ahamlat ?

Signed-off-by: daniellehrner <daniel.lehrner@consensys.net>
@daniellehrner
Copy link
Contributor Author

@garyschulte Do you think it's ready to merged with the latest changes? If yes, could you please approve?

Copy link
Contributor

@garyschulte garyschulte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@daniellehrner daniellehrner merged commit 9c52f52 into hyperledger:main Apr 7, 2025
43 checks passed
@daniellehrner daniellehrner deleted the feat/cache_payload_zero_bytes branch April 7, 2025 12:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants