1use crate::{
2 fuel_core_graphql_api::{
3 api_service::ChainInfoProvider,
4 query_costs,
5 },
6 graphql_api::Config,
7 schema::{
8 ReadViewProvider,
9 block::Block,
10 scalars::{
11 Address,
12 AssetId,
13 U16,
14 U32,
15 U64,
16 },
17 },
18};
19use async_graphql::{
20 Context,
21 Enum,
22 Object,
23 Union,
24};
25use fuel_core_types::{
26 fuel_tx,
27 fuel_tx::GasCostsValues,
28};
29use std::{
30 ops::Deref,
31 sync::Arc,
32};
33
34pub struct ChainInfo;
35pub struct ConsensusParameters(pub Arc<fuel_tx::ConsensusParameters>);
36pub struct TxParameters(fuel_tx::TxParameters);
37pub struct PredicateParameters(fuel_tx::PredicateParameters);
38pub struct ScriptParameters(fuel_tx::ScriptParameters);
39pub struct ContractParameters(fuel_tx::ContractParameters);
40pub struct FeeParameters(fuel_tx::FeeParameters);
41
42pub struct GasCosts(fuel_tx::GasCosts);
43
44#[derive(Clone, Copy, Debug, Enum, Eq, PartialEq)]
45pub enum GasCostsVersion {
46 V1,
47}
48
49#[derive(Clone, Copy, Debug, Enum, Eq, PartialEq)]
50pub enum FeeParametersVersion {
51 V1,
52}
53
54#[derive(Clone, Copy, Debug, Enum, Eq, PartialEq)]
55pub enum ContractParametersVersion {
56 V1,
57}
58
59#[derive(Clone, Copy, Debug, Enum, Eq, PartialEq)]
60pub enum ScriptParametersVersion {
61 V1,
62}
63
64#[derive(Clone, Copy, Debug, Enum, Eq, PartialEq)]
65pub enum PredicateParametersVersion {
66 V1,
67}
68
69#[derive(Clone, Copy, Debug, Enum, Eq, PartialEq)]
70pub enum TxParametersVersion {
71 V1,
72}
73
74#[derive(Clone, Copy, Debug, Enum, Eq, PartialEq)]
75pub enum ConsensusParametersVersion {
76 V1,
77}
78
79#[derive(Union)]
80pub enum DependentCost {
81 LightOperation(LightOperation),
82 HeavyOperation(HeavyOperation),
83}
84
85pub struct LightOperation {
86 base: u64,
87 units_per_gas: u64,
88}
89
90pub struct HeavyOperation {
91 base: u64,
92 gas_per_unit: u64,
93}
94
95impl From<fuel_tx::DependentCost> for DependentCost {
96 fn from(value: fuel_tx::DependentCost) -> Self {
97 match value {
98 fuel_tx::DependentCost::LightOperation {
99 base,
100 units_per_gas,
101 } => DependentCost::LightOperation(LightOperation {
102 base,
103 units_per_gas,
104 }),
105 fuel_tx::DependentCost::HeavyOperation { base, gas_per_unit } => {
106 DependentCost::HeavyOperation(HeavyOperation { base, gas_per_unit })
107 }
108 }
109 }
110}
111
112#[Object]
113impl ConsensusParameters {
114 async fn version(&self) -> ConsensusParametersVersion {
115 match self.0.as_ref() {
116 fuel_tx::ConsensusParameters::V1(_) | fuel_tx::ConsensusParameters::V2(_) => {
117 ConsensusParametersVersion::V1
118 }
119 }
120 }
121
122 async fn tx_params(&self) -> TxParameters {
123 TxParameters(self.0.tx_params().to_owned())
124 }
125
126 async fn predicate_params(&self) -> PredicateParameters {
127 PredicateParameters(self.0.predicate_params().to_owned())
128 }
129
130 async fn script_params(&self) -> ScriptParameters {
131 ScriptParameters(self.0.script_params().to_owned())
132 }
133
134 async fn contract_params(&self) -> ContractParameters {
135 ContractParameters(self.0.contract_params().to_owned())
136 }
137
138 async fn fee_params(&self) -> FeeParameters {
139 FeeParameters(self.0.fee_params().to_owned())
140 }
141
142 async fn base_asset_id(&self) -> AssetId {
143 AssetId(*self.0.base_asset_id())
144 }
145
146 async fn block_gas_limit(&self) -> U64 {
147 self.0.block_gas_limit().into()
148 }
149
150 async fn block_transaction_size_limit(&self) -> U64 {
151 self.0.block_transaction_size_limit().into()
152 }
153
154 async fn chain_id(&self) -> U64 {
155 (*self.0.chain_id()).into()
156 }
157
158 async fn gas_costs(&self) -> async_graphql::Result<GasCosts> {
159 Ok(GasCosts(self.0.gas_costs().clone()))
160 }
161
162 async fn privileged_address(&self) -> async_graphql::Result<Address> {
163 Ok(Address(*self.0.privileged_address()))
164 }
165}
166
167#[Object]
168impl TxParameters {
169 async fn version(&self) -> TxParametersVersion {
170 match self.0 {
171 fuel_tx::TxParameters::V1(_) => TxParametersVersion::V1,
172 }
173 }
174
175 async fn max_inputs(&self) -> U16 {
176 self.0.max_inputs().into()
177 }
178
179 async fn max_outputs(&self) -> U16 {
180 self.0.max_outputs().into()
181 }
182
183 async fn max_witnesses(&self) -> U32 {
184 self.0.max_witnesses().into()
185 }
186
187 async fn max_gas_per_tx(&self) -> U64 {
188 self.0.max_gas_per_tx().into()
189 }
190
191 async fn max_size(&self) -> U64 {
192 self.0.max_size().into()
193 }
194
195 async fn max_bytecode_subsections(&self) -> U16 {
196 self.0.max_bytecode_subsections().into()
197 }
198}
199
200#[Object]
201impl PredicateParameters {
202 async fn version(&self) -> PredicateParametersVersion {
203 match self.0 {
204 fuel_tx::PredicateParameters::V1(_) => PredicateParametersVersion::V1,
205 }
206 }
207
208 async fn max_predicate_length(&self) -> U64 {
209 self.0.max_predicate_length().into()
210 }
211
212 async fn max_predicate_data_length(&self) -> U64 {
213 self.0.max_predicate_data_length().into()
214 }
215
216 async fn max_gas_per_predicate(&self) -> U64 {
217 self.0.max_gas_per_predicate().into()
218 }
219
220 async fn max_message_data_length(&self) -> U64 {
221 self.0.max_message_data_length().into()
222 }
223}
224
225#[Object]
226impl ScriptParameters {
227 async fn version(&self) -> ScriptParametersVersion {
228 match self.0 {
229 fuel_tx::ScriptParameters::V1(_) => ScriptParametersVersion::V1,
230 }
231 }
232
233 async fn max_script_length(&self) -> U64 {
234 self.0.max_script_length().into()
235 }
236
237 async fn max_script_data_length(&self) -> U64 {
238 self.0.max_script_data_length().into()
239 }
240}
241
242#[Object]
243impl ContractParameters {
244 async fn version(&self) -> ContractParametersVersion {
245 match self.0 {
246 fuel_tx::ContractParameters::V1(_) => ContractParametersVersion::V1,
247 }
248 }
249
250 async fn contract_max_size(&self) -> U64 {
251 self.0.contract_max_size().into()
252 }
253
254 async fn max_storage_slots(&self) -> U64 {
255 self.0.max_storage_slots().into()
256 }
257}
258
259#[Object]
260impl FeeParameters {
261 async fn version(&self) -> FeeParametersVersion {
262 match self.0 {
263 fuel_tx::FeeParameters::V1(_) => FeeParametersVersion::V1,
264 }
265 }
266
267 async fn gas_price_factor(&self) -> U64 {
268 self.0.gas_price_factor().into()
269 }
270
271 async fn gas_per_byte(&self) -> U64 {
272 self.0.gas_per_byte().into()
273 }
274}
275
276#[Object]
277impl GasCosts {
278 async fn version(&self) -> GasCostsVersion {
279 match self.0.deref() {
280 GasCostsValues::V1(_)
281 | GasCostsValues::V2(_)
282 | GasCostsValues::V3(_)
283 | GasCostsValues::V4(_)
284 | GasCostsValues::V5(_)
285 | GasCostsValues::V6(_) => GasCostsVersion::V1,
286 }
287 }
288
289 async fn add(&self) -> U64 {
290 self.0.add().into()
291 }
292
293 async fn addi(&self) -> U64 {
294 self.0.addi().into()
295 }
296
297 async fn aloc(&self) -> U64 {
298 self.0.aloc().base().into()
299 }
300
301 async fn and(&self) -> U64 {
302 self.0.and().into()
303 }
304
305 async fn andi(&self) -> U64 {
306 self.0.andi().into()
307 }
308
309 async fn bal(&self) -> U64 {
310 self.0.bal().into()
311 }
312
313 async fn bhei(&self) -> U64 {
314 self.0.bhei().into()
315 }
316
317 async fn bhsh(&self) -> U64 {
318 self.0.bhsh().into()
319 }
320
321 async fn burn(&self) -> U64 {
322 self.0.burn().into()
323 }
324
325 async fn cb(&self) -> U64 {
326 self.0.cb().into()
327 }
328
329 async fn cfei(&self) -> U64 {
330 self.0.cfei().base().into()
331 }
332
333 async fn cfsi(&self) -> U64 {
334 self.0.cfsi().into()
335 }
336
337 async fn div(&self) -> U64 {
338 self.0.div().into()
339 }
340
341 async fn divi(&self) -> U64 {
342 self.0.divi().into()
343 }
344
345 async fn ecr1(&self) -> U64 {
346 self.0.ecr1().into()
347 }
348
349 async fn eck1(&self) -> U64 {
350 self.0.eck1().into()
351 }
352
353 async fn ed19(&self) -> U64 {
354 self.0.ed19().base().into()
355 }
356
357 async fn eq(&self) -> U64 {
358 self.0.eq_().into()
359 }
360
361 async fn exp(&self) -> U64 {
362 self.0.exp().into()
363 }
364
365 async fn expi(&self) -> U64 {
366 self.0.expi().into()
367 }
368
369 async fn flag(&self) -> U64 {
370 self.0.flag().into()
371 }
372
373 async fn gm(&self) -> U64 {
374 self.0.gm().into()
375 }
376
377 async fn gt(&self) -> U64 {
378 self.0.gt().into()
379 }
380
381 async fn gtf(&self) -> U64 {
382 self.0.gtf().into()
383 }
384
385 async fn ji(&self) -> U64 {
386 self.0.ji().into()
387 }
388
389 async fn jmp(&self) -> U64 {
390 self.0.jmp().into()
391 }
392
393 async fn jne(&self) -> U64 {
394 self.0.jne().into()
395 }
396
397 async fn jnei(&self) -> U64 {
398 self.0.jnei().into()
399 }
400
401 async fn jnzi(&self) -> U64 {
402 self.0.jnzi().into()
403 }
404
405 async fn jmpf(&self) -> U64 {
406 self.0.jmpf().into()
407 }
408
409 async fn jmpb(&self) -> U64 {
410 self.0.jmpb().into()
411 }
412
413 async fn jnzf(&self) -> U64 {
414 self.0.jnzf().into()
415 }
416
417 async fn jnzb(&self) -> U64 {
418 self.0.jnzb().into()
419 }
420
421 async fn jnef(&self) -> U64 {
422 self.0.jnef().into()
423 }
424
425 async fn jneb(&self) -> U64 {
426 self.0.jneb().into()
427 }
428
429 async fn lb(&self) -> U64 {
430 self.0.lb().into()
431 }
432
433 async fn log(&self) -> U64 {
434 self.0.log().into()
435 }
436
437 async fn lt(&self) -> U64 {
438 self.0.lt().into()
439 }
440
441 async fn lw(&self) -> U64 {
442 self.0.lw().into()
443 }
444
445 async fn mint(&self) -> U64 {
446 self.0.mint().into()
447 }
448
449 async fn mlog(&self) -> U64 {
450 self.0.mlog().into()
451 }
452
453 async fn mod_op(&self) -> U64 {
454 self.0.mod_op().into()
455 }
456
457 async fn modi(&self) -> U64 {
458 self.0.modi().into()
459 }
460
461 async fn move_op(&self) -> U64 {
462 self.0.move_op().into()
463 }
464
465 async fn movi(&self) -> U64 {
466 self.0.movi().into()
467 }
468
469 async fn mroo(&self) -> U64 {
470 self.0.mroo().into()
471 }
472
473 async fn mul(&self) -> U64 {
474 self.0.mul().into()
475 }
476
477 async fn muli(&self) -> U64 {
478 self.0.muli().into()
479 }
480
481 async fn mldv(&self) -> U64 {
482 self.0.mldv().into()
483 }
484
485 async fn niop(&self) -> Option<U64> {
486 self.0.niop().ok().map(Into::into)
487 }
488
489 async fn noop(&self) -> U64 {
490 self.0.noop().into()
491 }
492
493 async fn not(&self) -> U64 {
494 self.0.not().into()
495 }
496
497 async fn or(&self) -> U64 {
498 self.0.or().into()
499 }
500
501 async fn ori(&self) -> U64 {
502 self.0.ori().into()
503 }
504
505 async fn poph(&self) -> U64 {
506 self.0.poph().into()
507 }
508
509 async fn popl(&self) -> U64 {
510 self.0.popl().into()
511 }
512
513 async fn pshh(&self) -> U64 {
514 self.0.pshh().into()
515 }
516
517 async fn pshl(&self) -> U64 {
518 self.0.pshl().into()
519 }
520
521 async fn ret(&self) -> U64 {
522 self.0.ret().into()
523 }
524
525 async fn rvrt(&self) -> U64 {
526 self.0.rvrt().into()
527 }
528
529 async fn sb(&self) -> U64 {
530 self.0.sb().into()
531 }
532
533 async fn sll(&self) -> U64 {
534 self.0.sll().into()
535 }
536
537 async fn slli(&self) -> U64 {
538 self.0.slli().into()
539 }
540
541 async fn srl(&self) -> U64 {
542 self.0.srl().into()
543 }
544
545 async fn srli(&self) -> U64 {
546 self.0.srli().into()
547 }
548
549 async fn srw(&self) -> U64 {
550 self.0.srw().into()
551 }
552
553 async fn sub(&self) -> U64 {
554 self.0.sub().into()
555 }
556
557 async fn subi(&self) -> U64 {
558 self.0.subi().into()
559 }
560
561 async fn sw(&self) -> U64 {
562 self.0.sw().into()
563 }
564
565 async fn sww(&self) -> U64 {
566 self.0.sww().into()
567 }
568
569 async fn time(&self) -> U64 {
570 self.0.time().into()
571 }
572
573 async fn tr(&self) -> U64 {
574 self.0.tr().into()
575 }
576
577 async fn tro(&self) -> U64 {
578 self.0.tro().into()
579 }
580
581 async fn wdcm(&self) -> U64 {
582 self.0.wdcm().into()
583 }
584
585 async fn wqcm(&self) -> U64 {
586 self.0.wqcm().into()
587 }
588
589 async fn wdop(&self) -> U64 {
590 self.0.wdop().into()
591 }
592
593 async fn wqop(&self) -> U64 {
594 self.0.wqop().into()
595 }
596
597 async fn wdml(&self) -> U64 {
598 self.0.wdml().into()
599 }
600
601 async fn wqml(&self) -> U64 {
602 self.0.wqml().into()
603 }
604
605 async fn wddv(&self) -> U64 {
606 self.0.wddv().into()
607 }
608
609 async fn wqdv(&self) -> U64 {
610 self.0.wqdv().into()
611 }
612
613 async fn wdmd(&self) -> U64 {
614 self.0.wdmd().into()
615 }
616
617 async fn wqmd(&self) -> U64 {
618 self.0.wqmd().into()
619 }
620
621 async fn wdam(&self) -> U64 {
622 self.0.wdam().into()
623 }
624
625 async fn wqam(&self) -> U64 {
626 self.0.wqam().into()
627 }
628
629 async fn wdmm(&self) -> U64 {
630 self.0.wdmm().into()
631 }
632
633 async fn wqmm(&self) -> U64 {
634 self.0.wqmm().into()
635 }
636
637 async fn xor(&self) -> U64 {
638 self.0.xor().into()
639 }
640
641 async fn xori(&self) -> U64 {
642 self.0.xori().into()
643 }
644
645 async fn ecop(&self) -> Option<U64> {
646 self.0.ecop().ok().map(Into::into)
647 }
648
649 async fn aloc_dependent_cost(&self) -> DependentCost {
650 self.0.aloc().into()
651 }
652
653 async fn bldd(&self) -> Option<DependentCost> {
654 self.0.bldd().ok().map(Into::into)
655 }
656
657 async fn bsiz(&self) -> Option<DependentCost> {
658 self.0.bsiz().ok().map(Into::into)
659 }
660
661 async fn cfe(&self) -> DependentCost {
662 self.0.cfe().into()
663 }
664
665 async fn cfei_dependent_cost(&self) -> DependentCost {
666 self.0.cfei().into()
667 }
668
669 async fn call(&self) -> DependentCost {
670 self.0.call().into()
671 }
672
673 async fn ccp(&self) -> DependentCost {
674 self.0.ccp().into()
675 }
676
677 async fn croo(&self) -> DependentCost {
678 self.0.croo().into()
679 }
680
681 async fn csiz(&self) -> DependentCost {
682 self.0.csiz().into()
683 }
684
685 async fn ed19_dependent_cost(&self) -> DependentCost {
686 self.0.ed19().into()
687 }
688
689 async fn k256(&self) -> DependentCost {
690 self.0.k256().into()
691 }
692
693 async fn ldc(&self) -> DependentCost {
694 self.0.ldc().into()
695 }
696
697 async fn logd(&self) -> DependentCost {
698 self.0.logd().into()
699 }
700
701 async fn mcl(&self) -> DependentCost {
702 self.0.mcl().into()
703 }
704
705 async fn mcli(&self) -> DependentCost {
706 self.0.mcli().into()
707 }
708
709 async fn mcp(&self) -> DependentCost {
710 self.0.mcp().into()
711 }
712
713 async fn mcpi(&self) -> DependentCost {
714 self.0.mcpi().into()
715 }
716
717 async fn meq(&self) -> DependentCost {
718 self.0.meq().into()
719 }
720
721 async fn retd(&self) -> DependentCost {
722 self.0.retd().into()
723 }
724
725 async fn s256(&self) -> DependentCost {
726 self.0.s256().into()
727 }
728
729 async fn scwq(&self) -> DependentCost {
730 self.0.scwq().into()
731 }
732
733 async fn smo(&self) -> DependentCost {
734 self.0.smo().into()
735 }
736
737 async fn srwq(&self) -> DependentCost {
738 self.0.srwq().into()
739 }
740
741 async fn swwq(&self) -> DependentCost {
742 self.0.swwq().into()
743 }
744
745 async fn epar(&self) -> Option<DependentCost> {
746 self.0.epar().ok().map(Into::into)
747 }
748
749 async fn contract_root(&self) -> DependentCost {
752 self.0.contract_root().into()
753 }
754
755 async fn state_root(&self) -> DependentCost {
756 self.0.state_root().into()
757 }
758
759 async fn vm_initialization(&self) -> DependentCost {
760 self.0.vm_initialization().into()
761 }
762
763 async fn new_storage_per_byte(&self) -> U64 {
764 self.0.new_storage_per_byte().into()
765 }
766}
767
768#[Object]
769impl LightOperation {
770 async fn base(&self) -> U64 {
771 self.base.into()
772 }
773
774 async fn units_per_gas(&self) -> U64 {
775 self.units_per_gas.into()
776 }
777}
778
779#[Object]
780impl HeavyOperation {
781 async fn base(&self) -> U64 {
782 self.base.into()
783 }
784
785 async fn gas_per_unit(&self) -> U64 {
786 self.gas_per_unit.into()
787 }
788}
789
790#[Object]
791impl ChainInfo {
792 #[graphql(complexity = "query_costs().storage_read")]
793 async fn name(&self, ctx: &Context<'_>) -> async_graphql::Result<String> {
794 let config: &Config = ctx.data_unchecked();
795 Ok(config.chain_name.clone())
796 }
797
798 #[graphql(complexity = "query_costs().storage_read + child_complexity")]
799 async fn latest_block(&self, ctx: &Context<'_>) -> async_graphql::Result<Block> {
800 let query = ctx.read_view()?;
801
802 let latest_block = query.latest_block()?.into();
803 Ok(latest_block)
804 }
805
806 #[graphql(complexity = "query_costs().storage_read")]
807 async fn da_height(&self, ctx: &Context<'_>) -> U64 {
808 let Ok(query) = ctx.read_view() else {
809 return 0.into();
810 };
811
812 query.da_height().unwrap_or_default().0.into()
813 }
814
815 #[graphql(complexity = "query_costs().storage_read + child_complexity")]
816 async fn consensus_parameters(
817 &self,
818 ctx: &Context<'_>,
819 ) -> async_graphql::Result<ConsensusParameters> {
820 let params = ctx
821 .data_unchecked::<ChainInfoProvider>()
822 .current_consensus_params();
823
824 Ok(ConsensusParameters(params))
825 }
826
827 #[graphql(complexity = "query_costs().storage_read + child_complexity")]
828 async fn gas_costs(&self, ctx: &Context<'_>) -> async_graphql::Result<GasCosts> {
829 let params = ctx
830 .data_unchecked::<ChainInfoProvider>()
831 .current_consensus_params();
832
833 Ok(GasCosts(params.gas_costs().clone()))
834 }
835}
836
837#[derive(Default)]
838pub struct ChainQuery;
839
840#[Object]
841impl ChainQuery {
842 async fn chain(&self) -> ChainInfo {
843 ChainInfo
844 }
845}