From 3fd9cba20da44fef4dbe86904f9f55cafea74be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bigna=20H=C3=A4rdi?= <73821294+haerdib@users.noreply.github.com> Date: Tue, 10 Jan 2023 08:36:37 +0100 Subject: [PATCH] Enforce `Bytes` and remove obsolete hex-utils (#423) * remove hex utils remove utils fix build fix rebase * fix clippy --- src/api/api_client.rs | 19 +--- src/api/rpc_api/author.rs | 68 ++++++------ src/api/rpc_api/chain.rs | 3 - src/api/rpc_api/frame_system.rs | 3 +- src/api/rpc_api/pallet_transaction_payment.rs | 24 ++--- src/api/rpc_api/state.rs | 4 +- src/lib.rs | 13 ++- src/utils.rs | 102 ------------------ .../pallet_transaction_payment_tests.rs | 7 +- 9 files changed, 67 insertions(+), 176 deletions(-) delete mode 100644 src/utils.rs diff --git a/src/api/api_client.rs b/src/api/api_client.rs index 4a8eea082..fefc612fb 100644 --- a/src/api/api_client.rs +++ b/src/api/api_client.rs @@ -14,7 +14,6 @@ use crate::{ api::error::{Error, Result}, rpc::Request, - utils::FromHexString, GetAccountInformation, }; use ac_compose_macros::rpc_params; @@ -35,7 +34,7 @@ use sp_runtime::MultiSignature; /// /// ```no_run /// use substrate_api_client::{ -/// Api, FromHexString, rpc::Request, rpc::Error as RpcClientError, XtStatus, PlainTipExtrinsicParams, rpc::Result as RpcResult +/// Api, rpc::Request, rpc::Error as RpcClientError, XtStatus, PlainTipExtrinsicParams, rpc::Result as RpcResult /// }; /// use serde::de::DeserializeOwned; /// use ac_primitives::RpcParams; @@ -178,7 +177,6 @@ where Client: Request, Params: ExtrinsicParams, Runtime: FrameSystemConfig, - Runtime::Hash: FromHexString, { /// Create a new Api client with call to the node to retrieve metadata. pub fn new(client: Client) -> Result { @@ -239,7 +237,6 @@ where Client: Request, Params: ExtrinsicParams, Runtime: FrameSystemConfig, - Runtime::Hash: FromHexString, { /// Get the genesis hash from node via websocket query. fn get_genesis_hash(client: &Client) -> Result { @@ -265,10 +262,7 @@ where #[cfg(test)] mod tests { use super::*; - use crate::{ - rpc::mocks::RpcClientMock, utils::ToHexString, GenericAdditionalParams, - PlainTipExtrinsicParams, - }; + use crate::{rpc::mocks::RpcClientMock, GenericAdditionalParams, PlainTipExtrinsicParams}; use kitchensink_runtime::Runtime; use sp_core::{sr25519::Pair, H256}; use std::{ @@ -321,9 +315,9 @@ mod tests { fn api_runtime_update_works() { let runtime_version = RuntimeVersion { spec_version: 10, ..Default::default() }; // Update metadata - let encoded_metadata = fs::read("./ksm_metadata_v14.bin").unwrap(); + let encoded_metadata: Bytes = fs::read("./ksm_metadata_v14.bin").unwrap().into(); let metadata: RuntimeMetadataPrefixed = - Decode::decode(&mut encoded_metadata.as_slice()).unwrap(); + Decode::decode(&mut encoded_metadata.0.as_slice()).unwrap(); let metadata = Metadata::try_from(metadata).unwrap(); let mut changed_metadata = metadata.clone(); @@ -338,10 +332,7 @@ mod tests { "state_getRuntimeVersion".to_owned(), serde_json::to_string(&runtime_version).unwrap(), ), - ( - "state_getMetadata".to_owned(), - serde_json::to_string(&encoded_metadata.to_hex()).unwrap(), - ), + ("state_getMetadata".to_owned(), serde_json::to_string(&encoded_metadata).unwrap()), ]); let mut api = create_mock_api(Default::default(), Default::default(), changed_metadata, data); diff --git a/src/api/rpc_api/author.rs b/src/api/rpc_api/author.rs index 738949398..0602bb0f4 100644 --- a/src/api/rpc_api/author.rs +++ b/src/api/rpc_api/author.rs @@ -16,12 +16,12 @@ use crate::{ api::{Error, Result}, rpc::{HandleSubscription, Request, Subscribe}, - utils, Api, Events, ExtrinsicReport, FromHexString, GetBlock, GetStorage, Phase, ToHexString, - TransactionStatus, UncheckedExtrinsicV4, XtStatus, + Api, Events, ExtrinsicReport, GetBlock, GetStorage, Phase, TransactionStatus, + UncheckedExtrinsicV4, XtStatus, }; use ac_compose_macros::rpc_params; use ac_node_api::EventDetails; -use ac_primitives::{ExtrinsicParams, FrameSystemConfig}; +use ac_primitives::{Bytes, ExtrinsicParams, FrameSystemConfig}; use alloc::vec::Vec; use codec::Encode; use log::*; @@ -47,7 +47,7 @@ pub trait SubmitExtrinsic { /// Submit an encoded, opaque extrsinic to the substrate node. /// Returns the extrinsic hash. - fn submit_opaque_extrinsic(&self, encoded_extrinsic: Vec) -> Result; + fn submit_opaque_extrinsic(&self, encoded_extrinsic: Bytes) -> Result; } impl SubmitExtrinsic for Api @@ -66,14 +66,13 @@ where Call: Encode, SignedExtra: Encode, { - self.submit_opaque_extrinsic(extrinsic.encode()) + self.submit_opaque_extrinsic(extrinsic.encode().into()) } - fn submit_opaque_extrinsic(&self, encoded_extrinsic: Vec) -> Result { - let hex_encoded_xt = encoded_extrinsic.to_hex(); + fn submit_opaque_extrinsic(&self, encoded_extrinsic: Bytes) -> Result { + let hex_encoded_xt = rpc_params![encoded_extrinsic]; debug!("sending extrinsic: {:?}", hex_encoded_xt); - let xt_hash = - self.client().request("author_submitExtrinsic", rpc_params![hex_encoded_xt])?; + let xt_hash = self.client().request("author_submitExtrinsic", hex_encoded_xt)?; Ok(xt_hash) } } @@ -97,7 +96,7 @@ where /// watch the extrinsic progress. fn submit_and_watch_opaque_extrinsic( &self, - encoded_extrinsic: Vec, + encoded_extrinsic: Bytes, ) -> Result>; /// Submit an extrinsic and watch in until the desired status @@ -117,7 +116,7 @@ where // This method is blocking. fn submit_and_watch_opaque_extrinsic_until( &self, - encoded_extrinsic: Vec, + encoded_extrinsic: Bytes, watch_until: XtStatus, ) -> Result>; } @@ -148,7 +147,7 @@ where // This method is blocking. fn submit_and_watch_opaque_extrinsic_until_success( &self, - encoded_extrinsic: Vec, + encoded_extrinsic: Bytes, wait_for_finalized: bool, ) -> Result>; } @@ -160,7 +159,6 @@ where Params: ExtrinsicParams, Runtime: FrameSystemConfig, Runtime::Hashing: HashTrait, - Runtime::Hash: FromHexString, { fn submit_and_watch_extrinsic( &self, @@ -170,16 +168,16 @@ where Call: Encode, SignedExtra: Encode, { - self.submit_and_watch_opaque_extrinsic(extrinsic.encode()) + self.submit_and_watch_opaque_extrinsic(extrinsic.encode().into()) } fn submit_and_watch_opaque_extrinsic( &self, - encoded_extrinsic: Vec, + encoded_extrinsic: Bytes, ) -> Result> { self.client() .subscribe( "author_submitAndWatchExtrinsic", - rpc_params![encoded_extrinsic.to_hex()], + rpc_params![encoded_extrinsic], "author_unsubmitAndWatchExtrinsic", ) .map_err(|e| e.into()) @@ -194,15 +192,15 @@ where Call: Encode, SignedExtra: Encode, { - self.submit_and_watch_opaque_extrinsic_until(extrinsic.encode(), watch_until) + self.submit_and_watch_opaque_extrinsic_until(extrinsic.encode().into(), watch_until) } fn submit_and_watch_opaque_extrinsic_until( &self, - encoded_extrinsic: Vec, + encoded_extrinsic: Bytes, watch_until: XtStatus, ) -> Result> { - let tx_hash = Runtime::Hashing::hash_of(&encoded_extrinsic); + let tx_hash = Runtime::Hashing::hash_of(&encoded_extrinsic.0); let mut subscription: TransactionSubscriptionFor = self.submit_and_watch_opaque_extrinsic(encoded_extrinsic)?; @@ -238,7 +236,6 @@ where Runtime: FrameSystemConfig + GetRuntimeBlockType, Runtime::RuntimeBlock: BlockTrait + DeserializeOwned, Runtime::Hashing: HashTrait, - Runtime::Hash: FromHexString, { fn submit_and_watch_extrinsic_until_success( &self, @@ -249,12 +246,15 @@ where Call: Encode, SignedExtra: Encode, { - self.submit_and_watch_opaque_extrinsic_until_success(extrinsic.encode(), wait_for_finalized) + self.submit_and_watch_opaque_extrinsic_until_success( + extrinsic.encode().into(), + wait_for_finalized, + ) } fn submit_and_watch_opaque_extrinsic_until_success( &self, - encoded_extrinsic: Vec, + encoded_extrinsic: Bytes, wait_for_finalized: bool, ) -> Result> { let xt_status = match wait_for_finalized { @@ -282,7 +282,6 @@ where Runtime: FrameSystemConfig + GetRuntimeBlockType, Runtime::RuntimeBlock: BlockTrait + DeserializeOwned, Runtime::Hashing: HashTrait, - Runtime::Hash: FromHexString, { /// Retrieve block details from node and search for the position of the given extrinsic. fn retrieve_extrinsic_index_from_block( @@ -305,7 +304,7 @@ where /// Fetch all block events from node for the given block hash. fn fetch_events_from_block(&self, block_hash: Runtime::Hash) -> Result> { - let key = utils::storage_key("System", "Events"); + let key = crate::storage_key("System", "Events"); let event_bytes = self .get_opaque_storage_by_key_hash(key, Some(block_hash))? .ok_or(Error::BlockNotFound)?; @@ -344,7 +343,7 @@ mod tests { use super::*; use crate::{rpc::mocks::RpcClientMock, AssetTipExtrinsicParams, StorageData}; use ac_node_api::{metadata::Metadata, test_utils::*}; - use ac_primitives::{FrameSystemConfig, RuntimeVersion, SignedBlock}; + use ac_primitives::{Bytes, FrameSystemConfig, RuntimeVersion, SignedBlock}; use codec::{Decode, Encode}; use frame_metadata::RuntimeMetadataPrefixed; use kitchensink_runtime::{BalancesCall, Runtime, RuntimeCall, UncheckedExtrinsic}; @@ -478,20 +477,15 @@ mod tests { RuntimeCall::Balances(BalancesCall::transfer { dest: bob.clone(), value: 2000 }); let call3 = RuntimeCall::Balances(BalancesCall::transfer { dest: bob, value: 1000 }); - let xt1 = UncheckedExtrinsic::new_unsigned(call1).encode(); - let xt2 = UncheckedExtrinsic::new_unsigned(call2).encode(); - let xt3 = UncheckedExtrinsic::new_unsigned(call3).encode(); + let xt1: Bytes = UncheckedExtrinsic::new_unsigned(call1).encode().into(); + let xt2: Bytes = UncheckedExtrinsic::new_unsigned(call2).encode().into(); + let xt3: Bytes = UncheckedExtrinsic::new_unsigned(call3).encode().into(); - let xt_hash1 = ::Hashing::hash_of(&xt1); - let xt_hash2 = ::Hashing::hash_of(&xt2); - let xt_hash3 = ::Hashing::hash_of(&xt3); + let xt_hash1 = ::Hashing::hash_of(&xt1.0); + let xt_hash2 = ::Hashing::hash_of(&xt2.0); + let xt_hash3 = ::Hashing::hash_of(&xt3.0); - // We have to create a Block with hex encoded extrinsic for serialization. Otherwise the deserialization will fail. - // e.g. UncheckedExtrinsic.serialize and UncheckedExtrinsic::deserialize does not work. - let block = Block { - header: default_header(), - extrinsics: vec![xt1.to_hex(), xt2.to_hex(), xt3.to_hex()], - }; + let block = Block { header: default_header(), extrinsics: vec![xt1, xt2, xt3] }; let signed_block = SignedBlock { block, justifications: None }; let data = HashMap::::from([( "chain_getBlock".to_owned(), diff --git a/src/api/rpc_api/chain.rs b/src/api/rpc_api/chain.rs index 82a96a709..b5cac7252 100644 --- a/src/api/rpc_api/chain.rs +++ b/src/api/rpc_api/chain.rs @@ -14,7 +14,6 @@ use crate::{ api::{Api, Result}, rpc::{Request, Subscribe}, - FromHexString, }; use ac_compose_macros::rpc_params; use ac_primitives::{ExtrinsicParams, FrameSystemConfig, SignedBlock}; @@ -37,7 +36,6 @@ where Runtime: FrameSystemConfig, Params: ExtrinsicParams, Runtime::Header: DeserializeOwned, - Runtime::Hash: FromHexString, { type Header = Runtime::Header; @@ -81,7 +79,6 @@ where Runtime: FrameSystemConfig + GetRuntimeBlockType, Params: ExtrinsicParams, Runtime::RuntimeBlock: DeserializeOwned, - Runtime::Hash: FromHexString, { type Block = Runtime::RuntimeBlock; diff --git a/src/api/rpc_api/frame_system.rs b/src/api/rpc_api/frame_system.rs index ae0e18714..9f138a995 100644 --- a/src/api/rpc_api/frame_system.rs +++ b/src/api/rpc_api/frame_system.rs @@ -16,7 +16,6 @@ use crate::{ api::{Api, GetStorage, Result}, rpc::{Request, Subscribe}, - utils, }; use ac_compose_macros::rpc_params; use ac_primitives::{ @@ -182,7 +181,7 @@ where &self, ) -> Result>> { debug!("subscribing to events"); - let key = utils::storage_key("System", "Events"); + let key = crate::storage_key("System", "Events"); self.client() .subscribe("state_subscribeStorage", rpc_params![vec![key]], "state_unsubscribeStorage") .map_err(|e| e.into()) diff --git a/src/api/rpc_api/pallet_transaction_payment.rs b/src/api/rpc_api/pallet_transaction_payment.rs index 2b866e8b8..0c007a7d3 100644 --- a/src/api/rpc_api/pallet_transaction_payment.rs +++ b/src/api/rpc_api/pallet_transaction_payment.rs @@ -13,26 +13,27 @@ use crate::{ api::{Api, Error, Result}, rpc::Request, - utils::ToHexString, ExtrinsicParams, }; use ac_compose_macros::rpc_params; -use ac_primitives::{BalancesConfig, FeeDetails, InclusionFee, NumberOrHex, RuntimeDispatchInfo}; -use alloc::vec::Vec; +use ac_primitives::{ + BalancesConfig, Bytes, FeeDetails, InclusionFee, NumberOrHex, RuntimeDispatchInfo, +}; use core::str::FromStr; + /// Interface to common calls of the substrate transaction payment pallet. pub trait GetTransactionPayment { type Balance; fn get_fee_details( &self, - encoded_extrinsic: Vec, + encoded_extrinsic: Bytes, at_block: Option, ) -> Result>>; fn get_payment_info( &self, - encoded_extrinsic: Vec, + encoded_extrinsic: Bytes, at_block: Option, ) -> Result>>; } @@ -49,13 +50,12 @@ where fn get_fee_details( &self, - encoded_extrinsic: Vec, + encoded_extrinsic: Bytes, at_block: Option, ) -> Result>> { - let details: Option> = self.client().request( - "payment_queryFeeDetails", - rpc_params![encoded_extrinsic.to_hex(), at_block], - )?; + let details: Option> = self + .client() + .request("payment_queryFeeDetails", rpc_params![encoded_extrinsic, at_block])?; let details = match details { Some(details) => Some(convert_fee_details(details)?), @@ -66,12 +66,12 @@ where fn get_payment_info( &self, - encoded_extrinsic: Vec, + encoded_extrinsic: Bytes, at_block: Option, ) -> Result>> { let res = self .client() - .request("payment_queryInfo", rpc_params![encoded_extrinsic.to_hex(), at_block])?; + .request("payment_queryInfo", rpc_params![encoded_extrinsic, at_block])?; Ok(res) } } diff --git a/src/api/rpc_api/state.rs b/src/api/rpc_api/state.rs index 619efec75..08cbb1b7a 100644 --- a/src/api/rpc_api/state.rs +++ b/src/api/rpc_api/state.rs @@ -13,7 +13,7 @@ use crate::{ api::Result, rpc::{Request, Subscribe}, - utils, Api, MetadataError, ReadProof, + Api, MetadataError, ReadProof, }; use ac_compose_macros::rpc_params; use ac_primitives::{ @@ -306,7 +306,7 @@ where storage_key_name: &str, ) -> Result>> { debug!("subscribing to events"); - let key = utils::storage_key(pallet, storage_key_name); + let key = crate::storage_key(pallet, storage_key_name); self.client() .subscribe("state_subscribeStorage", rpc_params![vec![key]], "state_unsubscribeStorage") .map_err(|e| e.into()) diff --git a/src/lib.rs b/src/lib.rs index 2c6f4725a..fe0cb777f 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,9 +23,18 @@ pub use ac_compose_macros::*; pub use ac_node_api::*; pub use ac_primitives::*; pub use api::*; -pub use utils::*; pub mod api; pub mod extrinsic; pub mod rpc; -pub mod utils; + +use ac_primitives::StorageKey; +use sp_core::twox_128; + +/// Returns the concacenated 128 bit hash of the given module and specific storage key +/// as a full Substrate StorageKey. +pub fn storage_key(module: &str, storage_key_name: &str) -> StorageKey { + let mut key = twox_128(module.as_bytes()).to_vec(); + key.extend(twox_128(storage_key_name.as_bytes())); + StorageKey(key) +} diff --git a/src/utils.rs b/src/utils.rs deleted file mode 100644 index 31e32a073..000000000 --- a/src/utils.rs +++ /dev/null @@ -1,102 +0,0 @@ -/* - Copyright 2019 Supercomputing Systems AG - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -use ac_primitives::StorageKey; -use alloc::{string::String, vec::Vec}; -use hex::FromHexError; -use sp_core::{twox_128, H256}; - -pub fn storage_key(module: &str, storage_key_name: &str) -> StorageKey { - let mut key = twox_128(module.as_bytes()).to_vec(); - key.extend(twox_128(storage_key_name.as_bytes())); - StorageKey(key) -} - -pub trait FromHexString { - fn from_hex(hex: String) -> Result - where - Self: Sized; -} - -impl FromHexString for Vec { - fn from_hex(hex: String) -> Result { - let hexstr = hex.trim_matches('\"').trim_start_matches("0x"); - - hex::decode(hexstr) - } -} - -impl FromHexString for H256 { - fn from_hex(hex: String) -> Result { - let vec = Vec::from_hex(hex)?; - - match vec.len() { - 32 => Ok(H256::from_slice(&vec)), - _ => Err(hex::FromHexError::InvalidStringLength), - } - } -} - -pub trait ToHexString { - fn to_hex(self) -> String - where - Self: Sized; -} - -impl ToHexString for Vec { - fn to_hex(self) -> String { - let mut hex_str = hex::encode(self); - hex_str.insert_str(0, "0x"); - hex_str - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_hextstr_to_vec() { - assert_eq!(Vec::from_hex("0x01020a".to_string()), Ok(vec!(1, 2, 10))); - assert_eq!( - Vec::from_hex("null".to_string()), - Err(hex::FromHexError::InvalidHexCharacter { c: 'n', index: 0 }) - ); - assert_eq!( - Vec::from_hex("0x0q".to_string()), - Err(hex::FromHexError::InvalidHexCharacter { c: 'q', index: 1 }) - ); - } - - #[test] - fn test_hextstr_to_hash() { - assert_eq!( - H256::from_hex( - "0x0000000000000000000000000000000000000000000000000000000000000000".to_string() - ), - Ok(H256::from([0u8; 32])) - ); - assert_eq!( - H256::from_hex("0x010000000000000000".to_string()), - Err(hex::FromHexError::InvalidStringLength) - ); - assert_eq!( - H256::from_hex("0x0q".to_string()), - Err(hex::FromHexError::InvalidHexCharacter { c: 'q', index: 1 }) - ); - } -} diff --git a/testing/examples/pallet_transaction_payment_tests.rs b/testing/examples/pallet_transaction_payment_tests.rs index 2dc2d9948..10858a399 100644 --- a/testing/examples/pallet_transaction_payment_tests.rs +++ b/testing/examples/pallet_transaction_payment_tests.rs @@ -37,6 +37,9 @@ async fn main() { let encoded_xt = api.balance_transfer(GenericAddress::Id(bob), 1000000000000).encode(); // Tests - let _fee_details = api.get_fee_details(encoded_xt.clone(), Some(block_hash)).unwrap().unwrap(); - let _payment_info = api.get_payment_info(encoded_xt, Some(block_hash)).unwrap().unwrap(); + let _fee_details = api + .get_fee_details(encoded_xt.clone().into(), Some(block_hash)) + .unwrap() + .unwrap(); + let _payment_info = api.get_payment_info(encoded_xt.into(), Some(block_hash)).unwrap().unwrap(); }