fuel_core/schema/
chain.rs

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    // Non-opcode prices
750
751    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}