You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Replace #1032's //todo(epbs) stub at the Some(Role::PTCCommittee) arm in qbft_manager/src/lib.rs::receive_data with real PTC plumbing: a new PTCCommitteeInstanceId, a fourth instance Map on QbftManager, routing in receive_data, a cleaner entry, and the QbftDecidable impl for PayloadAttestationVote. Fork-gate mirroring the AggregatorCommittee/Boole+ pattern.
Context
Per SIP-94 §3 (ssvlabs/SIPs#94), PTC runs one QBFT instance per cluster per slot over PayloadAttestationVote (introduced in #1034). The qbft_manager currently routes Role::PTCCommittee messages to the placeholder stub introduced in #1032, which rejects with RoleNotActive + a warn-log + a //todo(epbs) marker. This issue replaces the stub with the real instance map plumbing: PTC joins Committee, AggregatorCommittee, and Proposer as the fourth committee-scoped instance kind.
PayloadAttestationVote (the QBFT decision type for PTC) needs a QbftDecidable impl so the manager can map Role::PTCCommittee + CommitteeId to a deterministic message id, in the same style as the existing BeaconVote and AggregatorCommitteeConsensusData impls.
Add a fourth Map<PTCCommitteeInstanceId, PayloadAttestationVote> field on QbftManager; initialize it in the constructor.
In receive_data, replace the Some(Role::PTCCommittee) stub arm (currently warn! + Err(QbftError::RoleNotActive) + //todo(epbs) line comment) with real routing next to Role::AggregatorCommittee. Fork-gate with if active_fork < Fork::CStar { return Err(QbftError::RoleNotActive); }. The //todo(epbs) line comment and the placeholder warn-log must be gone after this PR.
Add .retain(...) for the new map in cleaner, matching the TTL/eviction policy of the existing committee-scoped maps.
Add a QbftDecidable impl for PayloadAttestationVote. message_id() uses Role::PTCCommittee and DutyExecutor::Committee; structure should parallel the existing BeaconVote and AggregatorCommitteeConsensusData impls.
Acceptance criteria
QbftManager has four instance maps: Committee, AggregatorCommittee, Proposer, PTCCommittee.
receive_data routes Role::PTCCommittee messages to the new map.
Post-CStar slot: PTC messages route into the new instance map.
cleaner retains the new map under the same TTL/eviction policy as the sibling committee maps.
QbftDecidable for PayloadAttestationVote produces a deterministic message_id matching the structural pattern of the existing BeaconVote / AggregatorCommitteeConsensusData impls.
New routing tests cover pre-CStar rejection and post-CStar acceptance, paralleling tests/aggregator_tests.rs::test_aggregator_committee_rejected_before_boole.
All pre-existing tests still pass.
Open questions
message_id byte composition. Existing QbftDecidable impls for BeaconVote / AggregatorCommitteeConsensusData (around qbft_manager/src/lib.rs:470-506) encode a specific layout. PTC must follow the same pattern; verify the exact byte composition at PR time against the in-tree impls rather than copy-pasting from any prior plan.
Risks
Cleaner eviction policy mismatch. PTC instances must be evicted under the same TTL as the other committee-scoped instances to bound memory; mirror AggregatorCommittee retention exactly. A divergence here leaks instance state across slots.
Goal
Replace #1032's
//todo(epbs)stub at theSome(Role::PTCCommittee)arm inqbft_manager/src/lib.rs::receive_datawith real PTC plumbing: a newPTCCommitteeInstanceId, a fourth instanceMaponQbftManager, routing inreceive_data, acleanerentry, and theQbftDecidableimpl forPayloadAttestationVote. Fork-gate mirroring the AggregatorCommittee/Boole+ pattern.Context
Per SIP-94 §3 (ssvlabs/SIPs#94), PTC runs one QBFT instance per cluster per slot over
PayloadAttestationVote(introduced in #1034). Theqbft_managercurrently routesRole::PTCCommitteemessages to the placeholder stub introduced in #1032, which rejects withRoleNotActive+ a warn-log + a//todo(epbs)marker. This issue replaces the stub with the real instance map plumbing: PTC joinsCommittee,AggregatorCommittee, andProposeras the fourth committee-scoped instance kind.PayloadAttestationVote(the QBFT decision type for PTC) needs aQbftDecidableimpl so the manager can mapRole::PTCCommittee+CommitteeIdto a deterministic message id, in the same style as the existingBeaconVoteandAggregatorCommitteeConsensusDataimpls.Suggested approach
anchor/qbft_manager/src/lib.rs:PTCCommitteeInstanceId { committee: CommitteeId, instance_height: InstanceHeight }, mirroring the existingAggregatorCommitteeInstanceId.Map<PTCCommitteeInstanceId, PayloadAttestationVote>field onQbftManager; initialize it in the constructor.receive_data, replace theSome(Role::PTCCommittee)stub arm (currentlywarn!+Err(QbftError::RoleNotActive)+//todo(epbs)line comment) with real routing next toRole::AggregatorCommittee. Fork-gate withif active_fork < Fork::CStar { return Err(QbftError::RoleNotActive); }. The//todo(epbs)line comment and the placeholder warn-log must be gone after this PR..retain(...)for the new map incleaner, matching the TTL/eviction policy of the existing committee-scoped maps.QbftDecidableimpl forPayloadAttestationVote.message_id()usesRole::PTCCommitteeandDutyExecutor::Committee; structure should parallel the existingBeaconVoteandAggregatorCommitteeConsensusDataimpls.Acceptance criteria
QbftManagerhas four instance maps: Committee, AggregatorCommittee, Proposer, PTCCommittee.receive_dataroutesRole::PTCCommitteemessages to the new map.receive_datareturnsErr(QbftError::RoleNotActive).cleanerretains the new map under the same TTL/eviction policy as the sibling committee maps.QbftDecidable for PayloadAttestationVoteproduces a deterministicmessage_idmatching the structural pattern of the existingBeaconVote/AggregatorCommitteeConsensusDataimpls.//todo(epbs)marker and placeholder warn-log from feat: add Role::PTCCommittee with message-validator fork-gate #1032 are gone.grep -r "//todo(epbs)" anchor/qbft_manager/returns no hits.tests/aggregator_tests.rs::test_aggregator_committee_rejected_before_boole.Open questions
message_idbyte composition. ExistingQbftDecidableimpls forBeaconVote/AggregatorCommitteeConsensusData(aroundqbft_manager/src/lib.rs:470-506) encode a specific layout. PTC must follow the same pattern; verify the exact byte composition at PR time against the in-tree impls rather than copy-pasting from any prior plan.Risks
AggregatorCommitteeretention exactly. A divergence here leaks instance state across slots.//todo(epbs)line comment (visible/grep-able) and the placeholderwarn!(...)(runtime). Easy to remove one and miss the other.