Skip to content

compute blob tx KZG commitments once per test class#10095

Merged
macfarla merged 6 commits intobesu-eth:mainfrom
macfarla:optimiz-tx-pool-blob-fixtures
Mar 24, 2026
Merged

compute blob tx KZG commitments once per test class#10095
macfarla merged 6 commits intobesu-eth:mainfrom
macfarla:optimiz-tx-pool-blob-fixtures

Conversation

@macfarla
Copy link
Contributor

The 4 blob transaction fields in AbstractTransactionPoolTestBase were instance fields, causing ~1980 native KZG JNI operations per test run of LegacyTransactionPoolGasPriceTest (3 calls × 6 blobs × 2 ops × 55 test instances). Each BlobTestFixture starts from byteValue=0x00, so all instances produced identical blob data.

Make the 4 blob transaction fields static final, computed once at class load via private static factory methods. The existing instance methods are retained for TransactionPoolSaveRestoreTest which calls createBlobTransaction() at test-method time with the real blockGasLimit.
AbstractTransactionPoolTestBase.java

  • Added private static final BlobTestFixture BLOB_TEST_FIXTURE — shared fixture initialized once
  • Changed 4 blob transaction fields from protected final → protected static final, calling new private static factory methods
  • Added createStaticBlobTransaction, createStaticBlobTransactionWithSameBlobs, createStaticReplacementTransactionWithBlobs — private static methods using gasLimit(0L) (same as the instance fields got anyway, since blockGasLimit=0 at init time)
  • Kept the existing instance methods (createBlobTransaction, etc.) for TransactionPoolSaveRestoreTest which legitimately calls them at test-run time
  • Removed the null checks from the instance methods (they now use the shared static BLOB_TEST_FIXTURE)

Net effect: 1,980 native KZG JNI operations per test run → 36.

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

  • spotless: ./gradlew spotlessApply
  • unit tests: ./gradlew build

The 4 blob transaction fields in AbstractTransactionPoolTestBase were
instance fields, causing ~1980 native KZG JNI operations per test run of
LegacyTransactionPoolGasPriceTest (3 calls × 6 blobs × 2 ops × 55 test
instances). Each BlobTestFixture starts from byteValue=0x00, so all
instances produced identical blob data.

Make the 4 blob transaction fields static final, computed once at class
load via private static factory methods. The existing instance methods
are retained for TransactionPoolSaveRestoreTest which calls
createBlobTransaction() at test-method time with the real blockGasLimit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
Copilot AI review requested due to automatic review settings March 24, 2026 07:22
@macfarla macfarla added testing dev experience The build system, things that enable easier development etc. labels Mar 24, 2026
Copy link
Contributor

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 PR reduces expensive native KZG JNI work in transaction pool tests by caching blob-transaction test fixtures at class-load time rather than per test instance.

Changes:

  • Converted blob-related transaction fixtures from instance fields to static final fields computed once.
  • Introduced private static factory methods for creating the cached blob transactions.
  • Switched instance-time blob transaction creation to use a shared static final BlobTestFixture.

macfarla and others added 3 commits March 24, 2026 17:48
…thods

The instance methods createBlobTransaction and
createReplacementTransactionWithBlobs were updated to use the shared
static BLOB_TEST_FIXTURE, which introduces order-dependent test
behaviour and thread-safety concerns for tests that call these methods
at test-run time (e.g. TransactionPoolSaveRestoreTest).

Use a fresh BlobTestFixture per call in the instance methods instead.
The fixture itself is cheap to construct (no KZG work); only the
createBlobsWithCommitments call does native KZG computation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
@macfarla
Copy link
Contributor Author

old time:

BUILD SUCCESSFUL in 3m 27s
68 actionable tasks: 68 executed
Consider enabling configuration cache to speed up this build: https://docs.gradle.org/9.3.1/userguide/configuration_cache_enabling.html
./gradlew :ethereum:eth:test --tests "*LegacyTransactionPoolGasPriceTest*"   1.27s user 0.22s system 0% cpu 3:28.55 total

new time:

BUILD SUCCESSFUL in 2m 5s
68 actionable tasks: 68 executed
Consider enabling configuration cache to speed up this build: https://docs.gradle.org/9.3.1/userguide/configuration_cache_enabling.html
./gradlew :ethereum:eth:test --tests "*LegacyTransactionPoolGasPriceTest*"   1.13s user 0.20s system 1% cpu 2:06.26 total

and there are 4 classes that extend from this same Abstract class

Copy link
Contributor

@usmansaleem usmansaleem left a comment

Choose a reason for hiding this comment

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

LGTM

@macfarla macfarla enabled auto-merge (squash) March 24, 2026 16:01
@macfarla macfarla merged commit da48e42 into besu-eth:main Mar 24, 2026
46 checks passed
@macfarla macfarla deleted the optimiz-tx-pool-blob-fixtures branch March 24, 2026 21:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dev experience The build system, things that enable easier development etc. testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants