Skip to main content

fuel_core/schema/
upgrades.rs

1use crate::{
2    graphql_api::{
3        IntoApiResult,
4        api_service::ChainInfoProvider,
5        query_costs,
6    },
7    schema::{
8        ReadViewProvider,
9        chain::{
10            ConsensusParameters,
11            consensus_params_for_selection,
12        },
13        scalars::HexString,
14    },
15};
16use async_graphql::{
17    Context,
18    Object,
19    SimpleObject,
20};
21use fuel_core_types::{
22    blockchain::header::{
23        ConsensusParametersVersion,
24        StateTransitionBytecodeVersion,
25    },
26    fuel_types,
27    fuel_vm::UploadedBytecode as StorageUploadedBytecode,
28};
29
30#[derive(Default)]
31pub struct UpgradeQuery;
32
33#[Object]
34impl UpgradeQuery {
35    #[graphql(complexity = "query_costs().storage_read + child_complexity")]
36    async fn consensus_parameters(
37        &self,
38        ctx: &Context<'_>,
39        version: ConsensusParametersVersion,
40    ) -> async_graphql::Result<ConsensusParameters> {
41        let params = ctx
42            .data_unchecked::<ChainInfoProvider>()
43            .consensus_params_at_version(&version)?;
44
45        Ok(ConsensusParameters(consensus_params_for_selection(
46            params,
47            &ctx.look_ahead(),
48        )))
49    }
50
51    #[graphql(complexity = "query_costs().storage_read + child_complexity")]
52    async fn state_transition_bytecode_by_version(
53        &self,
54        ctx: &Context<'_>,
55        version: StateTransitionBytecodeVersion,
56    ) -> async_graphql::Result<Option<StateTransitionBytecode>> {
57        let query = ctx.read_view()?;
58        query
59            .state_transition_bytecode_root(version)
60            .into_api_result()
61    }
62
63    #[graphql(complexity = "query_costs().storage_read + child_complexity")]
64    async fn state_transition_bytecode_by_root(
65        &self,
66        root: HexString,
67    ) -> async_graphql::Result<StateTransitionBytecode> {
68        StateTransitionBytecode::try_from(root)
69    }
70}
71
72pub struct StateTransitionBytecode {
73    root: fuel_types::Bytes32,
74}
75
76#[Object]
77impl StateTransitionBytecode {
78    async fn root(&self) -> HexString {
79        HexString(self.root.to_vec())
80    }
81
82    #[graphql(complexity = "query_costs().state_transition_bytecode_read")]
83    async fn bytecode(
84        &self,
85        ctx: &Context<'_>,
86    ) -> async_graphql::Result<UploadedBytecode> {
87        let query = ctx.read_view()?;
88        query
89            .state_transition_bytecode(self.root)
90            .map(UploadedBytecode::from)
91            .map_err(async_graphql::Error::from)
92    }
93}
94
95impl From<fuel_types::Bytes32> for StateTransitionBytecode {
96    fn from(root: fuel_types::Bytes32) -> Self {
97        Self { root }
98    }
99}
100
101impl TryFrom<HexString> for StateTransitionBytecode {
102    type Error = async_graphql::Error;
103
104    fn try_from(root: HexString) -> Result<Self, Self::Error> {
105        let root = root.0.as_slice().try_into()?;
106        Ok(Self { root })
107    }
108}
109
110#[derive(SimpleObject)]
111pub struct UploadedBytecode {
112    /// Combined bytecode of all uploaded subsections.
113    bytecode: HexString,
114    /// Number of uploaded subsections (if incomplete).
115    uploaded_subsections_number: Option<u16>,
116    /// Indicates if the bytecode upload is complete.
117    completed: bool,
118}
119
120impl From<StorageUploadedBytecode> for UploadedBytecode {
121    fn from(value: fuel_core_types::fuel_vm::UploadedBytecode) -> Self {
122        match value {
123            StorageUploadedBytecode::Uncompleted {
124                bytecode,
125                uploaded_subsections_number,
126            } => Self {
127                bytecode: HexString(bytecode),
128                uploaded_subsections_number: Some(uploaded_subsections_number),
129                completed: false,
130            },
131            StorageUploadedBytecode::Completed(bytecode) => Self {
132                bytecode: HexString(bytecode),
133                uploaded_subsections_number: None,
134                completed: true,
135            },
136        }
137    }
138}