sequencer/request_response/
recipient_source.rs1use std::sync::Arc;
2
3use anyhow::{Context, Result};
4use async_trait::async_trait;
5use espresso_types::{PubKey, SeqTypes};
6use hotshot::{traits::NodeImplementation, SystemContext};
7use hotshot_types::{
8 data::EpochNumber,
9 epoch_membership::EpochMembershipCoordinator,
10 traits::node_implementation::{ConsensusTime, Versions},
11};
12use request_response::recipient_source::RecipientSource as RecipientSourceTrait;
13use tracing::warn;
14
15use super::request::Request;
16
17type Consensus<I, V> = Arc<SystemContext<SeqTypes, I, V>>;
19
20#[derive(Clone)]
21pub struct RecipientSource<I: NodeImplementation<SeqTypes>, V: Versions> {
22 pub consensus: Consensus<I, V>,
24 pub memberships: EpochMembershipCoordinator<SeqTypes>,
26 pub public_key: PubKey,
28}
29
30#[async_trait]
33impl<I: NodeImplementation<SeqTypes>, V: Versions> RecipientSourceTrait<Request, PubKey>
34 for RecipientSource<I, V>
35{
36 async fn get_expected_responders(&self, _request: &Request) -> Result<Vec<PubKey>> {
37 let epoch_number = self
39 .consensus
40 .consensus()
41 .read()
42 .await
43 .cur_epoch()
44 .unwrap_or(EpochNumber::genesis());
45
46 let membership = match self
48 .memberships
49 .stake_table_for_epoch(Some(epoch_number))
50 .await
51 {
52 Ok(membership) => membership,
53 Err(e) => {
54 warn!(
55 "Failed to get membership for epoch {}: {e:#}. Failing over to genesis",
56 epoch_number
57 );
58 self.memberships
59 .stake_table_for_epoch(Some(EpochNumber::genesis()))
60 .await
61 .with_context(|| "failed to get stake table for epoch")?
62 },
63 };
64
65 Ok(membership
67 .stake_table()
68 .await
69 .iter()
70 .map(|entry| entry.stake_table_entry.stake_key)
71 .filter(|key| *key != self.public_key)
72 .collect())
73 }
74}