Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add endpoint for hotshot config and env variables #1481

Merged
merged 16 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions sequencer/api/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[route.hotshot]
PATH = ["/hotshot"]
METHOD = "GET"
DOC = "Get the Hotshot configuration for the current node."

[route.env]
PATH = ["/env"]
METHOD = "GET"
DOC = "Get all ESPRESSO environment variables set for the current node."
14 changes: 13 additions & 1 deletion sequencer/src/api.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use self::data_source::StateSignatureDataSource;
use self::data_source::{HotShotConfigDataSource, MyHotShotConfig, StateSignatureDataSource};
use crate::{
network,
persistence::SequencerPersistence,
Expand Down Expand Up @@ -239,6 +239,18 @@ impl<N: network::Type, Ver: StaticVersionType + 'static, P: SequencerPersistence
}
}

impl<
N: network::Type,
jbearer marked this conversation as resolved.
Show resolved Hide resolved
D: HotShotConfigDataSource + Sync,
Ver: StaticVersionType + 'static,
P: SequencerPersistence,
> HotShotConfigDataSource for StorageState<N, P, D, Ver>
{
async fn get_config(&self) -> anyhow::Result<Option<MyHotShotConfig>> {
self.inner().get_config().await
}
}

#[async_trait]
impl<N: network::Type, D: Sync, Ver: StaticVersionType + 'static, P: SequencerPersistence>
StateSignatureDataSource<N> for StorageState<N, P, D, Ver>
Expand Down
77 changes: 75 additions & 2 deletions sequencer/src/api/data_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use super::{
use crate::{
network,
persistence::{self, SequencerPersistence},
SeqTypes, Transaction,
PubKey, SeqTypes, Transaction,
};
use anyhow::bail;
use async_trait::async_trait;
Expand All @@ -19,7 +19,11 @@ use hotshot_query_service::{
node::NodeDataSource,
status::StatusDataSource,
};
use hotshot_types::{data::ViewNumber, light_client::StateSignatureRequestBody};
use hotshot_types::{
data::ViewNumber, light_client::StateSignatureRequestBody, HotShotConfig, ValidatorConfig,
};
use serde::ser::SerializeStruct;
use serde::Serialize;
use tide_disco::Url;
use vbs::version::StaticVersionType;

Expand Down Expand Up @@ -84,6 +88,10 @@ pub(crate) trait SubmitDataSource<N: network::Type, P: SequencerPersistence> {
fn submit(&self, tx: Transaction) -> impl Send + Future<Output = anyhow::Result<()>>;
}

pub(crate) trait HotShotConfigDataSource {
fn get_config(&self) -> impl Send + Future<Output = anyhow::Result<Option<MyHotShotConfig>>>;
}

#[async_trait]
pub(crate) trait StateSignatureDataSource<N: network::Type> {
async fn get_state_signature(&self, height: u64) -> Option<StateSignatureRequestBody>;
Expand Down Expand Up @@ -134,6 +142,71 @@ pub(crate) trait CatchupDataSource {

impl CatchupDataSource for MetricsDataSource {}

pub struct MyHotShotConfig(HotShotConfig<PubKey>);

impl MyHotShotConfig {
pub fn new(c: HotShotConfig<PubKey>) -> Self {
Self(c)
}
}
pub struct MyValidatorConfig<'a>(&'a ValidatorConfig<PubKey>);

impl<'a> Serialize for MyValidatorConfig<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut state = serializer.serialize_struct("MyValidatorConfig", 3)?;

state.serialize_field("public_key", &self.0.public_key)?;
state.serialize_field("stake_value", &self.0.stake_value)?;
state.serialize_field("is_da", &self.0.is_da)?;

state.end()
}
}

impl Serialize for MyHotShotConfig {
jbearer marked this conversation as resolved.
Show resolved Hide resolved
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut state = serializer.serialize_struct("HotShotConfig", 20)?;
let config = &self.0;
state.serialize_field("execution_type", &config.execution_type)?;
state.serialize_field("start_threshold", &config.start_threshold)?;
state.serialize_field("num_nodes_with_stake", &config.num_nodes_with_stake)?;
state.serialize_field("num_nodes_without_stake", &config.num_nodes_without_stake)?;
state.serialize_field("known_nodes_with_stake", &config.known_nodes_with_stake)?;
state.serialize_field("known_da_nodes", &config.known_da_nodes)?;
state.serialize_field(
"known_nodes_without_stake",
&config.known_nodes_without_stake,
)?;

let validator_confg = MyValidatorConfig(&config.my_own_validator_config);

state.serialize_field("my_own_validator_config", &validator_confg)?;
state.serialize_field("da_staked_committee_size", &config.da_staked_committee_size)?;
state.serialize_field(
"da_non_staked_committee_size",
&config.da_non_staked_committee_size,
)?;
state.serialize_field("fixed_leader_for_gpuvid", &config.fixed_leader_for_gpuvid)?;
state.serialize_field("next_view_timeout", &config.next_view_timeout)?;
state.serialize_field("view_sync_timeout", &config.view_sync_timeout)?;
state.serialize_field("timeout_ratio", &config.timeout_ratio)?;
state.serialize_field("round_start_delay", &config.round_start_delay)?;
state.serialize_field("start_delay", &config.start_delay)?;
state.serialize_field("num_bootstrap", &config.num_bootstrap)?;
state.serialize_field("builder_timeout", &config.builder_timeout)?;
state.serialize_field("data_request_delay", &config.data_request_delay)?;
state.serialize_field("builder_url", &config.builder_url)?;

state.end()
}
}

#[cfg(test)]
pub(crate) mod testing {
use super::super::Options;
Expand Down
37 changes: 36 additions & 1 deletion sequencer/src/api/endpoints.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
//! Sequencer-specific API endpoint handlers.

use std::env;

use super::{
data_source::{
CatchupDataSource, SequencerDataSource, StateSignatureDataSource, SubmitDataSource,
CatchupDataSource, HotShotConfigDataSource, SequencerDataSource, StateSignatureDataSource,
SubmitDataSource,
},
StorageState,
};
Expand Down Expand Up @@ -286,3 +289,35 @@ where
)?;
Ok(api)
}

pub(super) fn config<S, Ver: StaticVersionType + 'static>(_: Ver) -> Result<Api<S, Error, Ver>>
where
S: 'static + Send + Sync + ReadState,
S::State: Send + Sync + HotShotConfigDataSource,
{
let toml = toml::from_str::<toml::Value>(include_str!("../../api/config.toml"))?;
let mut api = Api::<S, Error, Ver>::new(toml)?;

let env_vars: Vec<(String, String)> = env::vars()
.filter(|(key, _)| key.starts_with("ESPRESSO_"))
jbearer marked this conversation as resolved.
Show resolved Hide resolved
.collect();

api.get("hotshot", |_, state| {
async move {
state
.get_config()
.await
.map_err(|err| Error::catch_all(StatusCode::NotFound, format!("{err:#}")))
}
.boxed()
})?
.get("env", move |_, _| {
{
let env_vars = env_vars.clone();
async move { Ok(env_vars) }
}
.boxed()
})?;

Ok(api)
}
16 changes: 16 additions & 0 deletions sequencer/src/api/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub struct Options {
pub submit: Option<Submit>,
pub status: Option<Status>,
pub catchup: Option<Catchup>,
pub config: Option<Config>,
pub state: Option<State>,
pub hotshot_events: Option<HotshotEvents>,
pub explorer: Option<Explorer>,
Expand All @@ -58,6 +59,7 @@ impl From<Http> for Options {
submit: None,
status: None,
catchup: None,
config: None,
state: None,
hotshot_events: None,
explorer: None,
Expand Down Expand Up @@ -100,6 +102,12 @@ impl Options {
self
}

/// Add a config API module.
pub fn config(mut self, opt: Config) -> Self {
self.config = Some(opt);
self
}

/// Add a state API module.
pub fn state(mut self, opt: State) -> Self {
self.state = Some(opt);
Expand Down Expand Up @@ -371,6 +379,10 @@ impl Options {
self.init_and_spawn_hotshot_event_streaming_module(state, tasks, bind_version)?;
}

if self.config.is_some() {
app.register_module("config", endpoints::config(bind_version)?)?;
}

tasks.spawn(
"API server",
app.serve(format!("0.0.0.0:{}", self.http.port), Ver::instance()),
Expand Down Expand Up @@ -480,6 +492,10 @@ pub struct Status;
#[derive(Parser, Clone, Copy, Debug, Default)]
pub struct Catchup;

/// Options for the config API module.
#[derive(Parser, Clone, Copy, Debug, Default)]
pub struct Config;

/// Options for the query API module.
#[derive(Parser, Clone, Debug, Default)]
pub struct Query {
Expand Down
15 changes: 13 additions & 2 deletions sequencer/src/api/sql.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use super::{
data_source::{CatchupDataSource, Provider, SequencerDataSource},
data_source::{
CatchupDataSource, HotShotConfigDataSource, MyHotShotConfig, Provider, SequencerDataSource,
},
AccountQueryData, BlocksFrontier,
};
use crate::{
persistence::sql::Options,
persistence::{sql::Options, SequencerPersistence},
state::{BlockMerkleTree, FeeAccountProof, FeeMerkleTree},
SeqTypes,
};
Expand Down Expand Up @@ -96,6 +98,15 @@ impl CatchupDataSource for DataSource {
}
}

impl HotShotConfigDataSource for DataSource {
async fn get_config(&self) -> anyhow::Result<Option<MyHotShotConfig>> {
(*self.storage().await)
.load_config()
.await
.map(|res| res.map(|network_config| MyHotShotConfig::new(network_config.config)))
}
}

#[cfg(test)]
mod impl_testable_data_source {
use super::*;
Expand Down
5 changes: 4 additions & 1 deletion sequencer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,16 @@ where
if let Some(catchup) = modules.catchup {
http_opt = http_opt.catchup(catchup);
}

if let Some(hotshot_events) = modules.hotshot_events {
http_opt = http_opt.hotshot_events(hotshot_events);
}
if let Some(explorer) = modules.explorer {
http_opt = http_opt.explorer(explorer);
}

if let Some(config) = modules.config {
http_opt = http_opt.config(config);
}
http_opt
.serve(
move |metrics| {
Expand Down
4 changes: 4 additions & 0 deletions sequencer/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ impl ModuleArgs {
SequencerModule::Status(m) => curr = m.add(&mut modules.status, &mut provided)?,
SequencerModule::State(m) => curr = m.add(&mut modules.state, &mut provided)?,
SequencerModule::Catchup(m) => curr = m.add(&mut modules.catchup, &mut provided)?,
SequencerModule::Config(m) => curr = m.add(&mut modules.config, &mut provided)?,
SequencerModule::HotshotEvents(m) => {
curr = m.add(&mut modules.hotshot_events, &mut provided)?
}
Expand Down Expand Up @@ -321,6 +322,7 @@ module!("submit", api::options::Submit, requires: "http");
module!("status", api::options::Status, requires: "http");
module!("state", api::options::State, requires: "http", "storage-sql");
module!("catchup", api::options::Catchup, requires: "http");
module!("config", api::options::Config, requires: "http", "storage-sql");
module!("hotshot-events", api::options::HotshotEvents, requires: "http");
module!("explorer", api::options::Explorer, requires: "http", "storage-sql");

Expand Down Expand Up @@ -392,6 +394,7 @@ enum SequencerModule {
///
/// This module requires the http module to be started.
Catchup(Module<api::options::Catchup>),
Config(Module<api::options::Config>),
/// Run the merklized state API module.
///
/// This module requires the http and storage-sql modules to be started.
Expand All @@ -416,6 +419,7 @@ pub struct Modules {
pub status: Option<api::options::Status>,
pub state: Option<api::options::State>,
pub catchup: Option<api::options::Catchup>,
pub config: Option<api::options::Config>,
pub hotshot_events: Option<api::options::HotshotEvents>,
pub explorer: Option<api::options::Explorer>,
}
Loading