sequencer/request_response/
request.rs

1use anyhow::{Context, Result};
2use async_trait::async_trait;
3use committable::Commitment;
4use espresso_types::{
5    v0_3::{ChainConfig, RewardAccountV1, RewardMerkleTreeV1},
6    v0_4::{RewardAccountV2, RewardMerkleTreeV2},
7    FeeAccount, FeeMerkleTree, Leaf2,
8};
9use hotshot_types::data::VidShare;
10use request_response::{request::Request as RequestTrait, Serializable};
11use serde::{Deserialize, Serialize};
12
13use crate::api::BlocksFrontier;
14
15// Some type aliases for readability
16type Height = u64;
17type ViewNumber = u64;
18type RequestId = u64;
19
20/// The outermost request type. This an enum that contains all the possible requests that the
21/// sequencer can make.
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub enum Request {
24    /// A request for the accounts at a given height and view
25    Accounts(Height, ViewNumber, Vec<FeeAccount>),
26    /// A request for the leaf chain at a given height
27    Leaf(Height),
28    /// A request for a chain config with a particular commitment
29    ChainConfig(Commitment<ChainConfig>),
30    /// A request for the blocks frontier
31    BlocksFrontier(Height, ViewNumber),
32    /// A request for the reward accounts at a given height and view
33    RewardAccountsV2(Height, ViewNumber, Vec<RewardAccountV2>),
34    /// A request for the v1 reward accounts at a given height and view
35    RewardAccountsV1(Height, ViewNumber, Vec<RewardAccountV1>),
36    /// A request for the VID share at the given block height
37    VidShare(Height, RequestId),
38}
39
40/// The outermost response type. This an enum that contains all the possible responses that the
41/// sequencer can make.
42#[derive(Debug, Clone, Serialize, Deserialize)]
43pub enum Response {
44    /// A response for the accounts at a given height and view
45    Accounts(FeeMerkleTree),
46    /// A request for the leaf chain at a given height
47    Leaf(Vec<Leaf2>),
48    /// A response for a chain config with a particular commitment
49    ChainConfig(ChainConfig),
50    /// A response for the blocks frontier
51    BlocksFrontier(BlocksFrontier),
52    /// A response for the reward accounts at a given height and view
53    RewardAccountsV2(RewardMerkleTreeV2),
54    /// A response for the v1 reward accounts at a given height and view
55    RewardAccountsV1(RewardMerkleTreeV1),
56    /// A response for a VID share at the given block height
57    VidShare(VidShare),
58}
59
60/// Implement the `RequestTrait` trait for the `Request` type. This tells the request response
61/// protocol how to validate the request and what the response type is.
62#[async_trait]
63impl RequestTrait for Request {
64    type Response = Response;
65
66    async fn validate(&self) -> Result<()> {
67        // Right now, all requests are valid
68        Ok(())
69    }
70}
71
72/// Implement the `Serializable` trait for the `Request` type. This tells the request response
73/// protocol how to serialize and deserialize the request
74impl Serializable for Request {
75    fn to_bytes(&self) -> Result<Vec<u8>> {
76        bincode::serialize(&self).with_context(|| "failed to serialize")
77    }
78
79    fn from_bytes(bytes: &[u8]) -> Result<Self> {
80        bincode::deserialize(bytes).with_context(|| "failed to deserialize")
81    }
82}
83
84/// Implement the `Serializable` trait for the `Response` type. This tells the request response
85/// protocol how to serialize and deserialize the response.
86impl Serializable for Response {
87    fn to_bytes(&self) -> Result<Vec<u8>> {
88        bincode::serialize(self).with_context(|| "failed to serialize")
89    }
90
91    fn from_bytes(bytes: &[u8]) -> Result<Self> {
92        bincode::deserialize(bytes).with_context(|| "failed to deserialize")
93    }
94}