fuel_gql_client/client/schema/
block.rs

1use crate::client::{
2    schema::{
3        schema,
4        BlockId,
5        ConnectionArgs,
6        PageInfo,
7        Signature,
8        Tai64Timestamp,
9        U64,
10    },
11    PaginatedResult,
12};
13
14use super::{
15    tx::TransactionIdFragment,
16    Bytes32,
17};
18
19#[derive(cynic::QueryVariables, Debug)]
20pub struct BlockByIdArgs {
21    pub id: Option<BlockId>,
22}
23
24#[derive(cynic::QueryFragment, Debug)]
25#[cynic(
26    schema_path = "./assets/schema.sdl",
27    graphql_type = "Query",
28    variables = "BlockByIdArgs"
29)]
30pub struct BlockByIdQuery {
31    #[arguments(id: $id)]
32    pub block: Option<Block>,
33}
34
35#[derive(cynic::QueryVariables, Debug)]
36pub struct BlockByHeightArgs {
37    pub height: Option<U64>,
38}
39
40#[derive(cynic::QueryFragment, Debug)]
41#[cynic(
42    schema_path = "./assets/schema.sdl",
43    graphql_type = "Query",
44    variables = "BlockByHeightArgs"
45)]
46pub struct BlockByHeightQuery {
47    #[arguments(height: $height)]
48    pub block: Option<Block>,
49}
50
51#[derive(cynic::QueryFragment, Debug)]
52#[cynic(
53    schema_path = "./assets/schema.sdl",
54    graphql_type = "Query",
55    variables = "ConnectionArgs"
56)]
57pub struct BlocksQuery {
58    #[arguments(after: $after, before: $before, first: $first, last: $last)]
59    pub blocks: BlockConnection,
60}
61
62#[derive(cynic::QueryFragment, Debug)]
63#[cynic(schema_path = "./assets/schema.sdl")]
64pub struct BlockConnection {
65    pub edges: Vec<BlockEdge>,
66    pub page_info: PageInfo,
67}
68
69impl From<BlockConnection> for PaginatedResult<Block, String> {
70    fn from(conn: BlockConnection) -> Self {
71        PaginatedResult {
72            cursor: conn.page_info.end_cursor,
73            has_next_page: conn.page_info.has_next_page,
74            has_previous_page: conn.page_info.has_previous_page,
75            results: conn.edges.into_iter().map(|e| e.node).collect(),
76        }
77    }
78}
79
80#[derive(cynic::QueryFragment, Debug)]
81#[cynic(schema_path = "./assets/schema.sdl")]
82pub struct BlockEdge {
83    pub cursor: String,
84    pub node: Block,
85}
86
87#[derive(cynic::QueryFragment, Debug)]
88#[cynic(schema_path = "./assets/schema.sdl")]
89pub struct Block {
90    pub id: BlockId,
91    pub header: Header,
92    pub consensus: Consensus,
93    pub transactions: Vec<TransactionIdFragment>,
94}
95
96#[derive(cynic::QueryFragment, Debug)]
97#[cynic(schema_path = "./assets/schema.sdl", graphql_type = "Block")]
98pub struct BlockIdFragment {
99    pub id: BlockId,
100}
101
102#[derive(cynic::InputObject, Clone, Debug)]
103#[cynic(schema_path = "./assets/schema.sdl")]
104pub struct TimeParameters {
105    pub start_time: U64,
106    pub block_time_interval: U64,
107}
108
109#[derive(cynic::QueryVariables, Debug)]
110pub struct ProduceBlockArgs {
111    pub blocks_to_produce: U64,
112    pub time: Option<TimeParameters>,
113}
114
115#[derive(cynic::QueryFragment, Debug)]
116#[cynic(
117    schema_path = "./assets/schema.sdl",
118    variables = "ProduceBlockArgs",
119    graphql_type = "Mutation"
120)]
121pub struct BlockMutation {
122    #[arguments(blocksToProduce: $blocks_to_produce, time: $time)]
123    pub produce_blocks: U64,
124}
125
126#[derive(cynic::QueryFragment, Debug)]
127#[cynic(schema_path = "./assets/schema.sdl")]
128pub struct Header {
129    pub id: BlockId,
130    pub da_height: U64,
131    pub transactions_count: U64,
132    pub output_messages_count: U64,
133    pub transactions_root: Bytes32,
134    pub output_messages_root: Bytes32,
135    pub height: U64,
136    pub prev_root: Bytes32,
137    pub time: Tai64Timestamp,
138    pub application_hash: Bytes32,
139}
140
141#[derive(cynic::InlineFragments, Debug)]
142#[cynic(schema_path = "./assets/schema.sdl")]
143pub enum Consensus {
144    Genesis(Genesis),
145    PoAConsensus(PoAConsensus),
146    #[cynic(fallback)]
147    Unknown,
148}
149
150#[derive(cynic::QueryFragment, Debug)]
151#[cynic(schema_path = "./assets/schema.sdl")]
152pub struct Genesis {
153    pub chain_config_hash: Bytes32,
154    pub coins_root: Bytes32,
155    pub contracts_root: Bytes32,
156    pub messages_root: Bytes32,
157}
158
159#[derive(cynic::QueryFragment, Debug)]
160#[cynic(schema_path = "./assets/schema.sdl")]
161pub struct PoAConsensus {
162    pub signature: Signature,
163}
164
165impl Block {
166    /// Returns the block producer public key, if any.
167    pub fn block_producer(&self) -> Option<fuel_vm::fuel_crypto::PublicKey> {
168        let message = self.header.id.clone().into_message();
169        match &self.consensus {
170            Consensus::Genesis(_) => Some(Default::default()),
171            Consensus::PoAConsensus(poa) => {
172                let signature = poa.signature.clone().into_signature();
173                let producer_pub_key = signature.recover(&message);
174                producer_pub_key.ok()
175            }
176            Consensus::Unknown => None,
177        }
178    }
179}
180
181#[cfg(test)]
182mod tests {
183    use super::*;
184
185    #[test]
186    fn block_by_id_query_gql_output() {
187        use cynic::QueryBuilder;
188        let operation = BlockByIdQuery::build(BlockByIdArgs {
189            id: Some(BlockId::default()),
190        });
191        insta::assert_snapshot!(operation.query)
192    }
193
194    #[test]
195    fn block_by_height_query_gql_output() {
196        use cynic::QueryBuilder;
197        let operation = BlockByHeightQuery::build(BlockByHeightArgs {
198            height: Some(U64(0)),
199        });
200        insta::assert_snapshot!(operation.query)
201    }
202
203    #[test]
204    fn block_mutation_query_gql_output() {
205        use cynic::MutationBuilder;
206        let operation = BlockMutation::build(ProduceBlockArgs {
207            blocks_to_produce: U64(0),
208            time: None,
209        });
210        insta::assert_snapshot!(operation.query)
211    }
212
213    #[test]
214    fn blocks_connection_query_gql_output() {
215        use cynic::QueryBuilder;
216        let operation = BlocksQuery::build(ConnectionArgs {
217            after: None,
218            before: None,
219            first: None,
220            last: None,
221        });
222        insta::assert_snapshot!(operation.query)
223    }
224}