feat: re-fork cometbft-bera onto the v0.39.x line - #51
Draft
fridrik01 wants to merge 4 commits into
Draft
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.
| for i, pubk := range pubks { | ||
| blsPubKeys[i] = pubk.pk | ||
| } | ||
| return agSig.FastAggregateVerify(true, blsPubKeys, msg, dstMinPk) |
Comment on lines
+91
to
+93
| case *privvalproto.Message_SignBytesRequest: | ||
| var signature []byte | ||
| signature, err = privVal.SignBytes(r.SignBytesRequest.Value) |
Comment on lines
+319
to
+324
| if params.Feature.PbtsEnableHeight < 0 { | ||
| return fmt.Errorf("Feature.PbtsEnableHeight cannot be negative. Got: %d", params.Feature.PbtsEnableHeight) | ||
| } | ||
|
|
||
| // Synchrony params are only relevant when PBTS is enabled | ||
| if params.Feature.PbtsEnableHeight > 0 { |
Comment on lines
+1510
to
+1514
| if cs.Proposal.Round > 10 { | ||
| return true | ||
| } | ||
|
|
||
| sp := cs.state.ConsensusParams.Synchrony.InRound(cs.Proposal.Round) |
Comment on lines
+699
to
+702
| // With BLS aggregation the individual precommit votes cannot be | ||
| // reconstructed from an aggregated seen commit, so the whole *Commit | ||
| // stands in for the vote set. | ||
| return commit, nil |
Comment on lines
+1432
to
+1435
| _, blsKey := cs.privValidatorPubKey.(*bls12381.PubKey) | ||
| _, blsKey2 := cs.privValidatorPubKey.(bls12381.PubKey) | ||
| canBeAggregated := (blsKey || blsKey2) && | ||
| cs.state.Validators.AllKeysHaveSameType() |
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 16:27
71516da to
5ad4d72
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's 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, built on tagv0.39.3. That establishes the newbera-v0.39.xline.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.
What's in it
timeout_commitfrom config.ProcessProposalnow carries the address of the next block's proposer.One thing is deliberately left out. The
#5860blocksync fix (sender binding plus a signature-count cap) is excluded from this PR. It already lives on upstream cometbftv0.39.xand lands in this fork on thev0.39.4rebase, described in Base and upstream syncing below.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.Wire and upgrade compatibility
bera-v1.x, so an existing network can restart on this binary.cometbft.*versustendermint.*) and cannot gossip consensus messages to each other.v0.39.3, 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.
v0.39.4already contains the#5860blocksync fix, so no cherry-pick is needed.Testing
-tags bls12381.v0.39.3. 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.