Skip to content

Bft synch prune#678

Open
tock-ibm wants to merge 2 commits intohyperledger:mainfrom
tock-ibm:bft-synch-prune
Open

Bft synch prune#678
tock-ibm wants to merge 2 commits intohyperledger:mainfrom
tock-ibm:bft-synch-prune

Conversation

@tock-ibm
Copy link
Contributor

@tock-ibm tock-ibm commented Mar 12, 2026

#35

Builds on top of #675

Adds a prune requests method to be given to the synchronizer

It is not yet functional. It will be built step by step in the next few commits.

Signed-off-by: Yoav Tock <tock@il.ibm.com>
Copy link

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 starts wiring in the new BFT synchronizer path alongside the existing “simple” synchronizer, including adding a callback to prune committed requests from the SmartBFT mempool.

Changes:

  • Adds BFT synchronizer factory/state fields to Consensus and a new PruneRequestsFromMemPool hook for synchronizer-driven pruning.
  • Creates (but does not yet replace usage with) a BFT synchronizer instance during consensus construction.
  • Adds TODO notes around temporary append-listener usage and planned synchronizer migration.

Reviewed changes

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

File Description
node/ledger/consensus_ledger.go Adds a TODO note indicating the append listener registration is temporary until BFT synchronizer migration.
node/consensus/consensus.go Extends Consensus with BFT synchronizer plumbing and adds PruneRequestsFromMemPool for synchronizer-driven mempool pruning.
node/consensus/consensus_builder.go Wires a BFT synchronizer factory and attempts to create a BFT synchronizer during CreateConsensus, while still using the existing synchronizer.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +932 to +947
// TODO it make sense to have ConsenterBlockToDecision return the error
decision := ConsenterBlockToDecision(consenterBlock)
if decision == nil {
c.Logger.Panicf("Failed parsing block we pulled with BFT Synchronizer")
}

hdr := &state.Header{}
if err := hdr.Deserialize(decision.Proposal.Header); err != nil {
c.Logger.Panicf("Failed deserializing header: %v", err)
}

// Every request, including config requests, is included in the proposal's payload as a batch of requests,
// so we can just deserialize the payload to get all the included requests and remove them from the mempool.
var batch arma_types.BatchedRequests
if err := batch.Deserialize(decision.Proposal.Payload); err != nil {
c.Logger.Panicf("Failed deserializing proposal payload: %v", err)
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

PruneRequestsFromMemPool introduces new behavior (parses a committed block/decision and removes included requests from the SmartBFT mempool), but there doesn’t appear to be unit test coverage for it. Since this package already has consensus tests, please add tests that verify requests in the committed batch are removed from the pool (and cover an invalid/empty block case).

Suggested change
// TODO it make sense to have ConsenterBlockToDecision return the error
decision := ConsenterBlockToDecision(consenterBlock)
if decision == nil {
c.Logger.Panicf("Failed parsing block we pulled with BFT Synchronizer")
}
hdr := &state.Header{}
if err := hdr.Deserialize(decision.Proposal.Header); err != nil {
c.Logger.Panicf("Failed deserializing header: %v", err)
}
// Every request, including config requests, is included in the proposal's payload as a batch of requests,
// so we can just deserialize the payload to get all the included requests and remove them from the mempool.
var batch arma_types.BatchedRequests
if err := batch.Deserialize(decision.Proposal.Payload); err != nil {
c.Logger.Panicf("Failed deserializing proposal payload: %v", err)
// Guard against nil or empty blocks. In such cases there is nothing to prune.
if consenterBlock == nil || consenterBlock.Data == nil || len(consenterBlock.Data.Data) == 0 {
c.Logger.Debugf("PruneRequestsFromMemPool called with nil or empty block; skipping mempool pruning")
return
}
// TODO it make sense to have ConsenterBlockToDecision return the error
decision := ConsenterBlockToDecision(consenterBlock)
if decision == nil {
c.Logger.Errorf("Failed parsing block pulled with BFT Synchronizer; skipping mempool pruning")
return
}
hdr := &state.Header{}
if err := hdr.Deserialize(decision.Proposal.Header); err != nil {
c.Logger.Errorf("Failed deserializing header while pruning mempool: %v", err)
return
}
// Every request, including config requests, is included in the proposal's payload as a batch of requests,
// so we can just deserialize the payload to get all the included requests and remove them from the mempool.
var batch arma_types.BatchedRequests
if err := batch.Deserialize(decision.Proposal.Payload); err != nil {
c.Logger.Errorf("Failed deserializing proposal payload while pruning mempool: %v", err)
return

Copilot uses AI. Check for mistakes.
Signed-off-by: Yoav Tock <tock@il.ibm.com>
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