Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Request pool may not be pruned after a reconfig when the application installs the new config asynchronously

Closed
#728 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

A pull request for this has already been merged.

  • #729 by @HagarMeir — merged

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
58/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
go

Research direction

Read pkg/consensus/consensus.go around Consensus.reconfig, internal/bft/controller.go around Controller.Start and MaybePruneRevokedRequests, then trace startComponents to see how the new controller is started. Add a test app hook that switches the verification sequence after the reconfig prune, and check that the next decision removes a request invalid under the new sequence.

Written by the indexing model from the issue text.

Description

Follow-up to #698 / #699.

Summary

#699 prunes the request pool once inside Consensus.reconfig, before the components restart. That relies on the application's Verifier already reflecting the new config when the prune runs. If the application installs the new config asynchronously, the prune can run against the old config. The new controller then cannot catch up later, because Controller.Start records the verification sequence it reads at start, which may already be the new one.

Details

Consensus.reconfig prunes, then starts the components:
https://github.com/hyperledger/SmartBFT/blob/da420f46d186b3cef2562b0171e39055f930ddba/pkg/consensus/consensus.go#L232-L250

Controller.Start stores the sequence the Verifier reports at that moment:
https://github.com/hyperledger/SmartBFT/blob/da420f46d186b3cef2562b0171e39055f930ddba/internal/bft/controller.go#L820

MaybePruneRevokedRequests prunes only if that stored value differs from the current one:
https://github.com/hyperledger/SmartBFT/blob/da420f46d186b3cef2562b0171e39055f930ddba/internal/bft/controller.go#L757-L770

Suppose the application switches its Verifier from sequence s to s+1 on its own goroutine, after Deliver or Synchronizer.Sync has returned the reconfig. Depending on when the switch lands:

Switch lands Prune in reconfig uses Start stores Result
before the prune s+1 s+1 correct
after Controller.Start s s the next MaybePruneRevokedRequests sees s → s+1 and prunes; correct
during the prune, or between the prune and Controller.Start s (all or part of the pool) s+1 never pruned again

In the third case, requests that are invalid under s+1 stay in the pool. They go away only when proposed and rejected, which costs a view change if this node leads, or after RequestAutoRemoveTimeout. A view change restarts those timers.

This happens in Fabric-X Orderer on the sync path: the synchronizer's commit callback starts the config switch on a separate goroutine and returns before it completes.

Proposed fix

Make the stored sequence equal the one the prune ran against, so a switch that lands later is always detected:

  1. In Consensus.reconfig, read seq := c.Verifier.VerificationSequence() before c.Pool.Prune(...).
  2. Have the new controller start with that value instead of reading the Verifier again in Start. For example, pass it through startComponents to Controller.Start.

If the switch lands during or after the prune, the controller then holds s, and the next MaybePruneRevokedRequests (on decide, sync or view change) prunes against s+1. If it landed before, seq is already s+1 and nothing changes. The initial Start (not after a reconfig) can keep its current behaviour.

Test

In the test app, apply the new verification sequence after Deliver / Sync returns the reconfig, and after reconfig's prune, for example with a hook in the test Verifier. Check that a request that is invalid under the new sequence is removed from the pool by the next decision.

🤖 Generated with Claude Code

Dominant language
Go
Stars
110
Forks
41
Avg merge
1d 4h
Merged PRs (30d)
31

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from hyperledger/SmartBFT

All issues in hyperledger/SmartBFT

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.