Skip to content

feat(qbft_manager): wire EnvelopeProposer per-proposer QBFT instances #1122

Description

@shane-moore

Goal

Replace the transient EnvelopeProposer reject from #1120 with real per-proposer plumbing: EnvelopeProposerInstanceId, a fifth instance map, receive_data routing with a Gloas defense-in-depth gate, a fifth cleaner retain, and a QbftDecidable impl for EnvelopeConsensusData.

Context / motivation

Modeled on the ProposerConsensusData path (DutyExecutor::Validator), not the committee path. QbftManager currently holds four instance maps (qbft_manager/src/lib.rs:139-147 @ a9f378a4); the envelope value cannot reuse ProposerInstanceId because it has a different data type and no ValidatorDutyKind.

Suggested approach

  • Import EnvelopeConsensusData alongside the existing ssv_types::consensus values in qbft_manager/src/lib.rs.
  • EnvelopeProposerInstanceId { validator: PublicKeyBytes, instance_height: InstanceHeight } after ProposerInstanceId (qbft_manager/src/lib.rs:79); no duty field (one envelope duty per slot), no new ValidatorDutyKind variant.
  • Fifth map + DashMap::new() init (qbft_manager/src/lib.rs:139-147, qbft_manager/src/lib.rs:174-177).
  • In receive_data's DutyExecutor::Validator arm (qbft_manager/src/lib.rs:277-305): dedicated branch building the id and calling pass_to_instance::<EnvelopeConsensusData>, gated if !self.spec.fork_name_at_slot::<E>(slot).gloas_enabled() { return Err(QbftError::RoleNotActive); } (mirror the GloasBeaconVote gate at qbft_manager/src/lib.rs:321; spec field at qbft_manager/src/lib.rs:155). Remove the TODO(gloas) marker.
  • Fifth .retain(...) in the cleaner (qbft_manager/src/lib.rs:399-405).
  • impl<E: EthSpec> QbftDecidable<E> for EnvelopeConsensusData after the existing impls (qbft_manager/src/lib.rs:472-545): type Id = EnvelopeProposerInstanceId; message_id via MessageId::new(domain, Role::EnvelopeProposer, &DutyExecutor::Validator(id.validator)), mirroring the proposer impl.
  • Keep decide_instance generic. The Gloas check here gates inbound network messages; the local sign path added later must only initialize this instance after Gloas.

Acceptance criteria

  • Five instance maps; Validator-executor EnvelopeProposer routes to the new map; pre-Gloas rejects with RoleNotActive; Committee-executor still rejects with InconsistentMessageId.
  • Post-Gloas routing inserts into envelope_consensus_data_instances and does not touch proposer_consensus_data_instances.
  • Cleaner retains the new map under the same TTL as siblings.
  • QbftDecidable produces a per-proposer message_id with Role::EnvelopeProposer and DutyExecutor::Validator(validator_pubkey).
  • No ValidatorDutyKind::EnvelopeProposer is added.

Tests

Routing tests: pre-Gloas reject, post-Gloas map insertion, Committee-executor reject, and QbftDecidable::message_id shape. Reuse the gloas_dispatch_tests map-size pattern where possible, and replace the transient-reject test from #1120. cargo test -p qbft_manager.

Notes

Issues are directionally correct, not prescriptive; verify symbols at PR time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    epbsePBS / EIP-7732 / Gloas implementation

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions