Skip to main content

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}