1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
use futures::FutureExt;
use hotshot_types::traits::node_implementation::NodeType;
use snafu::ResultExt;
use tide_disco::{api::ApiError, method::ReadState, Api};

use super::{data_source::BuilderDataSource, Version};
use crate::api::load_api;
/// No changes to these types
pub use crate::v0_1::builder::{
    submit_api, BlockAvailableSnafu, BlockClaimSnafu, BuildError, BuilderAddressSnafu, Error,
    Options,
};

pub fn define_api<State, Types: NodeType>(
    options: &Options,
) -> Result<Api<State, Error, Version>, ApiError>
where
    State: 'static + Send + Sync + ReadState,
    <State as ReadState>::State: Send + Sync + BuilderDataSource<Types>,
{
    let mut api = load_api::<State, Error, Version>(
        options.api_path.as_ref(),
        include_str!("../../api/v0_3/builder.toml"),
        options.extensions.clone(),
    )?;
    api.with_version("0.0.3".parse().unwrap())
        .get("bundle", |req, state| {
            async move {
                let parent_view = req.integer_param("parent_view")?;
                let parent_hash = req.blob_param("parent_hash")?;
                let view_number = req.integer_param("view_number")?;
                state
                    .bundle(parent_view, &parent_hash, view_number)
                    .await
                    .with_context(|_| BlockClaimSnafu {
                        resource: format!(
                            "Block for parent {parent_hash}@{parent_view} and view {view_number}"
                        ),
                    })
            }
            .boxed()
        })?
        .get("builder_address", |_req, state| {
            async move { state.builder_address().await.context(BuilderAddressSnafu) }.boxed()
        })?;
    Ok(api)
}