diff --git a/node/rest/src/lib.rs b/node/rest/src/lib.rs index c7d01c9480..7529ea06d8 100644 --- a/node/rest/src/lib.rs +++ b/node/rest/src/lib.rs @@ -191,6 +191,7 @@ impl, R: Routing> Rest { .route(&format!("/{network}/stateRoot/latest"), get(Self::get_state_root_latest)) .route(&format!("/{network}/stateRoot/:height"), get(Self::get_state_root)) .route(&format!("/{network}/committee/latest"), get(Self::get_committee_latest)) + .route(&format!("/{network}/delegators/:validator"), get(Self::get_delegators_for_validator)) // Pass in `Rest` to make things convenient. .with_state(self.clone()) diff --git a/node/rest/src/routes.rs b/node/rest/src/routes.rs index c6abb8fe8a..2d0f4003ce 100644 --- a/node/rest/src/routes.rs +++ b/node/rest/src/routes.rs @@ -16,7 +16,7 @@ use super::*; use snarkos_node_router::{messages::UnconfirmedSolution, SYNC_LENIENCY}; use snarkvm::{ ledger::puzzle::Solution, - prelude::{block::Transaction, Identifier, LimitedWriter, Plaintext, ToBytes}, + prelude::{block::Transaction, Address, Identifier, LimitedWriter, Plaintext, ToBytes}, }; use indexmap::IndexMap; @@ -264,6 +264,24 @@ impl, R: Routing> Rest { Ok(ErasedJson::pretty(rest.ledger.latest_committee()?)) } + // GET //delegators/{validator} + pub(crate) async fn get_delegators_for_validator( + State(rest): State, + Path(validator): Path>, + ) -> Result { + // Do not process the request if the node is too far behind to avoid sending outdated data. + if rest.routing.num_blocks_behind() > SYNC_LENIENCY { + return Err(RestError("Unable to request delegators (node is syncing)".to_string())); + } + + // Return the delegators for the given validator. + match tokio::task::spawn_blocking(move || rest.ledger.get_delegators_for_validator(&validator)).await { + Ok(Ok(delegators)) => Ok(ErasedJson::pretty(delegators)), + Ok(Err(err)) => Err(RestError(format!("Unable to request delegators - {err}"))), + Err(err) => Err(RestError(format!("Unable to request delegators - {err}"))), + } + } + // GET //peers/count pub(crate) async fn get_peers_count(State(rest): State) -> ErasedJson { ErasedJson::pretty(rest.routing.router().number_of_connected_peers())