chore(foundation): faster toBufferBE via zero fast-path#23592
Merged
Conversation
PhilWindle
approved these changes
May 27, 2026
danielntmd
pushed a commit
to danielntmd/aztec-packages
that referenced
this pull request
Jun 4, 2026
BEGIN_COMMIT_OVERRIDE fix(archiver): skip descendants of invalid-attestations checkpoints (AztecProtocol#23502) chore: scale network validators (AztecProtocol#23579) fix(ci): nightly 10 TPS bench GCP auth and checkout (AztecProtocol#23586) chore: set eth node resource profile (AztecProtocol#23583) fix: wait for checkpoint before sentinel assertions (AztecProtocol#23573) fix: slash attestations for invalid checkpoint proposals (AztecProtocol#23506) test: fix web3signer pipelining `e2e_multi_validator_node_key_store.test.ts` (AztecProtocol#23568) fix: cap CI devbox hostname (AztecProtocol#23591) test: stabilize invalid checkpoint descendant e2e (AztecProtocol#23582) test(e2e): stabilize invalidation slots in `proposer invalidates multiple checkpoints` (AztecProtocol#23590) test(e2e): stabilize invalid proposal slashing target slot in `attested_invalid_proposal` (AztecProtocol#23589) chore(foundation): faster toBufferBE via zero fast-path (AztecProtocol#23592) fix: honour BB_BINARY_PATH (AztecProtocol#23570) chore: bump reth and lighthouse (AztecProtocol#23588) chore: add web3signer and postgres node selectors (AztecProtocol#23598) fix: do not symlink .codex folders (AztecProtocol#23593) chore: fix claude and codex symlinking tests (AztecProtocol#23599) test(e2e): narrow down sentinel check in `multiple_validators_sentinel` (AztecProtocol#23604) test(e2e): fix `proposer invalidates multiple checkpoints` timeout (AztecProtocol#23608) fix: record zero-amount slashing offenses (AztecProtocol#23556) fix: log slashing offense names (AztecProtocol#23565) feat(p2p): tx validation cache (AztecProtocol#23585) chore: add KEDA deployment module (AztecProtocol#23553) chore: add KEDA prover agent autoscaling (AztecProtocol#23554) chore: update destroy_bootnode.sh (AztecProtocol#23626) chore: skip failing chonk_pinned_inputs.test in CI (AztecProtocol#23643) chore(ci): tolerate public authwit P2P receipt flake (AztecProtocol#23648) END_COMMIT_OVERRIDE
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a zero fast-path to
toBufferBE, the bigint→big-endian-buffer conversion underlyingFr.toBuffer(). Field elements serialized in protocol structs are overwhelmingly zero (kernel public inputs are mostly fixed-size zero-padding), so short-circuiting the zero case avoids a wastefulbigint → hex string → Buffer.from(hex)round-trip.Why
Profiling
Tx.toBuffer()showed it spends ~6.7ms almost entirely in per-fieldFr.toBuffer()across ~3900 fields, and 96% of those fields are zero. The scalar conversion is already near-optimal otherwise — a 64-bit-words variant (writeBigUInt64BE×4) is actually slower on real (non-zero) field elements because V8's bigint shifts allocate.Micro-benchmark of
toBufferBEvariants (width=32, correctness-checked against current):The fast-path is ~8× on the real workload and costs one
=== 0ncompare on the worst case.Impact
End-to-end on
mockTx(42):tx.toBuffer()totaldata.toBuffer()data.toBuffer()(the kernel public inputs) is the production-relevant figure: the mock serializes an uncompressed proof, whereas real txs carry a compressed proof that serializes as a single blob. The benefit applies to everyFr.toBuffer()/ serialization path in the monorepo, not just txs.The remaining cost is structural — a Buffer is allocated per field and then
Buffer.concat'd across thousands of them. Eliminating that needs a single-preallocated-buffer serializer; this change is the safe, broadly-beneficial first step.Testing
toBufferBEpreviously had no direct unit tests; added coverage for the zero path, big-endian left-padding, exact-width values, and the negative-input throw. The conversion is otherwise byte-identical to before.