diff --git a/crates/fuel-core/src/schema/blob.rs b/crates/fuel-core/src/schema/blob.rs index 7e6949f8d04..08f5264bb99 100644 --- a/crates/fuel-core/src/schema/blob.rs +++ b/crates/fuel-core/src/schema/blob.rs @@ -28,11 +28,11 @@ impl Blob { } #[graphql(complexity = "query_costs().bytecode_read")] - async fn bytecode(&self, ctx: &Context<'_>) -> async_graphql::Result { + async fn bytecode(&self, ctx: &Context<'_>) -> async_graphql::Result> { let query = ctx.read_view()?; query .blob_bytecode(self.0) - .map(HexString) + .map(|bytes| HexString(bytes.into())) .map_err(async_graphql::Error::from) } } diff --git a/crates/fuel-core/src/schema/block.rs b/crates/fuel-core/src/schema/block.rs index e66952c6846..c955206015b 100644 --- a/crates/fuel-core/src/schema/block.rs +++ b/crates/fuel-core/src/schema/block.rs @@ -424,13 +424,13 @@ impl BlockMutation { pub struct BlockSubscription; #[Subscription] -impl BlockSubscription { +impl <'a>BlockSubscription { #[graphql(name = "alpha__new_blocks")] - async fn new_blocks<'a>( + async fn new_blocks( &self, ctx: &Context<'a>, ) -> async_graphql::Result< - impl Stream> + 'a + use<'a>, + impl Stream>> + 'a + use<'a>, > { require_expensive_subscriptions(ctx)?; let worker_state: &graphql_api::worker_service::SharedState = @@ -440,9 +440,7 @@ impl BlockSubscription { let stream = BroadcastStream::new(receiver).map(|result| { result .map(|bytes| { - // TODO: Avoid cloning the bytes here. - // https://github.com/FuelLabs/fuel-core/issues/2657 - HexString(bytes.as_ref().clone()) + HexString::from(bytes.as_ref().clone()) }) .map_err(Into::into) }); diff --git a/crates/fuel-core/src/schema/contract.rs b/crates/fuel-core/src/schema/contract.rs index 9f1225bd21a..2554ce0e22a 100644 --- a/crates/fuel-core/src/schema/contract.rs +++ b/crates/fuel-core/src/schema/contract.rs @@ -48,11 +48,11 @@ impl Contract { } #[graphql(complexity = "query_costs().bytecode_read")] - async fn bytecode(&self, ctx: &Context<'_>) -> async_graphql::Result { + async fn bytecode(&self, ctx: &Context<'_>) -> async_graphql::Result> { let query = ctx.read_view()?; query .contract_bytecode(self.0) - .map(HexString) + .map(|bytes|HexString(bytes.into())) .map_err(Into::into) } diff --git a/crates/fuel-core/src/schema/da_compressed.rs b/crates/fuel-core/src/schema/da_compressed.rs index d3c5759f16c..c6c169e679b 100644 --- a/crates/fuel-core/src/schema/da_compressed.rs +++ b/crates/fuel-core/src/schema/da_compressed.rs @@ -24,8 +24,8 @@ impl From> for DaCompressedBlock { #[Object] impl DaCompressedBlock { - async fn bytes(&self) -> HexString { - HexString(self.bytes.clone()) + async fn bytes(&self) -> HexString<'_> { + HexString(self.bytes.as_slice().into()) } } diff --git a/crates/fuel-core/src/schema/message.rs b/crates/fuel-core/src/schema/message.rs index ba6784a7e3b..9e01e72aab6 100644 --- a/crates/fuel-core/src/schema/message.rs +++ b/crates/fuel-core/src/schema/message.rs @@ -52,7 +52,7 @@ impl Message { (*self.0.nonce()).into() } - async fn data(&self) -> HexString { + async fn data(&self) -> HexString<'_> { self.0.data().clone().into() } @@ -90,7 +90,7 @@ impl MessageQuery { after: Option, last: Option, before: Option, - ) -> async_graphql::Result> + ) -> async_graphql::Result, Message, EmptyFields, EmptyFields>> { let query = ctx.read_view()?; let owner = owner.map(|owner| owner.0); @@ -221,7 +221,7 @@ impl MessageProof { self.0.amount.into() } - async fn data(&self) -> HexString { + async fn data(&self) -> HexString<'_> { self.0.data.clone().into() } } diff --git a/crates/fuel-core/src/schema/scalars.rs b/crates/fuel-core/src/schema/scalars.rs index 0a08fa87459..ef437c91dd3 100644 --- a/crates/fuel-core/src/schema/scalars.rs +++ b/crates/fuel-core/src/schema/scalars.rs @@ -22,6 +22,7 @@ use std::{ }, str::FromStr, }; +use std::borrow::Cow; pub use tx_pointer::TxPointer; pub use utxo_id::UtxoId; @@ -161,10 +162,26 @@ impl CursorType for SortedTxCursor { } #[derive(Clone, Debug, derive_more::Into, derive_more::From, PartialEq, Eq)] -pub struct HexString(pub(crate) Vec); +pub struct HexString<'a>(pub(crate) Cow<'a, [u8]>); + +impl From> for HexString<'_> { + fn from(vec: Vec) -> Self { + HexString(Cow::Owned(vec)) + } +} + +impl <'a>From<&'a [u8]> for HexString<'a> { + fn from(value: &'a [u8]) -> Self { HexString(Cow::Borrowed(value)) } +} + +impl From> for Vec { + fn from(hex: HexString) -> Self { + hex.0.into_owned() + } +} #[Scalar(name = "HexString")] -impl ScalarType for HexString { +impl ScalarType for HexString<'_> { fn parse(value: Value) -> InputValueResult { match &value { Value::String(value) => { @@ -179,14 +196,14 @@ impl ScalarType for HexString { } } -impl Display for HexString { +impl Display for HexString<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let s = format!("0x{}", hex::encode(&self.0)); + let s = format!("0x{}", hex::encode(&self.0.as_ref())); s.fmt(f) } } -impl CursorType for HexString { +impl CursorType for HexString<'_> { type Error = String; fn decode_cursor(s: &str) -> Result { @@ -198,28 +215,28 @@ impl CursorType for HexString { } } -impl FromStr for HexString { +impl FromStr for HexString<'_> { type Err = String; fn from_str(s: &str) -> Result { let value = s.strip_prefix("0x").unwrap_or(s); // decode into bytes let bytes = hex::decode(value).map_err(|e| e.to_string())?; - Ok(HexString(bytes)) + Ok(HexString(Cow::Owned(bytes))) } } -impl From for HexString { +impl From for HexString<'_> { fn from(n: fuel_types::Nonce) -> Self { - HexString(n.to_vec()) + HexString(Cow::Owned(n.to_vec())) } } -impl TryInto for HexString { +impl TryInto for HexString<'_> { type Error = TryFromSliceError; fn try_into(self) -> Result { - let bytes: [u8; 32] = self.0.as_slice().try_into()?; + let bytes: [u8; 32] = self.0.as_ref().try_into()?; Ok(fuel_types::Nonce::from(bytes)) } } diff --git a/crates/fuel-core/src/schema/storage.rs b/crates/fuel-core/src/schema/storage.rs index 960a121c842..93888c691c4 100644 --- a/crates/fuel-core/src/schema/storage.rs +++ b/crates/fuel-core/src/schema/storage.rs @@ -160,7 +160,7 @@ impl StorageSlot { self.key.into() } - async fn value(&self) -> HexString { - HexString(self.value.clone()) + async fn value(&self) -> HexString<'_> { + HexString::from(self.value.as_ref()) } } diff --git a/crates/fuel-core/src/schema/tx.rs b/crates/fuel-core/src/schema/tx.rs index f78d6017ed4..0e2cf9c2175 100644 --- a/crates/fuel-core/src/schema/tx.rs +++ b/crates/fuel-core/src/schema/tx.rs @@ -124,7 +124,7 @@ impl TxQuery { async fn dry_run_inner( &self, ctx: &Context<'_>, - txs: Vec, + txs: Vec>, // If set to false, disable input utxo validation, overriding the configuration of the node. // This allows for non-existent inputs to be used without signature validation // for read-only calls. @@ -375,7 +375,7 @@ impl TxQuery { #[graphql( desc = "The original transaction that contains application level logic only" )] - tx: HexString, + tx: HexString<'_>, #[graphql( desc = "Number of blocks into the future to estimate the gas price for" )] @@ -519,7 +519,7 @@ impl TxQuery { async fn estimate_predicates( &self, ctx: &Context<'_>, - tx: HexString, + tx: HexString<'_>, ) -> async_graphql::Result { let query = ctx.read_view()?.into_owned(); @@ -550,7 +550,7 @@ impl TxQuery { async fn dry_run( &self, ctx: &Context<'_>, - txs: Vec, + txs: Vec>, // If set to false, disable input utxo validation, overriding the configuration of the node. // This allows for non-existent inputs to be used without signature validation // for read-only calls. @@ -574,7 +574,7 @@ impl TxQuery { async fn dry_run_record_storage_reads( &self, ctx: &Context<'_>, - txs: Vec, + txs: Vec>, // If set to false, disable input utxo validation, overriding the configuration of the node. // This allows for non-existent inputs to be used without signature validation // for read-only calls. @@ -627,7 +627,7 @@ impl TxMutation { async fn dry_run( &self, ctx: &Context<'_>, - txs: Vec, + txs: Vec>, // If set to false, disable input utxo validation, overriding the configuration of the node. // This allows for non-existent inputs to be used without signature validation // for read-only calls. @@ -648,7 +648,7 @@ impl TxMutation { async fn submit( &self, ctx: &Context<'_>, - tx: HexString, + tx: HexString<'_>, estimate_predicates: Option, ) -> async_graphql::Result { let txpool = ctx.data_unchecked::(); @@ -679,7 +679,7 @@ impl TxMutation { pub struct TxStatusSubscription; #[Subscription] -impl TxStatusSubscription { +impl<'a> TxStatusSubscription { /// Returns a stream of status updates for the given transaction id. /// If the current status is [`TransactionStatus::Success`], [`TransactionStatus::Failed`], /// or [`TransactionStatus::SqueezedOut`] the stream will return that and end immediately. @@ -693,7 +693,7 @@ impl TxStatusSubscription { /// a status. If this occurs the stream can simply be restarted to return /// the latest status. #[graphql(complexity = "query_costs().status_change + child_complexity")] - async fn status_change<'a>( + async fn status_change( &self, ctx: &'a Context<'a>, #[graphql(desc = "The ID of the transaction")] id: TransactionId, @@ -721,7 +721,7 @@ impl TxStatusSubscription { } #[graphql(name = "alpha__preconfirmations")] - async fn preconfirmations<'a>( + async fn preconfirmations( &self, ctx: &'a Context<'a>, ) -> async_graphql::Result< @@ -745,10 +745,10 @@ impl TxStatusSubscription { /// Submits transaction to the `TxPool` and await either success or failure. #[graphql(complexity = "query_costs().submit_and_await + child_complexity")] - async fn submit_and_await<'a>( + async fn submit_and_await( &self, ctx: &'a Context<'a>, - tx: HexString, + tx: HexString<'a>, estimate_predicates: Option, ) -> async_graphql::Result< impl Stream> + 'a + use<'a>, @@ -767,10 +767,10 @@ impl TxStatusSubscription { /// Compared to the `submitAndAwait`, the stream also contains /// `SubmittedStatus` and potentially preconfirmation as an intermediate state. #[graphql(complexity = "query_costs().submit_and_await + child_complexity")] - async fn submit_and_await_status<'a>( + async fn submit_and_await_status( &self, ctx: &'a Context<'a>, - tx: HexString, + tx: HexString<'a>, estimate_predicates: Option, include_preconfirmation: Option, ) -> async_graphql::Result< @@ -788,7 +788,7 @@ impl TxStatusSubscription { async fn submit_and_await_status<'a>( ctx: &'a Context<'a>, - tx: HexString, + tx: HexString<'a>, estimate_predicates: bool, include_preconfirmation: bool, ) -> async_graphql::Result< @@ -884,8 +884,8 @@ pub mod schema_types { // signature verification. They provide a mocked version of the predicate that // returns `true` even if the signature doesn't match. pub predicate_address: Address, - pub predicate: HexString, - pub predicate_data: HexString, + pub predicate: HexString<'static>, + pub predicate_data: HexString<'static>, } #[derive(async_graphql::InputObject)] diff --git a/crates/fuel-core/src/schema/tx/input.rs b/crates/fuel-core/src/schema/tx/input.rs index 8a56d2bba02..47aa6b7c73b 100644 --- a/crates/fuel-core/src/schema/tx/input.rs +++ b/crates/fuel-core/src/schema/tx/input.rs @@ -17,13 +17,13 @@ use async_graphql::{ use fuel_core_types::fuel_tx; #[derive(Union)] -pub enum Input { - Coin(InputCoin), +pub enum Input<'a> { + Coin(InputCoin<'a>), Contract(InputContract), - Message(InputMessage), + Message(InputMessage<'a>), } -pub struct InputCoin { +pub struct InputCoin<'a> { utxo_id: UtxoId, owner: Address, amount: U64, @@ -31,12 +31,12 @@ pub struct InputCoin { tx_pointer: TxPointer, witness_index: u16, predicate_gas_used: U64, - predicate: HexString, - predicate_data: HexString, + predicate: HexString<'a>, + predicate_data: HexString<'a>, } #[Object] -impl InputCoin { +impl InputCoin<'_> { async fn utxo_id(&self) -> UtxoId { self.utxo_id } @@ -65,11 +65,11 @@ impl InputCoin { self.predicate_gas_used } - async fn predicate(&self) -> HexString { + async fn predicate(&self) -> HexString<'_> { self.predicate.clone() } - async fn predicate_data(&self) -> HexString { + async fn predicate_data(&self) -> HexString<'_> { self.predicate_data.clone() } } @@ -105,20 +105,20 @@ impl InputContract { } } -pub struct InputMessage { +pub struct InputMessage<'a> { sender: Address, recipient: Address, amount: U64, nonce: Nonce, witness_index: u16, predicate_gas_used: U64, - data: HexString, - predicate: HexString, - predicate_data: HexString, + data: HexString<'a>, + predicate: HexString<'a>, + predicate_data: HexString<'a>, } #[Object] -impl InputMessage { +impl InputMessage<'_> { async fn sender(&self) -> Address { self.sender } @@ -143,21 +143,21 @@ impl InputMessage { self.predicate_gas_used } - async fn data(&self) -> &HexString { + async fn data(&self) -> &HexString<'_> { &self.data } - async fn predicate(&self) -> &HexString { + async fn predicate(&self) -> &HexString<'_> { &self.predicate } - async fn predicate_data(&self) -> &HexString { + async fn predicate_data(&self) -> &HexString<'_> { &self.predicate_data } } -impl From<&fuel_tx::Input> for Input { - fn from(input: &fuel_tx::Input) -> Self { +impl <'a> From<&'a fuel_tx::Input> for Input<'a> { + fn from(input: &'a fuel_tx::Input) -> Self { match input { fuel_tx::Input::CoinSigned(fuel_tx::input::coin::CoinSigned { utxo_id, @@ -175,7 +175,7 @@ impl From<&fuel_tx::Input> for Input { tx_pointer: TxPointer(*tx_pointer), witness_index: *witness_index, predicate_gas_used: 0.into(), - predicate: HexString(Default::default()), + predicate: HexString(vec![].into()), predicate_data: HexString(Default::default()), }), fuel_tx::Input::CoinPredicate(fuel_tx::input::coin::CoinPredicate { @@ -196,8 +196,8 @@ impl From<&fuel_tx::Input> for Input { tx_pointer: TxPointer(*tx_pointer), witness_index: Default::default(), predicate_gas_used: (*predicate_gas_used).into(), - predicate: HexString(predicate.to_vec()), - predicate_data: HexString(predicate_data.clone().into_inner()), + predicate: HexString::from(predicate.as_ref()), + predicate_data: HexString::from(predicate_data.as_ref()), }), fuel_tx::Input::Contract(contract) => Input::Contract(contract.into()), fuel_tx::Input::MessageCoinSigned( @@ -239,8 +239,8 @@ impl From<&fuel_tx::Input> for Input { witness_index: Default::default(), predicate_gas_used: (*predicate_gas_used).into(), data: HexString(Default::default()), - predicate: HexString(predicate.to_vec()), - predicate_data: HexString(predicate_data.clone().into_inner()), + predicate: HexString::from(predicate.as_ref()), + predicate_data: HexString::from(predicate_data.as_ref()), }), fuel_tx::Input::MessageDataSigned( fuel_tx::input::message::MessageDataSigned { @@ -259,9 +259,9 @@ impl From<&fuel_tx::Input> for Input { nonce: Nonce(*nonce), witness_index: *witness_index, predicate_gas_used: 0.into(), - data: HexString(data.clone().into_inner()), - predicate: HexString(Default::default()), - predicate_data: HexString(Default::default()), + data: HexString::from(data.as_ref()), + predicate: HexString(vec![].into()), + predicate_data: HexString(vec![].into()), }), fuel_tx::Input::MessageDataPredicate( fuel_tx::input::message::MessageDataPredicate { @@ -282,9 +282,9 @@ impl From<&fuel_tx::Input> for Input { nonce: Nonce(*nonce), witness_index: Default::default(), predicate_gas_used: (*predicate_gas_used).into(), - data: HexString(data.clone().into_inner()), - predicate: HexString(predicate.to_vec()), - predicate_data: HexString(predicate_data.clone().into_inner()), + data: HexString::from(data.as_ref()), + predicate: HexString::from(predicate.as_ref()), + predicate_data: HexString::from(predicate_data.as_ref()), }), } } diff --git a/crates/fuel-core/src/schema/tx/receipt.rs b/crates/fuel-core/src/schema/tx/receipt.rs index 67f00eb01cf..7147489296e 100644 --- a/crates/fuel-core/src/schema/tx/receipt.rs +++ b/crates/fuel-core/src/schema/tx/receipt.rs @@ -126,7 +126,7 @@ impl Receipt { async fn gas_used(&self) -> Option { self.0.gas_used().map(Into::into) } - async fn data(&self) -> Option { + async fn data(&self) -> Option> { self.0.data().map(|d| d.to_vec().into()) } async fn sender(&self) -> Option
{ diff --git a/crates/fuel-core/src/schema/tx/types.rs b/crates/fuel-core/src/schema/tx/types.rs index 2b6f3e8e5a6..727eafa9385 100644 --- a/crates/fuel-core/src/schema/tx/types.rs +++ b/crates/fuel-core/src/schema/tx/types.rs @@ -107,7 +107,7 @@ impl ProgramState { self.return_type } - async fn data(&self) -> HexString { + async fn data(&self) -> HexString<'_> { self.data.clone().into() } } @@ -671,7 +671,7 @@ impl Transaction { self.0.is_blob() } - async fn inputs(&self) -> Option> { + async fn inputs(&self) -> Option>> { match &self.0 { fuel_tx::Transaction::Script(tx) => { Some(tx.inputs().iter().map(Into::into).collect()) @@ -724,37 +724,37 @@ impl Transaction { } } - async fn witnesses(&self) -> Option> { + async fn witnesses<'a>(&'a self) -> Option>> { match &self.0 { fuel_tx::Transaction::Script(tx) => Some( tx.witnesses() .iter() - .map(|w| HexString(w.clone().into_inner())) + .map(|w| HexString::from(w.as_vec().as_ref())) .collect(), ), fuel_tx::Transaction::Create(tx) => Some( tx.witnesses() .iter() - .map(|w| HexString(w.clone().into_inner())) + .map(|w| HexString::from(w.as_vec().as_ref())) .collect(), ), fuel_tx::Transaction::Mint(_) => None, fuel_tx::Transaction::Upgrade(tx) => Some( tx.witnesses() .iter() - .map(|w| HexString(w.clone().into_inner())) + .map(|w| HexString::from(w.as_vec().as_ref())) .collect(), ), fuel_tx::Transaction::Upload(tx) => Some( tx.witnesses() .iter() - .map(|w| HexString(w.clone().into_inner())) + .map(|w| HexString::from(w.as_vec().as_ref())) .collect(), ), fuel_tx::Transaction::Blob(tx) => Some( tx.witnesses() .iter() - .map(|w| HexString(w.clone().into_inner())) + .map(|w| HexString::from(w.as_vec().as_ref())) .collect(), ), } @@ -795,10 +795,10 @@ impl Transaction { .map_err(Into::into) } - async fn script(&self) -> Option { + async fn script(&self) -> Option> { match &self.0 { fuel_tx::Transaction::Script(script) => { - Some(HexString(script.script().clone())) + Some(HexString::from(script.script().as_ref())) } fuel_tx::Transaction::Create(_) | fuel_tx::Transaction::Mint(_) @@ -808,10 +808,10 @@ impl Transaction { } } - async fn script_data(&self) -> Option { + async fn script_data(&self) -> Option> { match &self.0 { fuel_tx::Transaction::Script(script) => { - Some(HexString(script.script_data().clone())) + Some(HexString::from(script.script_data().as_ref())) } fuel_tx::Transaction::Create(_) | fuel_tx::Transaction::Mint(_) @@ -854,7 +854,7 @@ impl Transaction { } } - async fn storage_slots(&self) -> Option> { + async fn storage_slots(&self) -> Option>> { match &self.0 { fuel_tx::Transaction::Script(_) => None, fuel_tx::Transaction::Create(create) => Some( @@ -939,8 +939,8 @@ impl Transaction { #[graphql(complexity = "query_costs().tx_raw_payload")] /// Return the transaction bytes using canonical encoding - async fn raw_payload(&self) -> HexString { - HexString(self.0.clone().to_bytes()) + async fn raw_payload(&self) -> HexString<'_> { + HexString::from(self.0.to_bytes()) } } @@ -1094,8 +1094,8 @@ impl DryRunStorageReads { #[derive(Clone)] pub struct StorageReadReplayEvent { column: U32, - key: HexString, - value: Option, + key: HexString<'static>, + value: Option>, } impl From @@ -1104,8 +1104,8 @@ impl From fn from(event: fuel_core_types::services::executor::StorageReadReplayEvent) -> Self { Self { column: event.column.into(), - key: HexString(event.key), - value: event.value.map(HexString), + key: HexString(event.key.into()), + value: event.value.map(|bytes|HexString(bytes.into())), } } } @@ -1116,11 +1116,11 @@ impl StorageReadReplayEvent { self.column } - async fn key(&self) -> HexString { + async fn key(&self) -> HexString<'_> { self.key.clone() } - async fn value(&self) -> Option { + async fn value(&self) -> Option> { self.value.clone() } } diff --git a/crates/fuel-core/src/schema/upgrades.rs b/crates/fuel-core/src/schema/upgrades.rs index f74899104d7..f6c2dd13ac7 100644 --- a/crates/fuel-core/src/schema/upgrades.rs +++ b/crates/fuel-core/src/schema/upgrades.rs @@ -57,7 +57,7 @@ impl UpgradeQuery { #[graphql(complexity = "query_costs().storage_read + child_complexity")] async fn state_transition_bytecode_by_root( &self, - root: HexString, + root: HexString<'_>, ) -> async_graphql::Result { StateTransitionBytecode::try_from(root) } @@ -69,15 +69,15 @@ pub struct StateTransitionBytecode { #[Object] impl StateTransitionBytecode { - async fn root(&self) -> HexString { - HexString(self.root.to_vec()) + async fn root(&self) -> HexString<'_> { + HexString::from(self.root.as_ref()) } #[graphql(complexity = "query_costs().state_transition_bytecode_read")] async fn bytecode( &self, ctx: &Context<'_>, - ) -> async_graphql::Result { + ) -> async_graphql::Result> { let query = ctx.read_view()?; query .state_transition_bytecode(self.root) @@ -92,38 +92,38 @@ impl From for StateTransitionBytecode { } } -impl TryFrom for StateTransitionBytecode { +impl TryFrom> for StateTransitionBytecode { type Error = async_graphql::Error; fn try_from(root: HexString) -> Result { - let root = root.0.as_slice().try_into()?; + let root = (*root.0).try_into()?; Ok(Self { root }) } } #[derive(SimpleObject)] -pub struct UploadedBytecode { +pub struct UploadedBytecode<'a> { /// Combined bytecode of all uploaded subsections. - bytecode: HexString, + bytecode: HexString<'a>, /// Number of uploaded subsections (if incomplete). uploaded_subsections_number: Option, /// Indicates if the bytecode upload is complete. completed: bool, } -impl From for UploadedBytecode { +impl From for UploadedBytecode<'_> { fn from(value: fuel_core_types::fuel_vm::UploadedBytecode) -> Self { match value { StorageUploadedBytecode::Uncompleted { bytecode, uploaded_subsections_number, } => Self { - bytecode: HexString(bytecode), + bytecode: HexString(bytecode.into()), uploaded_subsections_number: Some(uploaded_subsections_number), completed: false, }, StorageUploadedBytecode::Completed(bytecode) => Self { - bytecode: HexString(bytecode), + bytecode: HexString(bytecode.into()), uploaded_subsections_number: None, completed: true, },