feat: re-fork cometbft-bera onto the v0.39.x line - #51
Open
fridrik01 wants to merge 8 commits into
Open
Conversation
fridrik01
force-pushed
the
refork-cometbft-bera-to-0.39
branch
3 times, most recently
from
June 26, 2026 10:27
518c996 to
ecb80ec
Compare
fridrik01
force-pushed
the
refork-cometbft-bera-to-0.39
branch
from
July 23, 2026 11:08
f39c0b5 to
9fe10d1
Compare
|
The latest Buf updates on your PR. Results from workflow Protobuf Lint / lint (pull_request).
|
fridrik01
force-pushed
the
refork-cometbft-bera-to-0.39
branch
from
July 23, 2026 11:34
9fe10d1 to
71516da
Compare
There was a problem hiding this comment.
Pull request overview
Re-forks Berachain’s CometBFT customizations onto v0.39.3 while preserving bera-v1.x consensus and persisted-state compatibility.
Changes:
- Ports PBTS, BLS commit aggregation, and whole-commit catch-up.
- Adds ADR-115 next-block delays and next-proposer ABCI data.
- Updates protobuf formats, validator encoding, remote signing, tests, and tooling.
Reviewed changes
Copilot reviewed 91 out of 93 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
.golangci.yml |
Allows BLST imports. |
CHANGELOG.md |
Documents fork features and compatibility. |
buf.gen.yaml |
Maps protobuf wrappers for generation. |
version/version.go |
Sets Berachain fork version. |
blocksync/reactor.go |
Uses feature-based vote-extension settings. |
blocksync/reactor_test.go |
Updates blocksync fixtures for PBTS. |
consensus/state.go |
Integrates PBTS, aggregation, delays, and catch-up. |
consensus/state_test.go |
Adapts consensus state tests. |
consensus/state_ingest.go |
Uses feature parameters during ingestion. |
consensus/state_ingest_test.go |
Updates ingestion tests. |
consensus/reactor.go |
Gossips block-part hints and aggregated commits. |
consensus/reactor_test.go |
Updates reactor state expectations. |
consensus/replay.go |
Replays aggregated commit messages. |
consensus/replay_test.go |
Adapts proposal timestamps. |
consensus/msgs.go |
Converts new consensus messages. |
consensus/msgs_test.go |
Pins new message wire formats. |
consensus/metrics.go |
Defines PBTS and delay metrics. |
consensus/metrics.gen.go |
Generates metric implementations. |
consensus/pbts_test.go |
Tests PBTS timing behavior. |
consensus/mempool_test.go |
Passes proposal receive times. |
consensus/invalid_test.go |
Removes vote timestamps. |
consensus/common_test.go |
Updates shared proposal helpers. |
consensus/byzantine_test.go |
Adapts Byzantine scenarios. |
consensus/aggregation_reactor_test.go |
Tests BLS network commits. |
consensus/aggregation_replay_test.go |
Tests aggregated WAL recovery. |
consensus/aggregation_pbts_test.go |
Tests PBTS rejection with BLS. |
consensus/aggregation_catchup_test.go |
Tests whole-commit catch-up. |
consensus/types/round_state.go |
Supports commit-backed LastCommit. |
consensus/types/peer_round_state.go |
Tracks peer catch-up commits. |
consensus/types/height_vote_set.go |
Stores received aggregated commits. |
crypto/bls12381/aggregation.go |
Implements BLS aggregation. |
crypto/bls12381/aggregation_none.go |
Adds disabled-build stubs. |
crypto/bls12381/aggregation_test.go |
Tests aggregate verification. |
crypto/bls12381/key.go |
Updates disabled BLS API. |
crypto/bls12381/key_bls12381.go |
Adds compression and corrected aggregation types. |
crypto/bls12381/const.go |
Defines compressed key size. |
crypto/encoding/codec.go |
Supports pointer and compressed BLS keys. |
evidence/pool_test.go |
Updates encoded evidence size. |
internal/test/commit.go |
Uses feature parameters. |
internal/test/config.go |
Adds PBTS genesis parameters. |
internal/test/params.go |
Enables extensions through feature parameters. |
node/setup.go |
Shortens seed disconnect timing. |
privval/file.go |
Removes timestamp re-signing and adds raw signing. |
privval/file_test.go |
Updates timestamp signing tests. |
privval/msgs.go |
Wraps raw-signing messages. |
privval/retry_signer_client.go |
Retries raw signing. |
privval/signer_client.go |
Adds remote raw signing. |
privval/signer_client_test.go |
Tests remote raw signing. |
privval/signer_requestHandler.go |
Handles raw-signing requests. |
proto/buf.yaml |
Exempts intentional wire changes. |
proto/tendermint/abci/types.proto |
Adds delay and next proposer fields. |
proto/tendermint/consensus/message.go |
Wraps new consensus messages. |
proto/tendermint/consensus/types.proto |
Defines commit and block-part messages. |
proto/tendermint/privval/types.proto |
Defines raw-signing messages. |
proto/tendermint/state/types.proto |
Persists next-block delay. |
proto/tendermint/types/canonical.proto |
Removes signed vote timestamps. |
proto/tendermint/types/canonical.pb.go |
Regenerates canonical types. |
proto/tendermint/types/params.proto |
Adds feature and synchrony parameters. |
proto/tendermint/types/validator.proto |
Adds aggregation flags and key fields. |
rpc/client/evidence_test.go |
Uses committed PBTS block time. |
state/execution.go |
Applies ADR-115 and next proposer data. |
state/execution_test.go |
Updates execution expectations. |
state/state.go |
Persists delays and creates PBTS blocks. |
state/validation.go |
Validates PBTS block times. |
state/validation_test.go |
Updates block validation tests. |
store/store_test.go |
Adapts pruning tests for PBTS. |
test/e2e/runner/setup.go |
Writes feature-based genesis settings. |
types/block.go |
Adds aggregate flags and commit reader support. |
types/block_test.go |
Updates commit tests. |
types/canonical.go |
Excludes vote timestamps from sign bytes. |
types/events.go |
Adds block-part event. |
types/evidence.go |
Removes evidence vote timestamps. |
types/params.go |
Implements feature and synchrony parameters. |
types/params_test.go |
Tests new parameter representation. |
types/priv_validator.go |
Adds BLS mocks and raw signing. |
types/proposal.go |
Adds PBTS proposal timestamps and timeliness. |
types/proposal_test.go |
Updates proposal tests. |
types/test_util.go |
Removes vote timestamps from helpers. |
types/time/time.go |
Adds injectable clock source. |
types/time/mocks/source.go |
Provides generated clock mock. |
types/validation.go |
Verifies aggregated commits. |
types/validator.go |
Changes validator key serialization. |
types/validator_set_test.go |
Updates validator protobuf fixtures. |
types/vote.go |
Enforces zero vote timestamps. |
types/vote_test.go |
Updates signed-byte vectors. |
types/vote_set.go |
Creates aggregated BLS commits. |
types/vote_set_test.go |
Updates vote-set tests. |
Files not reviewed (2)
- abci/types/types.pb.go: Generated file
- consensus/metrics.gen.go: Generated file
Suppressed comments (2)
consensus/state.go:1440
- This second aggregation path also runs when vote extensions are enabled, bypassing
canAggregateCommits. That creates an aggregated extended commit which the restart and whole-commit catch-up paths cannot consume. Include!cs.isVoteExtensionsEnabled(lastCommitAsVs.GetHeight())incanBeAggregatedbefore callingMakeBLSCommit.
if canBeAggregated {
if !cs.isPBTSEnabled(cs.Height) {
panic("Wanted to aggregate LastCommit, but PBTS is not enabled for height " + strconv.FormatInt(cs.Height, 10))
}
lastExtCommit = lastCommitAsVs.MakeBLSCommit()
consensus/state.go:1535
- Aggregation is selected even when vote extensions are enabled, despite the new catch-up path explicitly not supporting that combination. The resulting extended commit cannot be reconstructed after restart because its individual consensus signatures were cleared, and
AddCommitrefuses it. Gate aggregation on vote extensions being disabled.
func (cs *State) canAggregateCommits() bool {
proposerKey := cs.Validators.GetProposer().PubKey
_, blsKey := proposerKey.(*bls12381.PubKey)
_, blsKey2 := proposerKey.(bls12381.PubKey)
return (blsKey || blsKey2) && cs.Validators.AllKeysHaveSameType()
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
fridrik01
force-pushed
the
refork-cometbft-bera-to-0.39
branch
3 times, most recently
from
August 13, 2026 18:04
607a0aa to
bc6bf7f
Compare
Re-forks the berachain CometBFT customizations from the bera-v1.x line onto a fresh v0.39.x base (tag v0.39.3), establishing the bera-v0.39.x line. Brings over: - Proposer-Based Timestamps (PBTS) + removal of per-vote timestamps - BLS12-381 signature aggregation (aggregated commits + fast catch-up) - NextBlockDelay (ADR-115) and NextProposerAddress in ProcessProposal - validator pub-key wire format, Synchrony/Feature params, and supporting proto Forward-compatible: existing bera-v1.x networks can restart on this binary (on-disk state and consensus sign/wire bytes are byte-identical). Upstream cometbft#5860 is intentionally excluded (arrives via the v0.39.4 rebase).
fridrik01
force-pushed
the
refork-cometbft-bera-to-0.39
branch
from
August 13, 2026 18:41
bc6bf7f to
f8b4e4f
Compare
fridrik01
marked this pull request as ready for review
August 13, 2026 18:54
…signatures (cherry picked from commit ab1bb7a)
fridrik01
force-pushed
the
refork-cometbft-bera-to-0.39
branch
from
August 14, 2026 10:38
29ae2bd to
49564d1
Compare
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.
Berachain's CometBFT fork (
bera-v1.x) is built on upstream v1.x line, which has been wound down in favor of v0.39. Security fixes and improvements such as the new libp2p networking layer now land only on v0.39, while our v1.x base is effectively unmaintained and ours to secure alone. Migrating onto v0.39 puts us back on a maintained line, and keeping PBTS and BLS aggregation preserves the block format so the move can be a rolling binary upgrade rather than a coordinated halt-and-swap.This PR re-forks the berachain CometBFT customizations from the
bera-v1.xline (CometBFT v1.x) onto a freshv0.39.xbase. That establishes the newbera-v0.39.xline. The line was created from tagv0.39.3and has since adoptedv0.39.4through the standard sync-merge flow (#61), so this PR lands on a base that is current with upstreamv0.39.4.It is designed to be forward-compatible, so an existing
bera-v1.xnetwork can restart directly on this binary with no state migration. That works because the on-disk state and the consensus sign and wire bytes are kept byte-identical tobera-v1.x, which we verified against abera-v1.xbuild (see Testing).PBTS and BLS signature aggregation are always enabled on this fork.
Whats in it
timeout_commitfrom config.ProcessProposalnow carries the address of the next block proposer.SignBytesrequest, and BLS public keys are handled in compressed form.The
#5860blocksync fix (sender binding plus a signature-count cap) is not part of this PRs diff because it did not need porting. It reached the fork through the upstreamv0.39.4sync (#61) that this branch now sits on.How to review
Most of the diff is a faithful port of code that already runs in
bera-v1.xproduction, so the review effort is best spent on the parts that had to change specifically forv0.39.There is one caveat on method. Provenance cannot be shown with a mechanical diff, because the
bera-v1.xline moved its packages underinternal/andapi/and renamed the proto packages fromcometbft.*totendermint.*. A file-to-file diff therefore does not line up, and the split below is curated by hand.The following can be skimmed, since they are faithful ports and need little review:
crypto/bls12381, the aggregation primitives. The only change is a build-tag split and an alias relocation..pb.gofiles. Review the.protofiles and the wire facts instead of the generated Go.verifyAggregatedCommitandMakeBLSCommit(intypes/validation.goandtypes/vote_set.go),IsTimely(intypes/proposal.go), and the bulk of the function bodies inconsensus/state.go.The following deserve close review, since they exist only because of the back-port and are where bugs would hide:
LastCommitis now an interface (VoteSetReader) that holds either a*VoteSetor a whole aggregated*Commit. This required guarded type assertions at roughly six call sites, plus acmtjsonregistration so that the/dump_consensus_stateendpoint still works. Seeconsensus/state.go,consensus/types/round_state.go,types/block.go, andtypes/vote_set.go.v0.39must still compile withoutblst. Anaggregation_none.gostub and acanAggregateCommitsfallback gate the aggregated path. Seecrypto/bls12381/aggregation_none.goandconsensus/state.go.timeout_commit. The commit timeout is now derived fromstate.NextBlockDelay, with a fallback toconfig.TimeoutCommit. Seeconsensus/state.go,state/state.go, andstate/execution.go.gogofastercodegen, a mapping fromwrapperstogogo, moving theauthorityfield from 6 to 8, and a hand-writtenWrapandUnwrapfor the newCommitmessage. Seebuf.gen.yamlandproto/tendermint/consensus/message.go.ToProtoandFromProtonow writepub_key_bytesandpub_key_type, with a fallback to the legacypub_key. Seetypes/validator.goandcrypto/encoding/codec.go.v0.39call sites.NewProposalnow takes the block time, which is threaded through about twenty callers. In addition,privval/file.godrops the obsolete path that re-signed a vote when only its timestamp differed, and aProposalTimestampDifferencemetric was added. Seetypes/proposal.go,privval/file.go, andconsensus/metrics.go.The three features are coupled through the
VoteSetReaderchange, which is why they ship as a single PR rather than three.Review follow-ups
Auditing the branch against
bera-v1.xduring review surfaced two fixes that postdate the re-fork snapshot. Both are now on this branch.SynchronyParamscometbft/cometbft#4816) and the bypass was removed on bera-v1.x in chore(state): avoid 10 round check for timeliness #50, The commit re-applies chore(state): avoid 10 round check for timeliness #50 and ports its regression test.MaxVotesCountsignatures (49564d1), a cherry-pick of fix(consensus): reject gossiped commits with more than MaxVotesCount … #54.Wire and upgrade compatibility
bera-v1.x, so an existing network can restart on this binary.bera-v1.x(f8b4e4f), with the fork's two extra messages pinned to their bera-v1.x field numbers (has_proposal_block_partat 10 and the wholecommitat 11), so old and new binaries gossip with each other during the rollout.v0.39.4, owing to the new parameters and the removal of vote timestamps. That is the intended bera shape.Base and upstream syncing
The
bera-v0.39.xline is branched from a tagged upstream release, the CometBFTv0.39.3tag, which gives it a fixed and well-known starting point on the upstreamv0.39.xline. It was created with:Future upstream releases are adopted by merging the release tag into
bera-v0.39.xthrough a normal PR:Sync PRs must be merged with a merge commit, never squashed. Squashing breaks the shared ancestry with upstream, so every later sync re-conflicts on changes we already took. Merging rather than rebasing also keeps the branch append-only, so open PRs, clones, and go module consumers survive a sync, and each conflict is resolved once inside a reviewed PR.
The bera-specific changes stay easy to inspect.
git diff v0.39.4 bera-v0.39.xshows everything we maintain on top of the latest upstream tag.Urgent upstream fixes can be cherry-picked between releases, and the next sync merge supersedes them. The first such sync has already happened.
bera-v0.39.xmergedv0.39.4in #61, which brought in the#5860blocksync fix without any cherry-pick.Testing
-tags bls12381.v0.39.4after Sync our bera-v0.39.x branch to receive the new upstream v0.39.4 tag #61. The one remaining flake reproduces on the pristine tag as well, so it is not a regression.bera-v1.xwas verified out of tree. A one-time harness captured the exact bytes and hashes abera-v1.xbuild produces and confirmed this port produces identical output, covering the vote and proposal sign bytes, the aggregated-commit hash and its proto encoding, the block header hash, the consensus params hash, the persisted state proto, and a full real aggregated commit. That harness is not part of this PR, so a committed vectors test could be added later to make it reproducible in CI.New tests added by this PR:
TestAggregateAndVerifyaggregates BLS signatures and verifies the aggregate, including rejecting an invalid signature and a missing public key.TestReactorAggregatedCommitsruns a full all-BLS validator network and confirms the aggregated commits it produces verify against the validator set.TestAggregationPBTSRejectsUntimelyProposalconfirms that under PBTS a proposal whose timestamp is outside the timely window is prevoted nil.TestAggregationWALReplayRestartrestarts a node through WAL replay and confirms it recovers a height that was committed with an aggregated commit.TestAggregationCatchUpViaAddCommitdrives the catch-up path where a lagging node adopts an aggregated commit throughAddCommitand advances, and checks thatAddCommitrejects forged, wrong-block, and non-aggregated commits.TestPBTSProposerWaitTime,TestPBTSProposalIsTimely, andTestPBTSSynchronyParamsInRoundunit-test the proposer wait, the timeliness check, and the per-round synchrony scaling.TestPBTSFarFutureProposalRejectedAtHighRoundis the regression test for the removed round>10 timeliness bypass, ported from bera-v1.x chore(state): avoid 10 round check for timeliness #50. It drives 13 rounds of consensus against far-future proposals and asserts they are prevoted nil at every round, including rounds above 10.TestPBTSSynchronyParamsInRoundadditionally asserts the synchrony back-off caps atMaxMessageDelayat overflow-prone rounds.TestCommitMessageValidateBasicchecks theMaxVotesCountcap on gossiped whole commits, at and above the cap.