Skip to main content

fedimint_hbbft/sender_queue/
queueing_honey_badger.rs

1//! Convenience methods for a `SenderQueue` wrapping a `QueueingHoneyBadger`.
2
3use std::result;
4
5use crate::crypto::PublicKey;
6use rand::distributions::{Distribution, Standard};
7use rand::Rng;
8use serde::{de::DeserializeOwned, Serialize};
9
10use super::{Error, SenderQueue, SenderQueueableConsensusProtocol};
11use crate::queueing_honey_badger::{Change, Error as QhbError, QueueingHoneyBadger};
12use crate::transaction_queue::TransactionQueue;
13use crate::{Contribution, CpStep, Epoched, NodeIdT};
14
15impl<T, N, Q> Epoched for QueueingHoneyBadger<T, N, Q>
16where
17    T: Contribution + Serialize + DeserializeOwned + Clone,
18    N: NodeIdT + Serialize + DeserializeOwned,
19    Q: TransactionQueue<T>,
20    Standard: Distribution<N>,
21{
22    type Epoch = (u64, u64);
23
24    fn epoch(&self) -> (u64, u64) {
25        self.dyn_hb().epoch()
26    }
27}
28
29impl<T, N, Q> SenderQueueableConsensusProtocol for QueueingHoneyBadger<T, N, Q>
30where
31    T: Contribution + Serialize + DeserializeOwned + Clone,
32    N: NodeIdT + Serialize + DeserializeOwned,
33    Q: TransactionQueue<T>,
34    Standard: Distribution<N>,
35{
36    fn max_future_epochs(&self) -> u64 {
37        self.dyn_hb().max_future_epochs()
38    }
39}
40
41type Result<T, N, Q> =
42    result::Result<CpStep<SenderQueue<QueueingHoneyBadger<T, N, Q>>>, Error<QhbError>>;
43
44impl<T, N, Q> SenderQueue<QueueingHoneyBadger<T, N, Q>>
45where
46    T: Contribution + Serialize + DeserializeOwned + Clone,
47    N: NodeIdT + Serialize + DeserializeOwned,
48    Q: TransactionQueue<T>,
49    Standard: Distribution<N>,
50{
51    /// Adds a transaction to the queue.
52    ///
53    /// This can be called at any time to append to the transaction queue. The new transaction will
54    /// be proposed in some future epoch.
55    ///
56    /// If no proposal has yet been made for the current epoch, this may trigger one. In this case,
57    /// a nonempty step will returned, with the corresponding messages. (Or, if we are the only
58    /// validator, even with the completed batch as an output.)
59    pub fn push_transaction<R: Rng>(&mut self, tx: T, rng: &mut R) -> Result<T, N, Q> {
60        self.apply(|algo| algo.push_transaction(tx, rng))
61    }
62
63    /// Casts a vote to change the set of validators or parameters.
64    ///
65    /// This stores a pending vote for the change. It will be included in some future batch, and
66    /// once enough validators have been voted for the same change, it will take effect.
67    pub fn vote_for<R: Rng>(&mut self, change: Change<N>, rng: &mut R) -> Result<T, N, Q> {
68        self.apply(|algo| algo.vote_for(change, rng))
69    }
70
71    /// Casts a vote to add a node as a validator.
72    ///
73    /// This stores a pending vote for the change. It will be included in some future batch, and
74    /// once enough validators have been voted for the same change, it will take effect.
75    pub fn vote_to_add<R: Rng>(
76        &mut self,
77        node_id: N,
78        pub_key: PublicKey,
79        rng: &mut R,
80    ) -> Result<T, N, Q> {
81        self.apply(|algo| algo.vote_to_add(node_id, pub_key, rng))
82    }
83
84    /// Casts a vote to demote a validator to observer.
85    ///
86    /// This stores a pending vote for the change. It will be included in some future batch, and
87    /// once enough validators have been voted for the same change, it will take effect.
88    pub fn vote_to_remove<R: Rng>(&mut self, node_id: &N, rng: &mut R) -> Result<T, N, Q> {
89        self.apply(|algo| algo.vote_to_remove(node_id, rng))
90    }
91}