hashgraph_like_consensus/api.rs
1//! Public API trait for the consensus service.
2//!
3//! [`ConsensusServiceAPI`] defines the full set of operations available to callers:
4//! creating proposals, casting votes, processing network messages, and querying state.
5
6use alloy_signer::Signer;
7
8use crate::{
9 error::ConsensusError,
10 events::ConsensusEventBus,
11 protos::consensus::v1::{Proposal, Vote},
12 scope::ConsensusScope,
13 session::ConsensusConfig,
14 storage::ConsensusStorage,
15 types::CreateProposalRequest,
16};
17
18/// Defines the public contract for a consensus service.
19///
20/// Generic over the scope type (`Scope`), storage backend (`S`), and event bus (`E`).
21/// The default implementation is provided by
22/// [`ConsensusService`](crate::service::ConsensusService).
23pub trait ConsensusServiceAPI<Scope, S, E>
24where
25 Scope: ConsensusScope,
26 S: ConsensusStorage<Scope>,
27 E: ConsensusEventBus<Scope>,
28{
29 /// Create a new proposal using scope-level (or global default) configuration.
30 fn create_proposal(
31 &self,
32 scope: &Scope,
33 request: CreateProposalRequest,
34 ) -> impl Future<Output = Result<Proposal, ConsensusError>> + Send;
35
36 /// Create a new proposal with an explicit [`ConsensusConfig`] override.
37 ///
38 /// Pass `None` to fall back to scope defaults (same as [`create_proposal`](Self::create_proposal)).
39 fn create_proposal_with_config(
40 &self,
41 scope: &Scope,
42 request: CreateProposalRequest,
43 config: Option<ConsensusConfig>,
44 ) -> impl Future<Output = Result<Proposal, ConsensusError>> + Send;
45
46 /// Cast a vote on an active proposal.
47 ///
48 /// The vote is cryptographically signed with `signer` and linked into the
49 /// hashgraph chain. Returns the signed [`Vote`] for network propagation.
50 fn cast_vote<SN: Signer + Sync + Send>(
51 &self,
52 scope: &Scope,
53 proposal_id: u32,
54 choice: bool,
55 signer: SN,
56 ) -> impl Future<Output = Result<Vote, ConsensusError>> + Send;
57
58 /// Cast a vote and return the updated [`Proposal`] (with the new vote included).
59 ///
60 /// Convenience method useful for the proposal creator who wants to immediately
61 /// gossip the updated proposal to peers.
62 fn cast_vote_and_get_proposal<SN: Signer + Sync + Send>(
63 &self,
64 scope: &Scope,
65 proposal_id: u32,
66 choice: bool,
67 signer: SN,
68 ) -> impl Future<Output = Result<Proposal, ConsensusError>> + Send;
69
70 /// Process a proposal received from the network.
71 ///
72 /// Validates the proposal and all embedded votes, then stores it locally.
73 /// If enough votes are already present, consensus is reached immediately.
74 fn process_incoming_proposal(
75 &self,
76 scope: &Scope,
77 proposal: Proposal,
78 ) -> impl Future<Output = Result<(), ConsensusError>> + Send;
79
80 /// Process a single vote received from the network.
81 ///
82 /// Validates the vote (signature, timestamp, chain) and adds it to the
83 /// corresponding proposal session. May trigger consensus.
84 fn process_incoming_vote(
85 &self,
86 scope: &Scope,
87 vote: Vote,
88 ) -> impl Future<Output = Result<(), ConsensusError>> + Send;
89
90 /// Retrieve a proposal by ID, including all votes collected so far.
91 fn get_proposal(
92 &self,
93 scope: &Scope,
94 proposal_id: u32,
95 ) -> impl Future<Output = Result<Proposal, ConsensusError>> + Send;
96
97 /// Retrieve only the payload bytes of a proposal.
98 fn get_proposal_payload(
99 &self,
100 scope: &Scope,
101 proposal_id: u32,
102 ) -> impl Future<Output = Result<Vec<u8>, ConsensusError>> + Send;
103}