Skip to content

Commit

Permalink
add stake table endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
rob-maron committed Nov 19, 2024
1 parent ed4bec1 commit db297a4
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 19 deletions.
8 changes: 8 additions & 0 deletions sequencer/api/node.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[route.stake_table_current]
PATH = ["stake-table/current"]
DOC = "Get the stake table for the current epoch"

[route.stake_table]
PATH = ["stake-table/:epoch_number"]
":epoch_number" = "Integer"
DOC = "Get the stake table for the given epoch"
46 changes: 44 additions & 2 deletions sequencer/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use async_lock::RwLock;
use async_once_cell::Lazy;
use async_trait::async_trait;
use committable::{Commitment, Committable};
use data_source::{CatchupDataSource, SubmitDataSource};
use data_source::{CatchupDataSource, StakeTableDataSource, SubmitDataSource};
use derivative::Derivative;
use espresso_types::{
retain_accounts, v0::traits::SequencerPersistence, v0_3::ChainConfig, AccountQueryData,
Expand All @@ -26,9 +26,14 @@ use hotshot_types::{
event::Event,
light_client::StateSignatureRequestBody,
network::NetworkConfig,
traits::{network::ConnectedNetwork, node_implementation::Versions, ValidatedState as _},
traits::{
network::ConnectedNetwork,
node_implementation::{NodeType, Versions},
ValidatedState as _,
},
utils::{View, ViewInner},
};
use hotshot_types::{stake_table::StakeTableEntry, traits::election::Membership};
use jf_merkle_tree::MerkleTreeScheme;
use std::sync::Arc;

Expand Down Expand Up @@ -157,6 +162,43 @@ impl<N: ConnectedNetwork<PubKey>, D: Send + Sync, V: Versions, P: SequencerPersi
}
}

impl<N: ConnectedNetwork<PubKey>, D: Sync, V: Versions, P: SequencerPersistence>
StakeTableDataSource<SeqTypes> for StorageState<N, P, D, V>
{
/// Get the stake table for a given epoch or the current epoch if not provided
async fn get_stake_table(
&self,
epoch: Option<<SeqTypes as NodeType>::Epoch>,
) -> Vec<StakeTableEntry<<SeqTypes as NodeType>::SignatureKey>> {
self.as_ref().get_stake_table(epoch).await
}
}

impl<N: ConnectedNetwork<PubKey>, V: Versions, P: SequencerPersistence>
StakeTableDataSource<SeqTypes> for ApiState<N, P, V>
{
/// Get the stake table for a given epoch or the current epoch if not provided
async fn get_stake_table(
&self,
epoch: Option<<SeqTypes as NodeType>::Epoch>,
) -> Vec<StakeTableEntry<<SeqTypes as NodeType>::SignatureKey>> {
// Get the epoch from the argument or the current epoch if not provided
let epoch = if let Some(epoch) = epoch {
epoch
} else {
self.consensus().await.read().await.cur_epoch().await
};

self.consensus()
.await
.read()
.await
.memberships
.quorum_membership
.stake_table(epoch)
}
}

impl<N: ConnectedNetwork<PubKey>, V: Versions, P: SequencerPersistence> SubmitDataSource<N, P>
for ApiState<N, P, V>
{
Expand Down
16 changes: 13 additions & 3 deletions sequencer/src/api/data_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@ use hotshot_query_service::{
node::NodeDataSource,
status::StatusDataSource,
};
use hotshot_types::network::{
BuilderType, CombinedNetworkConfig, Libp2pConfig, RandomBuilderConfig,
};
use hotshot_types::{
data::ViewNumber,
light_client::StateSignatureRequestBody,
network::NetworkConfig,
stake_table::StakeTableEntry,
traits::{network::ConnectedNetwork, node_implementation::Versions},
HotShotConfig, PeerConfig, ValidatorConfig,
};
use hotshot_types::{
network::{BuilderType, CombinedNetworkConfig, Libp2pConfig, RandomBuilderConfig},
traits::node_implementation::NodeType,
};
use serde::{Deserialize, Serialize};
use tide_disco::Url;
use vec1::Vec1;
Expand Down Expand Up @@ -114,6 +116,14 @@ pub(crate) trait NodeStateDataSource {
fn node_state(&self) -> impl Send + Future<Output = &NodeState>;
}

pub(crate) trait StakeTableDataSource<T: NodeType> {
/// Get the stake table for a given epoch or the current epoch if not provided
fn get_stake_table(
&self,
epoch: Option<<T as NodeType>::Epoch>,
) -> impl Send + Future<Output = Vec<StakeTableEntry<T::SignatureKey>>>;
}

pub(crate) trait CatchupDataSource: Sync {
/// Get the state of the requested `account`.
///
Expand Down
57 changes: 43 additions & 14 deletions sequencer/src/api/endpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use anyhow::Result;
use committable::Committable;
use espresso_types::{FeeAccount, FeeMerkleTree, NamespaceId, NsProof, PubKey, Transaction};
use futures::{try_join, FutureExt};
use hotshot_query_service::merklized_state::Snapshot;
use hotshot_query_service::{
availability::{self, AvailabilityDataSource, CustomSnafu, FetchBlockSnafu},
explorer::{self, ExplorerDataSource},
Expand All @@ -18,8 +17,9 @@ use hotshot_query_service::{
},
node, ApiState, Error,
};
use hotshot_query_service::{merklized_state::Snapshot, node::NodeDataSource};
use hotshot_types::{
data::ViewNumber,
data::{EpochNumber, ViewNumber},
traits::{
network::ConnectedNetwork,
node_implementation::{ConsensusTime, Versions},
Expand All @@ -30,12 +30,12 @@ use serde::{de::Error as _, Deserialize, Serialize};
use snafu::OptionExt;
use tagged_base64::TaggedBase64;
use tide_disco::{method::ReadState, Api, Error as _, StatusCode};
use vbs::version::StaticVersionType;
use vbs::version::{StaticVersion, StaticVersionType};

use super::{
data_source::{
CatchupDataSource, HotShotConfigDataSource, NodeStateDataSource, SequencerDataSource,
StateSignatureDataSource, SubmitDataSource,
StakeTableDataSource, StateSignatureDataSource, SubmitDataSource,
},
StorageState,
};
Expand Down Expand Up @@ -174,18 +174,47 @@ where
Ok(api)
}

type NodeApi<N, P, D, V, ApiVer> = Api<AvailState<N, P, D, V>, node::Error, ApiVer>;

pub(super) fn node<N, P, D, V: Versions>() -> Result<NodeApi<N, P, D, V, SequencerApiVersion>>
pub(super) fn node<S>() -> Result<Api<S, node::Error, StaticVersion<0, 1>>>
where
N: ConnectedNetwork<PubKey>,
D: SequencerDataSource + Send + Sync + 'static,
P: SequencerPersistence,
S: 'static + Send + Sync + ReadState,
<S as ReadState>::State:
Send + Sync + StakeTableDataSource<SeqTypes> + NodeDataSource<SeqTypes>,
{
let api = node::define_api::<AvailState<N, P, D, V>, SeqTypes, _>(
&Default::default(),
SequencerApiVersion::instance(),
)?;
// Extend the base API
let mut options = node::Options::default();
let extension = toml::from_str(include_str!("../../api/node.toml"))?;
options.extensions.push(extension);

// Create the base API with our extensions
let mut api = node::define_api::<S, SeqTypes, _>(&options, SequencerApiVersion::instance())?;

// Tack on the application logic
api.at("stake_table", |req, state| {
async move {
// Try to get the epoch from the request. If this fails, error
// as it was probably a mistake
let epoch = EpochNumber::new(req.integer_param("epoch_number").map_err(|_| {
hotshot_query_service::node::Error::Custom {
message: "Epoch number is required".to_string(),
status: StatusCode::BAD_REQUEST,
}
})?);

Ok(state
.read(|state| state.get_stake_table(Some(epoch)).boxed())
.await)
}
.boxed()
})?
.at("stake_table_current", |_, state| {
async move {
Ok(state
.read(|state| state.get_stake_table(None).boxed())
.await)
}
.boxed()
})?;

Ok(api)
}
pub(super) fn submit<N, P, S, ApiVer: StaticVersionType + 'static>() -> Result<Api<S, Error, ApiVer>>
Expand Down

0 comments on commit db297a4

Please sign in to comment.