fuel_core_client/client/schema/
block.rs1use super::{
2 Bytes32,
3 HexString,
4};
5use crate::client::schema::{
6 BlockId,
7 ConnectionArgsFields,
8 PageInfo,
9 Signature,
10 Tai64Timestamp,
11 TransactionId,
12 U16,
13 U32,
14 U64,
15 schema,
16};
17use fuel_core_types::{
18 fuel_crypto,
19 fuel_types::BlockHeight,
20};
21
22#[derive(cynic::QueryVariables, Debug)]
23pub struct BlockByIdArgs {
24 pub id: Option<BlockId>,
25}
26
27#[derive(cynic::QueryFragment, Clone, Debug)]
28#[cynic(
29 schema_path = "./assets/schema.sdl",
30 graphql_type = "Query",
31 variables = "BlockByIdArgs"
32)]
33pub struct BlockByIdQuery {
34 #[arguments(id: $id)]
35 pub block: Option<Block>,
36}
37
38#[derive(cynic::QueryVariables, Debug)]
39pub struct BlockByHeightArgs {
40 pub height: Option<U32>,
41}
42
43#[derive(cynic::QueryFragment, Clone, Debug)]
44#[cynic(
45 schema_path = "./assets/schema.sdl",
46 graphql_type = "Query",
47 variables = "BlockByHeightArgs"
48)]
49pub struct BlockByHeightQuery {
50 #[arguments(height: $height)]
51 pub block: Option<Block>,
52}
53
54#[derive(cynic::QueryFragment, Clone, Debug)]
55#[cynic(
56 schema_path = "./assets/schema.sdl",
57 graphql_type = "Query",
58 variables = "ConnectionArgs"
59)]
60pub struct BlocksQuery {
61 #[arguments(after: $after, before: $before, first: $first, last: $last)]
62 pub blocks: BlockConnection,
63}
64
65#[derive(cynic::QueryFragment, Clone, Debug)]
66#[cynic(schema_path = "./assets/schema.sdl")]
67pub struct BlockConnection {
68 pub edges: Vec<BlockEdge>,
69 pub page_info: PageInfo,
70}
71
72#[derive(cynic::QueryFragment, Clone, Debug)]
73#[cynic(schema_path = "./assets/schema.sdl")]
74pub struct BlockEdge {
75 pub cursor: String,
76 pub node: Block,
77}
78
79#[derive(cynic::Enum, Clone, Debug)]
80#[cynic(schema_path = "./assets/schema.sdl")]
81pub enum BlockVersion {
82 V1,
83 #[cynic(fallback)]
84 Unknown,
85}
86
87#[derive(cynic::QueryFragment, Clone, Debug)]
89#[cynic(schema_path = "./assets/schema.sdl")]
90pub struct Block {
91 pub version: BlockVersion,
92 pub id: BlockId,
93 pub header: Header,
94 pub consensus: Consensus,
95 pub transaction_ids: Vec<TransactionId>,
96}
97
98#[derive(cynic::QueryFragment, Clone, Debug)]
99#[cynic(schema_path = "./assets/schema.sdl", graphql_type = "Block")]
100pub struct BlockIdFragment {
101 pub id: BlockId,
102}
103
104#[derive(cynic::QueryFragment, Clone, Debug)]
105#[cynic(schema_path = "./assets/schema.sdl", graphql_type = "Block")]
106pub struct BlockHeightFragment {
107 pub height: U32,
108}
109
110#[derive(cynic::QueryVariables, Debug)]
111pub struct ProduceBlockArgs {
112 pub start_timestamp: Option<Tai64Timestamp>,
113 pub blocks_to_produce: U32,
114}
115
116#[derive(cynic::QueryFragment, Clone, Debug)]
117#[cynic(
118 schema_path = "./assets/schema.sdl",
119 variables = "ProduceBlockArgs",
120 graphql_type = "Mutation"
121)]
122pub struct BlockMutation {
123 #[arguments(blocksToProduce: $blocks_to_produce, startTimestamp: $start_timestamp)]
124 pub produce_blocks: U32,
125}
126
127#[derive(cynic::Enum, Clone, Debug)]
128#[cynic(schema_path = "./assets/schema.sdl")]
129pub enum HeaderVersion {
130 V1,
131 V2,
132 #[cynic(fallback)]
133 Unknown,
134}
135
136#[derive(cynic::QueryFragment, Clone, Debug)]
137#[cynic(schema_path = "./assets/schema.sdl")]
138pub struct Header {
139 pub version: HeaderVersion,
140 pub id: BlockId,
141 pub da_height: U64,
142 pub consensus_parameters_version: U32,
143 pub state_transition_bytecode_version: U32,
144 pub transactions_count: U16,
145 pub message_receipt_count: U32,
146 pub transactions_root: Bytes32,
147 pub message_outbox_root: Bytes32,
148 pub event_inbox_root: Bytes32,
149 pub height: U32,
150 pub prev_root: Bytes32,
151 pub time: Tai64Timestamp,
152 pub application_hash: Bytes32,
153 #[cfg(feature = "fault-proving")]
154 pub tx_id_commitment: Option<Bytes32>,
155}
156
157#[derive(cynic::InlineFragments, Clone, Debug)]
158#[cynic(schema_path = "./assets/schema.sdl")]
159pub enum Consensus {
160 Genesis(Genesis),
161 PoAConsensus(PoAConsensus),
162 #[cynic(fallback)]
163 Unknown,
164}
165
166#[derive(cynic::QueryFragment, Clone, Debug)]
167#[cynic(schema_path = "./assets/schema.sdl")]
168pub struct Genesis {
169 pub chain_config_hash: Bytes32,
170 pub coins_root: Bytes32,
171 pub contracts_root: Bytes32,
172 pub messages_root: Bytes32,
173 pub transactions_root: Bytes32,
174}
175
176#[derive(cynic::QueryFragment, Clone, Debug)]
177#[cynic(schema_path = "./assets/schema.sdl")]
178pub struct PoAConsensus {
179 pub signature: Signature,
180}
181
182impl Block {
183 pub fn block_producer(&self) -> Option<fuel_crypto::PublicKey> {
185 let message = self.header.id.clone().into_message();
186 match &self.consensus {
187 Consensus::Genesis(_) => Some(Default::default()),
188 Consensus::PoAConsensus(poa) => {
189 let signature = poa.signature.clone().into_signature();
190 let producer_pub_key = signature.recover(&message);
191 producer_pub_key.ok()
192 }
193 Consensus::Unknown => None,
194 }
195 }
196}
197
198#[derive(cynic::QueryFragment, Clone, Debug)]
199#[cynic(schema_path = "./assets/schema.sdl", graphql_type = "Subscription")]
200pub struct NewBlocksSubscription {
201 #[cynic(rename = "alpha__new_blocks")]
202 pub new_blocks: HexString,
203}
204
205impl From<BlockHeightFragment> for BlockHeight {
206 fn from(fragment: BlockHeightFragment) -> Self {
207 BlockHeight::new(fragment.height.into())
208 }
209}
210
211#[cfg(test)]
212mod tests {
213 use super::*;
214
215 #[test]
216 fn block_by_id_query_gql_output() {
217 use cynic::QueryBuilder;
218 let operation = BlockByIdQuery::build(BlockByIdArgs {
219 id: Some(BlockId::default()),
220 });
221
222 let snapshot_name = if cfg!(feature = "fault-proving") {
223 "block_by_id_query_gql_output_with_tx_id_commitment"
224 } else {
225 "block_by_id_query_gql_output"
226 };
227
228 insta::assert_snapshot!(snapshot_name, operation.query)
229 }
230
231 #[test]
232 fn block_by_height_query_gql_output() {
233 use cynic::QueryBuilder;
234 let operation = BlockByHeightQuery::build(BlockByHeightArgs {
235 height: Some(U32(0)),
236 });
237
238 let snapshot_name = if cfg!(feature = "fault-proving") {
239 "block_by_height_query_gql_output_with_tx_id_commitment"
240 } else {
241 "block_by_height_query_gql_output"
242 };
243
244 insta::assert_snapshot!(snapshot_name, operation.query)
245 }
246
247 #[test]
248 fn block_mutation_query_gql_output() {
249 use cynic::MutationBuilder;
250 let operation = BlockMutation::build(ProduceBlockArgs {
251 blocks_to_produce: U32(0),
252 start_timestamp: None,
253 });
254 insta::assert_snapshot!(operation.query)
255 }
256
257 #[test]
258 fn blocks_connection_query_gql_output() {
259 use cynic::QueryBuilder;
260 let args = crate::client::schema::ConnectionArgs {
261 after: None,
262 before: None,
263 first: None,
264 last: None,
265 };
266 let operation = BlocksQuery::build(args);
267
268 let snapshot_name = if cfg!(feature = "fault-proving") {
269 "blocks_connection_query_gql_output_with_tx_id_commitment"
270 } else {
271 "blocks_connection_query_gql_output"
272 };
273
274 insta::assert_snapshot!(snapshot_name, operation.query)
275 }
276}