ab_farmer_rpc_primitives/
lib.rs

1//! Primitives for the farmer
2
3use ab_core_primitives::block::BlockRoot;
4use ab_core_primitives::block::header::OwnedBlockHeaderSeal;
5use ab_core_primitives::hashes::Blake3Hash;
6use ab_core_primitives::pot::SlotNumber;
7use ab_core_primitives::segments::HistorySize;
8use ab_core_primitives::shard::NumShards;
9use ab_core_primitives::solutions::{ShardMembershipEntropy, Solution, SolutionRange};
10use ab_farmer_components::FarmerProtocolInfo;
11use ab_networking::libp2p::Multiaddr;
12use parity_scale_codec::{Decode, Encode, EncodeLike, Input, Output};
13use serde::{Deserialize, Serialize};
14use std::time::Duration;
15
16/// Defines a limit for number of segments that can be requested over RPC
17pub const MAX_SEGMENT_HEADERS_PER_REQUEST: usize = 1000;
18// TODO: This is a workaround for https://github.com/paritytech/jsonrpsee/issues/1617 and should be
19//  removed once that issue is resolved
20/// Shard membership expiration
21pub const SHARD_MEMBERSHIP_EXPIRATION: Duration = Duration::from_mins(1);
22
23/// Information necessary for farmer application
24#[derive(Debug, Clone, Serialize, Deserialize)]
25#[serde(rename_all = "camelCase")]
26pub struct FarmerAppInfo {
27    /// Genesis root of the beacon chain
28    pub genesis_root: BlockRoot,
29    /// Bootstrap nodes for DSN
30    pub dsn_bootstrap_nodes: Vec<Multiaddr>,
31    /// Whether node is syncing right now
32    pub syncing: bool,
33    /// How much time farmer has to audit sectors and generate a solution
34    pub farming_timeout: Duration,
35    /// Protocol info for farmer
36    pub protocol_info: FarmerProtocolInfo,
37}
38
39impl Encode for FarmerAppInfo {
40    fn size_hint(&self) -> usize {
41        0_usize
42            .saturating_add(Encode::size_hint(&self.genesis_root))
43            .saturating_add(Encode::size_hint(
44                &self
45                    .dsn_bootstrap_nodes
46                    .iter()
47                    .map(|addr| addr.as_ref())
48                    .collect::<Vec<_>>(),
49            ))
50            .saturating_add(Encode::size_hint(&self.syncing))
51            .saturating_add(Encode::size_hint(&self.farming_timeout))
52            .saturating_add(Encode::size_hint(&self.protocol_info))
53    }
54
55    fn encode_to<O: Output + ?Sized>(&self, output: &mut O) {
56        Encode::encode_to(&self.genesis_root, output);
57        Encode::encode_to(
58            &self
59                .dsn_bootstrap_nodes
60                .iter()
61                .map(|addr| addr.as_ref())
62                .collect::<Vec<_>>(),
63            output,
64        );
65        Encode::encode_to(&self.syncing, output);
66        Encode::encode_to(&self.farming_timeout, output);
67        Encode::encode_to(&self.protocol_info, output);
68    }
69}
70
71impl EncodeLike for FarmerAppInfo {}
72
73impl Decode for FarmerAppInfo {
74    fn decode<I: Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
75        Ok(FarmerAppInfo {
76            genesis_root: BlockRoot::decode(input)
77                .map_err(|error| error.chain("Could not decode `FarmerAppInfo::genesis_root`"))?,
78            dsn_bootstrap_nodes: Vec::<Vec<u8>>::decode(input)
79                .map_err(|error| {
80                    error.chain("Could not decode `FarmerAppInfo::dsn_bootstrap_nodes`")
81                })?
82                .into_iter()
83                .map(Multiaddr::try_from)
84                .collect::<Result<Vec<_>, _>>()
85                .map_err(|error| {
86                    parity_scale_codec::Error::from("Failed to decode bytes as Multiaddr")
87                        .chain(error.to_string())
88                        .chain("Could not decode `FarmerAppInfo::dsn_bootstrap_nodes`")
89                })?,
90            syncing: bool::decode(input)
91                .map_err(|error| error.chain("Could not decode `FarmerAppInfo::syncing`"))?,
92            farming_timeout: Duration::decode(input).map_err(|error| {
93                error.chain("Could not decode `FarmerAppInfo::farming_timeout`")
94            })?,
95            protocol_info: FarmerProtocolInfo::decode(input)
96                .map_err(|error| error.chain("Could not decode `FarmerAppInfo::protocol_info`"))?,
97        })
98    }
99}
100
101/// Information about new slot that just arrived
102#[derive(Debug, Copy, Clone, Eq, PartialEq, Encode, Decode, Serialize, Deserialize)]
103#[serde(rename_all = "camelCase")]
104pub struct SlotInfo {
105    /// Slot number
106    pub slot: SlotNumber,
107    /// Global slot challenge
108    pub global_challenge: Blake3Hash,
109    /// Acceptable solution range for farmer audits
110    pub solution_range: SolutionRange,
111    /// Shard membership entropy
112    pub shard_membership_entropy: ShardMembershipEntropy,
113    /// The number of shards in the network
114    pub num_shards: NumShards,
115}
116
117/// Response of a slot challenge consisting of an optional solution and
118/// the submitter(farmer)'s secret key for block signing.
119#[derive(Clone, Debug, Encode, Decode, Serialize, Deserialize)]
120#[serde(rename_all = "camelCase")]
121pub struct SolutionResponse {
122    /// Slot number.
123    pub slot_number: SlotNumber,
124    /// Solution farmer has for the challenge.
125    ///
126    /// Corresponds to `slot_number` above.
127    pub solution: Solution,
128}
129
130/// Block sealing info
131#[derive(Clone, Copy, Debug, Encode, Decode, Serialize, Deserialize)]
132#[serde(rename_all = "camelCase")]
133pub struct BlockSealInfo {
134    /// Block pre-seal hash to be signed
135    pub pre_seal_hash: Blake3Hash,
136    /// Public key hash of the plot identity that should create signature
137    pub public_key_hash: Blake3Hash,
138}
139
140/// Block sealing response
141#[derive(Clone, Copy, Debug, Encode, Decode, Serialize, Deserialize)]
142#[serde(rename_all = "camelCase")]
143pub struct BlockSealResponse {
144    /// Block pre-seal hash that was signed
145    pub pre_seal_hash: Blake3Hash,
146    /// The seal itself
147    pub seal: OwnedBlockHeaderSeal,
148}
149
150/// Farmer shard membership info
151#[derive(Debug, Clone, Eq, PartialEq, Encode, Decode, Serialize, Deserialize)]
152#[serde(rename_all = "camelCase")]
153pub struct FarmerShardMembershipInfo {
154    /// Public key hash of the plot identity
155    pub public_key_hash: Blake3Hash,
156    /// Seed used to derive the shard commitment (typically a hash of the private key)
157    pub shard_commitments_seed: Blake3Hash,
158    /// History sizes
159    pub history_sizes: Vec<HistorySize>,
160}