Skip to main content

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