From 3a1071a4fa2f1ab45065a340aafe9fb4d31dcf30 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 29 Sep 2023 15:45:59 +0100 Subject: [PATCH 01/20] Bump subxt versions --- Cargo.lock | 184 ++++++++++--------------------- crates/cargo-contract/Cargo.toml | 2 +- crates/extrinsics/Cargo.toml | 5 +- 3 files changed, 62 insertions(+), 129 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 708958f28..ed43de34a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1028,8 +1028,9 @@ dependencies = [ "contract-build", "contract-metadata", "contract-transcode", + "futures", "hex", - "jsonrpsee 0.20.1", + "jsonrpsee", "pallet-contracts-primitives", "parity-scale-codec", "predicates", @@ -2124,7 +2125,6 @@ dependencies = [ "rustls-native-certs", "tokio", "tokio-rustls", - "webpki-roots 0.23.1", ] [[package]] @@ -2530,50 +2530,19 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "jsonrpsee" -version = "0.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "367a292944c07385839818bb71c8d76611138e2dedb0677d035b8da21d29c78b" -dependencies = [ - "jsonrpsee-client-transport 0.16.3", - "jsonrpsee-core 0.16.3", - "jsonrpsee-http-client", - "jsonrpsee-types 0.16.3", -] - [[package]] name = "jsonrpsee" version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ad9b31183a8bcbe843e32ca8554ad2936633548d95a7bb6a8e14c767dea6b05" dependencies = [ - "jsonrpsee-core 0.20.1", - "jsonrpsee-types 0.20.1", + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-http-client", + "jsonrpsee-types", "jsonrpsee-ws-client", ] -[[package]] -name = "jsonrpsee-client-transport" -version = "0.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8b3815d9f5d5de348e5f162b316dc9cdf4548305ebb15b4eb9328e66cf27d7a" -dependencies = [ - "futures-util", - "http", - "jsonrpsee-core 0.16.3", - "jsonrpsee-types 0.16.3", - "pin-project", - "rustls-native-certs", - "soketto", - "thiserror", - "tokio", - "tokio-rustls", - "tokio-util", - "tracing", - "webpki-roots 0.25.2", -] - [[package]] name = "jsonrpsee-client-transport" version = "0.20.1" @@ -2582,7 +2551,7 @@ checksum = "97f2743cad51cc86b0dbfe316309eeb87a9d96a3d7f4dd7a99767c4b5f065335" dependencies = [ "futures-util", "http", - "jsonrpsee-core 0.20.1", + "jsonrpsee-core", "pin-project", "rustls-native-certs", "soketto", @@ -2594,29 +2563,6 @@ dependencies = [ "url", ] -[[package]] -name = "jsonrpsee-core" -version = "0.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b5dde66c53d6dcdc8caea1874a45632ec0fcf5b437789f1e45766a1512ce803" -dependencies = [ - "anyhow", - "async-lock", - "async-trait", - "beef", - "futures-channel", - "futures-timer", - "futures-util", - "hyper", - "jsonrpsee-types 0.16.3", - "rustc-hash", - "serde", - "serde_json", - "thiserror", - "tokio", - "tracing", -] - [[package]] name = "jsonrpsee-core" version = "0.20.1" @@ -2629,7 +2575,8 @@ dependencies = [ "beef", "futures-timer", "futures-util", - "jsonrpsee-types 0.20.1", + "hyper", + "jsonrpsee-types", "rustc-hash", "serde", "serde_json", @@ -2640,35 +2587,22 @@ dependencies = [ [[package]] name = "jsonrpsee-http-client" -version = "0.16.3" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e5f9fabdd5d79344728521bb65e3106b49ec405a78b66fbff073b72b389fa43" +checksum = "0dd865d0072764cb937b0110a92b5f53e995f7101cb346beca03d93a2dea79de" dependencies = [ "async-trait", "hyper", "hyper-rustls", - "jsonrpsee-core 0.16.3", - "jsonrpsee-types 0.16.3", - "rustc-hash", + "jsonrpsee-core", + "jsonrpsee-types", "serde", "serde_json", "thiserror", "tokio", + "tower", "tracing", -] - -[[package]] -name = "jsonrpsee-types" -version = "0.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245ba8e5aa633dd1c1e4fae72bce06e71f42d34c14a2767c6b4d173b57bee5e5" -dependencies = [ - "anyhow", - "beef", - "serde", - "serde_json", - "thiserror", - "tracing", + "url", ] [[package]] @@ -2692,9 +2626,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d88e35e9dfa89248ae3e92f689c1f0a190ce12d377eba7d2d08e5a7f6cc5694a" dependencies = [ "http", - "jsonrpsee-client-transport 0.20.1", - "jsonrpsee-core 0.20.1", - "jsonrpsee-types 0.20.1", + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", "url", ] @@ -3430,9 +3364,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] @@ -3775,7 +3709,7 @@ checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", "ring", - "rustls-webpki 0.101.4", + "rustls-webpki", "sct", ] @@ -3800,16 +3734,6 @@ dependencies = [ "base64 0.21.3", ] -[[package]] -name = "rustls-webpki" -version = "0.100.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e98ff011474fa39949b7e5c0428f9b4937eda7da7848bbb947786b7be0b27dab" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "rustls-webpki" version = "0.101.4" @@ -5038,10 +4962,11 @@ checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" [[package]] name = "subxt" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d140449e7d967b21b0ae386cdc6bd5933ade38613866bb40bb2c6df79638a4" +checksum = "86ad149b178bedc983532ed795e0024dcdcb802a7f93377172c8aa6a3429590f" dependencies = [ + "async-trait", "base58", "blake2", "derivative", @@ -5050,7 +4975,7 @@ dependencies = [ "futures", "hex", "impl-serde", - "jsonrpsee 0.16.3", + "jsonrpsee", "parity-scale-codec", "primitive-types", "scale-bits", @@ -5070,14 +4995,14 @@ dependencies = [ [[package]] name = "subxt-codegen" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9af52575d54de7b9528601788f2876b41965e3e473d137c9c61c1ac35aeeaa3b" +checksum = "b82d423038ed4e49b1b337b174c6c2a0a01d1f7d60d8094bfa2c1bce29ac41aa" dependencies = [ "frame-metadata 16.0.0", "heck", "hex", - "jsonrpsee 0.16.3", + "jsonrpsee", "parity-scale-codec", "proc-macro2", "quote", @@ -5090,9 +5015,9 @@ dependencies = [ [[package]] name = "subxt-lightclient" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aa72c1cb7e06772efa1476949c3f0e83718c79c1b2615eb510c076b012e9c84" +checksum = "5d3aba25e5309150ae74dd75badac9780814292332cfdd79827aff56b354f763" dependencies = [ "futures", "futures-util", @@ -5107,9 +5032,9 @@ dependencies = [ [[package]] name = "subxt-macro" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afe9f7e2994a20ab9748a9a040a3fe96054faa219a60ed21af51b9ab9e5f7da6" +checksum = "5a32cb896b742c5cc269a3a4da7f090f61e2b8552c7337f5e038e63a9301ea44" dependencies = [ "darling 0.20.3", "proc-macro-error", @@ -5119,9 +5044,9 @@ dependencies = [ [[package]] name = "subxt-metadata" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "880017c466f66af10e1c9b28cfa4cb2e4f59ab1bfe0b0f7250f7aca6e9d593b0" +checksum = "9928f1b9679351800285f4acab6980d2b8e04b7a6decfbf71e258ee6e74a2dc8" dependencies = [ "frame-metadata 16.0.0", "parity-scale-codec", @@ -5132,9 +5057,9 @@ dependencies = [ [[package]] name = "subxt-signer" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1e4cf3f57cb7ee062111a8f590670efb385e60cf5805054c4a7f377b2bc65d" +checksum = "cf1c1fa2b719eac18ed37d734e33f70ebb25f68920d8e951149c0d942c0879b5" dependencies = [ "bip39", "hex", @@ -5475,6 +5400,27 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -5488,6 +5434,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -6084,21 +6031,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki-roots" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" -dependencies = [ - "rustls-webpki 0.100.2", -] - -[[package]] -name = "webpki-roots" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" - [[package]] name = "which" version = "4.4.2" diff --git a/crates/cargo-contract/Cargo.toml b/crates/cargo-contract/Cargo.toml index 8b30f38d9..1d8a80382 100644 --- a/crates/cargo-contract/Cargo.toml +++ b/crates/cargo-contract/Cargo.toml @@ -39,7 +39,7 @@ semver = "1.0" # dependencies for extrinsics (deploying and calling a contract) tokio = { version = "1", features = ["macros", "rt-multi-thread"] } -subxt = "0.31.0" +subxt = "0.32.0" sp-core = "22.0.0" sp-weights = "21.0.0" pallet-contracts-primitives = "25.0.0" diff --git a/crates/extrinsics/Cargo.toml b/crates/extrinsics/Cargo.toml index fd2a9a233..2e96bad97 100644 --- a/crates/extrinsics/Cargo.toml +++ b/crates/extrinsics/Cargo.toml @@ -21,6 +21,7 @@ contract-transcode = { version = "4.0.0-alpha", path = "../transcode" } anyhow = "1.0.75" clap = { version = "4.4.5", features = ["derive", "env"] } +futures = { version = "0.3.27", default-features = false, features = ["std"] } tracing = "0.1.37" scale = { package = "parity-scale-codec", version = "3.0.0", features = ["derive"] } colored = "2.0.4" @@ -34,8 +35,8 @@ sp-runtime = "25.0.0" sp-weights = "21.0.0" pallet-contracts-primitives = "25.0.0" scale-info = "2.8.0" -subxt = "0.31.0" -subxt-signer = { version = "0.31.0", features = ["subxt", "sr25519"] } +subxt = "0.32.0" +subxt-signer = { version = "0.32.0", features = ["subxt", "sr25519"] } hex = "0.4.3" jsonrpsee = { version = "0.20.1", features = ["ws-client"] } From 9474cd423f6118ef122ae58d7ac9d52d3604a539 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 29 Sep 2023 15:46:32 +0100 Subject: [PATCH 02/20] generic bounds --- crates/extrinsics/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/extrinsics/src/lib.rs b/crates/extrinsics/src/lib.rs index ca91641a8..514f41d3a 100644 --- a/crates/extrinsics/src/lib.rs +++ b/crates/extrinsics/src/lib.rs @@ -273,7 +273,7 @@ where T: Config, Call: tx::TxPayload, Signer: tx::Signer, - >::OtherParams: Default, + >::OtherParams: Default, { client .tx() From 9f83642d1c90f44752907969b8f5c0715e56f4e6 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 2 Oct 2023 17:56:46 +0100 Subject: [PATCH 03/20] Use new storage iter api for contract info --- crates/cargo-contract/src/cmd/info.rs | 13 +-------- crates/extrinsics/src/lib.rs | 38 +++++++++++---------------- 2 files changed, 17 insertions(+), 34 deletions(-) diff --git a/crates/cargo-contract/src/cmd/info.rs b/crates/cargo-contract/src/cmd/info.rs index 9bdfa2d87..56df501a7 100644 --- a/crates/cargo-contract/src/cmd/info.rs +++ b/crates/cargo-contract/src/cmd/info.rs @@ -78,18 +78,7 @@ impl InfoCommand { if self.all { // 1000 is max allowed value const MAX_COUNT: u32 = 1000; - let mut count_from = None; - let mut contracts = Vec::new(); - loop { - let len = contracts.len(); - contracts.append( - &mut fetch_all_contracts(&client, MAX_COUNT, count_from).await?, - ); - if contracts.len() < len + MAX_COUNT as usize { - break - } - count_from = contracts.last(); - } + let contracts = fetch_all_contracts(&client, MAX_COUNT).await?; if self.output_json { let contracts_json = serde_json::json!({ diff --git a/crates/extrinsics/src/lib.rs b/crates/extrinsics/src/lib.rs index 514f41d3a..e51253831 100644 --- a/crates/extrinsics/src/lib.rs +++ b/crates/extrinsics/src/lib.rs @@ -52,10 +52,7 @@ use scale::{ Decode, Encode, }; -use sp_core::{ - hashing, - Bytes, -}; +use sp_core::Bytes; use subxt::{ blocks, config, @@ -404,27 +401,24 @@ fn parse_contract_account_address( pub async fn fetch_all_contracts( client: &Client, count: u32, - count_from: Option<&AccountId32>, ) -> Result> { - let key = api::storage() - .contracts() - .contract_info_of_root() - .to_root_bytes(); - let start_key = count_from - .map(|e| [key.clone(), hashing::twox_64(&e.0).to_vec(), e.0.to_vec()].concat()); - let keys = client - .storage() - .at_latest() - .await? - .fetch_keys(key.as_ref(), count, start_key.as_deref()) - .await?; + let query = api::storage().contracts().contract_info_of_iter(); + + let mut contracts = client.storage().at_latest().await?.iter(query).await?; - let contracts = keys - .into_iter() - .map(|e| parse_contract_account_address(&e.0, key.len())) - .collect::>()?; + let mut contract_accounts = Vec::new(); + while let Some(result) = contracts.next().await { + if contract_accounts.len() >= count as usize { + break + } + // at the moment we are ignoring the contract info itself, this could be improved + // by returning this information. + let (key, _contract_info) = result?; + let contract_account = parse_contract_account_address(&key, key.len())?; + contract_accounts.push(contract_account); + } - Ok(contracts) + Ok(contract_accounts) } // Converts a Url into a String representation without excluding the default port. From d247900b99c397e17a6c1d01a300585064b6921e Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 2 Oct 2023 18:21:18 +0100 Subject: [PATCH 04/20] Rework fetching of TokenMetadata --- crates/cargo-contract/src/cmd/call.rs | 4 +--- crates/cargo-contract/src/cmd/remove.rs | 4 +--- crates/cargo-contract/src/cmd/upload.rs | 4 +--- crates/extrinsics/src/balance.rs | 11 ++++++++--- crates/extrinsics/src/call.rs | 24 +++++++++++++++++------- crates/extrinsics/src/instantiate.rs | 13 +++++++------ crates/extrinsics/src/remove.rs | 14 +++++++++++++- crates/extrinsics/src/upload.rs | 23 +++++++++++++++++------ 8 files changed, 65 insertions(+), 32 deletions(-) diff --git a/crates/cargo-contract/src/cmd/call.rs b/crates/cargo-contract/src/cmd/call.rs index 67b7e8892..feffefd50 100644 --- a/crates/cargo-contract/src/cmd/call.rs +++ b/crates/cargo-contract/src/cmd/call.rs @@ -42,7 +42,6 @@ use contract_extrinsics::{ DefaultConfig, ExtrinsicOptsBuilder, StorageDeposit, - TokenMetadata, }; use contract_transcode::Value; use sp_weights::Weight; @@ -173,14 +172,13 @@ impl CallCommand { ); })?; } - let token_metadata = TokenMetadata::query(call_exec.client()).await?; let display_events = call_exec.call(Some(gas_limit)).await?; let output = if self.output_json() { display_events.to_json()? } else { display_events.display_events( self.extrinsic_cli_opts.verbosity().unwrap(), - &token_metadata, + &call_exec.token_metadata(), )? }; println!("{output}"); diff --git a/crates/cargo-contract/src/cmd/remove.rs b/crates/cargo-contract/src/cmd/remove.rs index 5d8557b44..67d0faec1 100644 --- a/crates/cargo-contract/src/cmd/remove.rs +++ b/crates/cargo-contract/src/cmd/remove.rs @@ -25,7 +25,6 @@ use contract_extrinsics::{ DefaultConfig, ExtrinsicOptsBuilder, RemoveCommandBuilder, - TokenMetadata, }; use subxt::Config; @@ -66,10 +65,9 @@ impl RemoveCommand { let output = if self.output_json() { display_events.to_json()? } else { - let token_metadata = TokenMetadata::query(remove_exec.client()).await?; display_events.display_events( self.extrinsic_cli_opts.verbosity().unwrap(), - &token_metadata, + &remove_exec.token_metadata(), )? }; println!("{output}"); diff --git a/crates/cargo-contract/src/cmd/upload.rs b/crates/cargo-contract/src/cmd/upload.rs index b06a0affa..293ba0013 100644 --- a/crates/cargo-contract/src/cmd/upload.rs +++ b/crates/cargo-contract/src/cmd/upload.rs @@ -26,7 +26,6 @@ use contract_build::name_value_println; use contract_extrinsics::{ Balance, ExtrinsicOptsBuilder, - TokenMetadata, UploadCommandBuilder, }; @@ -92,10 +91,9 @@ impl UploadCommand { let output = if self.output_json() { display_events.to_json()? } else { - let token_metadata = TokenMetadata::query(upload_exec.client()).await?; display_events.display_events( self.extrinsic_cli_opts.verbosity()?, - &token_metadata, + upload_exec.token_metadata(), )? }; println!("{output}"); diff --git a/crates/extrinsics/src/balance.rs b/crates/extrinsics/src/balance.rs index cae7ced0e..374bf8337 100644 --- a/crates/extrinsics/src/balance.rs +++ b/crates/extrinsics/src/balance.rs @@ -25,10 +25,14 @@ use rust_decimal::{ Decimal, }; use serde_json::json; +use subxt::backend::{ + legacy::LegacyRpcMethods, + rpc::RpcClient, +}; use super::{ Balance, - Client, + DefaultConfig, }; use anyhow::{ @@ -74,8 +78,9 @@ pub enum UnitPrefix { impl TokenMetadata { /// Query [TokenMetadata] through the node's RPC - pub async fn query(client: &Client) -> Result { - let sys_props = client.rpc().system_properties().await?; + pub async fn query(client: RpcClient) -> Result { + let legacy_rpc = LegacyRpcMethods::::new(client); + let sys_props = legacy_rpc.system_properties().await?; let default_decimals = json!(12); let default_units = json!("UNIT"); diff --git a/crates/extrinsics/src/call.rs b/crates/extrinsics/src/call.rs index 3b614883f..0946e619d 100644 --- a/crates/extrinsics/src/call.rs +++ b/crates/extrinsics/src/call.rs @@ -179,7 +179,11 @@ impl CallCommandBuilder { let signer = self.opts.extrinsic_opts.signer()?; let url = self.opts.extrinsic_opts.url(); - let client = OnlineClient::from_url(url).await?; + let rpc = subxt::backend::rpc::RpcClient::from_url(&url).await?; + let client = OnlineClient::from_rpc_client(rpc.clone()).await?; + + let token_metadata = TokenMetadata::query(rpc).await?; + Ok(CallExec { contract: self.opts.contract.clone(), message: self.opts.message.clone(), @@ -192,6 +196,7 @@ impl CallCommandBuilder { transcoder, call_data, signer, + token_metadata, }) } } @@ -208,6 +213,7 @@ pub struct CallExec { transcoder: ContractMessageTranscoder, call_data: Vec, signer: Keypair, + token_metadata: TokenMetadata, } impl CallExec { @@ -222,17 +228,16 @@ impl CallExec { /// includes information about the simulated call, or an error in case of failure. pub async fn call_dry_run(&self) -> Result> { let url = self.opts.url(); - let token_metadata = TokenMetadata::query(&self.client).await?; let storage_deposit_limit = self .opts .storage_deposit_limit() .as_ref() - .map(|bv| bv.denominate_balance(&token_metadata)) + .map(|bv| bv.denominate_balance(&self.token_metadata)) .transpose()?; let call_request = CallRequest { origin: account_id(&self.signer), dest: self.contract.clone(), - value: self.value.denominate_balance(&token_metadata)?, + value: self.value.denominate_balance(&self.token_metadata)?, gas_limit: None, storage_deposit_limit, input_data: self.call_data.clone(), @@ -258,13 +263,13 @@ impl CallExec { None => self.estimate_gas().await?, }; tracing::debug!("calling contract {:?}", self.contract); - let token_metadata = TokenMetadata::query(&self.client).await?; let call = api::tx().contracts().call( self.contract.clone().into(), - self.value.denominate_balance(&token_metadata)?, + self.value.denominate_balance(&self.token_metadata)?, gas_limit.into(), - self.opts.compact_storage_deposit_limit(&token_metadata)?, + self.opts + .compact_storage_deposit_limit(&self.token_metadata)?, self.call_data.clone(), ); @@ -372,6 +377,11 @@ impl CallExec { pub fn signer(&self) -> &Keypair { &self.signer } + + /// Returns the token metadata. + pub fn token_metadata(&self) -> &TokenMetadata { + &self.token_metadata + } } /// A struct that encodes RPC parameters required for a call to a smart contract. diff --git a/crates/extrinsics/src/instantiate.rs b/crates/extrinsics/src/instantiate.rs index b0a92c73b..61b8daefe 100644 --- a/crates/extrinsics/src/instantiate.rs +++ b/crates/extrinsics/src/instantiate.rs @@ -174,9 +174,10 @@ impl InstantiateCommandBuilder { }; let salt = self.opts.salt.clone().map(|s| s.0).unwrap_or_default(); - let client = OnlineClient::from_url(&url).await?; + let rpc = subxt::backend::rpc::RpcClient::from_url(&url).await?; + let client = OnlineClient::from_rpc_client(rpc.clone()).await?; - let token_metadata = TokenMetadata::query(&client).await?; + let token_metadata = TokenMetadata::query(rpc).await?; let args = InstantiateArgs { constructor: self.opts.constructor.clone(), @@ -203,6 +204,7 @@ impl InstantiateCommandBuilder { client, signer, transcoder, + token_metadata, }) } } @@ -272,6 +274,7 @@ pub struct InstantiateExec { client: Client, signer: Keypair, transcoder: ContractMessageTranscoder, + token_metadata: TokenMetadata, } impl InstantiateExec { @@ -370,12 +373,11 @@ impl InstantiateExec { .find_last::()? .ok_or_else(|| anyhow!("Failed to find Instantiated event"))?; - let token_metadata = TokenMetadata::query(&self.client).await?; Ok(InstantiateExecResult { result, code_hash, contract_address: instantiated.contract, - token_metadata, + token_metadata: self.token_metadata.clone(), }) } @@ -399,12 +401,11 @@ impl InstantiateExec { .find_first::()? .ok_or_else(|| anyhow!("Failed to find Instantiated event"))?; - let token_metadata = TokenMetadata::query(&self.client).await?; Ok(InstantiateExecResult { result, code_hash: None, contract_address: instantiated.contract, - token_metadata, + token_metadata: self.token_metadata.clone(), }) } diff --git a/crates/extrinsics/src/remove.rs b/crates/extrinsics/src/remove.rs index 46efd23cc..e8af54130 100644 --- a/crates/extrinsics/src/remove.rs +++ b/crates/extrinsics/src/remove.rs @@ -27,6 +27,7 @@ use super::{ DefaultConfig, ErrorVariant, Missing, + TokenMetadata, }; use crate::extrinsic_opts::ExtrinsicOpts; use anyhow::Result; @@ -118,8 +119,12 @@ impl RemoveCommandBuilder { artifacts_path.display() )), }?; + let url = self.opts.extrinsic_opts.url(); - let client = OnlineClient::from_url(url).await?; + let rpc = subxt::backend::rpc::RpcClient::from_url(&url).await?; + let client = OnlineClient::from_rpc_client(rpc.clone()).await?; + + let token_metadata = TokenMetadata::query(rpc).await?; Ok(RemoveExec { final_code_hash, @@ -127,6 +132,7 @@ impl RemoveCommandBuilder { client, transcoder, signer, + token_metadata, }) } } @@ -137,6 +143,7 @@ pub struct RemoveExec { client: Client, transcoder: ContractMessageTranscoder, signer: Keypair, + token_metadata: TokenMetadata, } impl RemoveExec { @@ -193,6 +200,11 @@ impl RemoveExec { pub fn signer(&self) -> &Keypair { &self.signer } + + /// Returns the token metadata. + pub fn token_metadata(&self) -> &TokenMetadata { + &self.token_metadata + } } pub struct RemoveResult { diff --git a/crates/extrinsics/src/upload.rs b/crates/extrinsics/src/upload.rs index 55c0e9702..fc5b6fd0c 100644 --- a/crates/extrinsics/src/upload.rs +++ b/crates/extrinsics/src/upload.rs @@ -105,13 +105,19 @@ impl UploadCommandBuilder { artifacts_path.display() ) })?; + let url = self.opts.extrinsic_opts.url(); - let client = OnlineClient::from_url(url).await?; + let rpc = subxt::backend::rpc::RpcClient::from_url(&url).await?; + let client = OnlineClient::from_rpc_client(rpc.clone()).await?; + + let token_metadata = TokenMetadata::query(rpc).await?; + Ok(UploadExec { opts: self.opts.extrinsic_opts.clone(), client, code, signer, + token_metadata, }) } } @@ -121,6 +127,7 @@ pub struct UploadExec { client: Client, code: WasmCode, signer: Keypair, + token_metadata: TokenMetadata, } impl UploadExec { @@ -132,12 +139,11 @@ impl UploadExec { /// the state of the blockchain. pub async fn upload_code_rpc(&self) -> Result> { let url = self.opts.url(); - let token_metadata = TokenMetadata::query(&self.client).await?; let storage_deposit_limit = self .opts .storage_deposit_limit() .as_ref() - .map(|bv| bv.denominate_balance(&token_metadata)) + .map(|bv| bv.denominate_balance(&self.token_metadata)) .transpose()?; let call_request = CodeUploadRequest { origin: account_id(&self.signer), @@ -155,9 +161,9 @@ impl UploadExec { /// The function handles the necessary interactions with the blockchain's runtime /// API to ensure the successful upload of the code. pub async fn upload_code(&self) -> Result { - let token_metadata = TokenMetadata::query(&self.client).await?; - let storage_deposit_limit = - self.opts.compact_storage_deposit_limit(&token_metadata)?; + let storage_deposit_limit = self + .opts + .compact_storage_deposit_limit(&self.token_metadata)?; let call = crate::runtime_api::api::tx().contracts().upload_code( self.code.0.clone(), storage_deposit_limit, @@ -194,6 +200,11 @@ impl UploadExec { pub fn signer(&self) -> &Keypair { &self.signer } + + /// Returns the token metadata. + pub fn token_metadata(&self) -> &TokenMetadata { + &self.token_metadata + } } /// A struct that encodes RPC parameters required for a call to upload a new code. From d3adbfdcb75974301f477b8b81dfeafd11858d60 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 2 Oct 2023 18:23:26 +0100 Subject: [PATCH 05/20] CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14c868d15..162813adf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add `--binary` flag for `info` command - [#1311](https://github.com/paritytech/cargo-contract/pull/1311/) - Add `--all` flag for `info` command - [#1319](https://github.com/paritytech/cargo-contract/pull/1319) - Fix for a Url to String conversion in `info` command - [#1330](https://github.com/paritytech/cargo-contract/pull/1330) +- Bump `subxt` to `0.32.0` - [#1352](https://github.com/paritytech/cargo-contract/pull/1352) ## [4.0.0-alpha] From a2793ebeec2c29b8a8c7cd742332df5b37999ed6 Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 3 Oct 2023 09:54:49 +0100 Subject: [PATCH 06/20] WIP --- crates/extrinsics/src/lib.rs | 50 +++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/crates/extrinsics/src/lib.rs b/crates/extrinsics/src/lib.rs index e51253831..1f3b8d836 100644 --- a/crates/extrinsics/src/lib.rs +++ b/crates/extrinsics/src/lib.rs @@ -54,6 +54,9 @@ use scale::{ }; use sp_core::Bytes; use subxt::{ + backend::{ + rpc::RpcClient + }, blocks, config, tx, @@ -66,6 +69,7 @@ use std::{ option::Option, path::Path, }; +use subxt::backend::legacy::LegacyRpcMethods; pub use balance::{ BalanceVariant, @@ -263,6 +267,7 @@ pub fn account_id(keypair: &Keypair) -> AccountId32 { /// future there could be a flag to wait for finality before reporting success. async fn submit_extrinsic( client: &OnlineClient, + rpc: RpcClient, call: &Call, signer: &Signer, ) -> core::result::Result, subxt::Error> @@ -282,10 +287,47 @@ where .await } -async fn state_call(url: &str, func: &str, args: A) -> Result { - let cli = WsClientBuilder::default().build(&url).await?; - let params = rpc_params![func, Bytes(args.encode())]; - let bytes: Bytes = cli.request("state_call", params).await?; +/// Return the account nonce at the *best* block for an account ID. +/// +/// Replace this with the new `account_id` query available in the next `subxt` +/// release. +async fn get_account_nonce( + client: &OnlineClient, + rpc: RpcClient, + account_id: &T::AccountId, +) -> Result +where + T: Config +{ + let rpc = LegacyRpcMethods::::new(rpc); + let best_block = rpc.chain_get_block_hash(None)?; + let account_nonce_bytes = self + .client + .backend() + .call( + "AccountNonceApi_account_nonce", + Some(&scale::Encode::encode(&account_id)), + best_block, + ) + .await?; + + // custom decoding from a u16/u32/u64 into a u64, based on the number of bytes we + // got back. + let cursor = &mut &account_nonce_bytes[..]; + let account_nonce: u64 = match account_nonce_bytes.len() { + 2 => ::decode(cursor)?.into(), + 4 => ::decode(cursor)?.into(), + 8 => ::decode(cursor)?, + _ => return Err(subxt::Error::Decode(subxt::error::DecodeError::custom_string(format!("state call AccountNonceApi_account_nonce returned an unexpected number of bytes: {} (expected 2, 4 or 8)", account_nonce_bytes.len())))) + }; + Ok(account_nonce) +} + + +async fn state_call(rpc: RpcClient, func: &str, args: A) -> Result { + let cli = subxt::backend::legacy::LegacyRpcMethods::::new(rpc); + let params = args.encode(); + let bytes = cli.state_call(func, Some(¶ms), None).await?; Ok(R::decode(&mut bytes.as_ref())?) } From af4aa9892fd336c328eb78186f6042fdc1bfceb1 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 3 Oct 2023 12:38:44 +0100 Subject: [PATCH 07/20] Fetch nonce from best_block --- Cargo.lock | 15 ------------ crates/extrinsics/Cargo.toml | 1 - crates/extrinsics/src/call.rs | 13 ++++++---- crates/extrinsics/src/instantiate.rs | 13 ++++++---- crates/extrinsics/src/lib.rs | 36 ++++++++++++++-------------- crates/extrinsics/src/remove.rs | 8 +++++-- crates/extrinsics/src/upload.rs | 16 +++++++------ 7 files changed, 50 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 06414cde1..7560269aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1030,7 +1030,6 @@ dependencies = [ "contract-transcode", "futures", "hex", - "jsonrpsee", "pallet-contracts-primitives", "parity-scale-codec", "predicates", @@ -2540,7 +2539,6 @@ dependencies = [ "jsonrpsee-core", "jsonrpsee-http-client", "jsonrpsee-types", - "jsonrpsee-ws-client", ] [[package]] @@ -2619,19 +2617,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "jsonrpsee-ws-client" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d88e35e9dfa89248ae3e92f689c1f0a190ce12d377eba7d2d08e5a7f6cc5694a" -dependencies = [ - "http", - "jsonrpsee-client-transport", - "jsonrpsee-core", - "jsonrpsee-types", - "url", -] - [[package]] name = "keccak" version = "0.1.4" diff --git a/crates/extrinsics/Cargo.toml b/crates/extrinsics/Cargo.toml index 809c95fa8..a07624c9b 100644 --- a/crates/extrinsics/Cargo.toml +++ b/crates/extrinsics/Cargo.toml @@ -38,7 +38,6 @@ scale-info = "2.8.0" subxt = "0.32.0" subxt-signer = { version = "0.32.0", features = ["subxt", "sr25519"] } hex = "0.4.3" -jsonrpsee = { version = "0.20.1", features = ["ws-client"] } [dev-dependencies] assert_cmd = "2.0.12" diff --git a/crates/extrinsics/src/call.rs b/crates/extrinsics/src/call.rs index 0946e619d..e2001c669 100644 --- a/crates/extrinsics/src/call.rs +++ b/crates/extrinsics/src/call.rs @@ -44,6 +44,7 @@ use subxt_signer::sr25519::Keypair; use core::marker::PhantomData; use subxt::{ + backend::rpc::RpcClient, Config, OnlineClient, }; @@ -179,10 +180,10 @@ impl CallCommandBuilder { let signer = self.opts.extrinsic_opts.signer()?; let url = self.opts.extrinsic_opts.url(); - let rpc = subxt::backend::rpc::RpcClient::from_url(&url).await?; + let rpc = RpcClient::from_url(&url).await?; let client = OnlineClient::from_rpc_client(rpc.clone()).await?; - let token_metadata = TokenMetadata::query(rpc).await?; + let token_metadata = TokenMetadata::query(rpc.clone()).await?; Ok(CallExec { contract: self.opts.contract.clone(), @@ -192,6 +193,7 @@ impl CallCommandBuilder { gas_limit: self.opts.gas_limit, proof_size: self.opts.proof_size, value: self.opts.value.clone(), + rpc, client, transcoder, call_data, @@ -209,6 +211,7 @@ pub struct CallExec { gas_limit: Option, proof_size: Option, value: BalanceVariant, + rpc: RpcClient, client: Client, transcoder: ContractMessageTranscoder, call_data: Vec, @@ -227,7 +230,6 @@ impl CallExec { /// Returns the dry run simulation result of type [`ContractExecResult`], which /// includes information about the simulated call, or an error in case of failure. pub async fn call_dry_run(&self) -> Result> { - let url = self.opts.url(); let storage_deposit_limit = self .opts .storage_deposit_limit() @@ -242,7 +244,7 @@ impl CallExec { storage_deposit_limit, input_data: self.call_data.clone(), }; - state_call(&url, "ContractsApi_call", call_request).await + state_call(self.rpc.clone(), "ContractsApi_call", call_request).await } /// Calls a contract on the blockchain with a specified gas limit. @@ -273,7 +275,8 @@ impl CallExec { self.call_data.clone(), ); - let result = submit_extrinsic(&self.client, &call, &self.signer).await?; + let result = + submit_extrinsic(&self.client, self.rpc.clone(), &call, &self.signer).await?; let display_events = DisplayEvents::from_events( &result, diff --git a/crates/extrinsics/src/instantiate.rs b/crates/extrinsics/src/instantiate.rs index 61b8daefe..203cb2086 100644 --- a/crates/extrinsics/src/instantiate.rs +++ b/crates/extrinsics/src/instantiate.rs @@ -47,6 +47,7 @@ use scale::Encode; use sp_core::Bytes; use sp_weights::Weight; use subxt::{ + backend::rpc::RpcClient, blocks::ExtrinsicEvents, Config, OnlineClient, @@ -177,7 +178,7 @@ impl InstantiateCommandBuilder { let rpc = subxt::backend::rpc::RpcClient::from_url(&url).await?; let client = OnlineClient::from_rpc_client(rpc.clone()).await?; - let token_metadata = TokenMetadata::query(rpc).await?; + let token_metadata = TokenMetadata::query(rpc.clone()).await?; let args = InstantiateArgs { constructor: self.opts.constructor.clone(), @@ -201,6 +202,7 @@ impl InstantiateCommandBuilder { args, opts: self.opts.extrinsic_opts.clone(), url, + rpc, client, signer, transcoder, @@ -271,6 +273,7 @@ pub struct InstantiateExec { opts: ExtrinsicOpts, args: InstantiateArgs, url: String, + rpc: RpcClient, client: Client, signer: Keypair, transcoder: ContractMessageTranscoder, @@ -344,7 +347,7 @@ impl InstantiateExec { data: self.args.data.clone(), salt: self.args.salt.clone(), }; - state_call(&self.url, "ContractsApi_instantiate", &call_request).await + state_call(self.rpc.clone(), "ContractsApi_instantiate", &call_request).await } async fn instantiate_with_code( @@ -361,7 +364,8 @@ impl InstantiateExec { self.args.salt.clone(), ); - let result = submit_extrinsic(&self.client, &call, &self.signer).await?; + let result = + submit_extrinsic(&self.client, self.rpc.clone(), &call, &self.signer).await?; // The CodeStored event is only raised if the contract has not already been // uploaded. @@ -395,7 +399,8 @@ impl InstantiateExec { self.args.salt.clone(), ); - let result = submit_extrinsic(&self.client, &call, &self.signer).await?; + let result = + submit_extrinsic(&self.client, self.rpc.clone(), &call, &self.signer).await?; let instantiated = result .find_first::()? diff --git a/crates/extrinsics/src/lib.rs b/crates/extrinsics/src/lib.rs index 1f3b8d836..ea3484a6e 100644 --- a/crates/extrinsics/src/lib.rs +++ b/crates/extrinsics/src/lib.rs @@ -33,14 +33,8 @@ use subxt::utils::AccountId32; use anyhow::{ anyhow, Context, - Ok, Result, }; -use jsonrpsee::{ - core::client::ClientT, - rpc_params, - ws_client::WsClientBuilder, -}; use std::path::PathBuf; use crate::runtime_api::api; @@ -52,11 +46,8 @@ use scale::{ Decode, Encode, }; -use sp_core::Bytes; use subxt::{ - backend::{ - rpc::RpcClient - }, + backend::rpc::RpcClient, blocks, config, tx, @@ -277,9 +268,13 @@ where Signer: tx::Signer, >::OtherParams: Default, { + let account_id = Signer::account_id(signer); + let account_nonce = get_account_nonce(client, rpc, &account_id).await?; + client .tx() - .sign_and_submit_then_watch_default(call, signer) + .create_signed_with_nonce(call, signer, account_nonce, Default::default())? + .submit_and_watch() .await? .wait_for_in_block() .await? @@ -295,14 +290,16 @@ async fn get_account_nonce( client: &OnlineClient, rpc: RpcClient, account_id: &T::AccountId, -) -> Result +) -> core::result::Result where - T: Config + T: Config, { let rpc = LegacyRpcMethods::::new(rpc); - let best_block = rpc.chain_get_block_hash(None)?; - let account_nonce_bytes = self - .client + let best_block = rpc + .chain_get_block_hash(None) + .await? + .ok_or(subxt::Error::Other("Best block not found".into()))?; + let account_nonce_bytes = client .backend() .call( "AccountNonceApi_account_nonce", @@ -323,8 +320,11 @@ where Ok(account_nonce) } - -async fn state_call(rpc: RpcClient, func: &str, args: A) -> Result { +async fn state_call( + rpc: RpcClient, + func: &str, + args: A, +) -> Result { let cli = subxt::backend::legacy::LegacyRpcMethods::::new(rpc); let params = args.encode(); let bytes = cli.state_call(func, Some(¶ms), None).await?; diff --git a/crates/extrinsics/src/remove.rs b/crates/extrinsics/src/remove.rs index e8af54130..2d936f5a2 100644 --- a/crates/extrinsics/src/remove.rs +++ b/crates/extrinsics/src/remove.rs @@ -33,6 +33,7 @@ use crate::extrinsic_opts::ExtrinsicOpts; use anyhow::Result; use core::marker::PhantomData; use subxt::{ + backend::rpc::RpcClient, Config, OnlineClient, }; @@ -124,11 +125,12 @@ impl RemoveCommandBuilder { let rpc = subxt::backend::rpc::RpcClient::from_url(&url).await?; let client = OnlineClient::from_rpc_client(rpc.clone()).await?; - let token_metadata = TokenMetadata::query(rpc).await?; + let token_metadata = TokenMetadata::query(rpc.clone()).await?; Ok(RemoveExec { final_code_hash, opts: self.opts.extrinsic_opts.clone(), + rpc, client, transcoder, signer, @@ -140,6 +142,7 @@ impl RemoveCommandBuilder { pub struct RemoveExec { final_code_hash: [u8; 32], opts: ExtrinsicOpts, + rpc: RpcClient, client: Client, transcoder: ContractMessageTranscoder, signer: Keypair, @@ -162,7 +165,8 @@ impl RemoveExec { .contracts() .remove_code(sp_core::H256(code_hash.0)); - let result = submit_extrinsic(&self.client, &call, &self.signer).await?; + let result = + submit_extrinsic(&self.client, self.rpc.clone(), &call, &self.signer).await?; let display_events = DisplayEvents::from_events( &result, Some(&self.transcoder), diff --git a/crates/extrinsics/src/upload.rs b/crates/extrinsics/src/upload.rs index fc5b6fd0c..923aa0cd5 100644 --- a/crates/extrinsics/src/upload.rs +++ b/crates/extrinsics/src/upload.rs @@ -18,7 +18,6 @@ use super::{ account_id, events::DisplayEvents, runtime_api::api::{ - self, contracts::events::CodeStored, runtime_types::pallet_contracts::wasm::Determinism, }, @@ -40,6 +39,7 @@ use core::marker::PhantomData; use pallet_contracts_primitives::CodeUploadResult; use scale::Encode; use subxt::{ + backend::rpc::RpcClient, Config, OnlineClient, }; @@ -107,13 +107,14 @@ impl UploadCommandBuilder { })?; let url = self.opts.extrinsic_opts.url(); - let rpc = subxt::backend::rpc::RpcClient::from_url(&url).await?; + let rpc = RpcClient::from_url(&url).await?; let client = OnlineClient::from_rpc_client(rpc.clone()).await?; - let token_metadata = TokenMetadata::query(rpc).await?; + let token_metadata = TokenMetadata::query(rpc.clone()).await?; Ok(UploadExec { opts: self.opts.extrinsic_opts.clone(), + rpc, client, code, signer, @@ -124,6 +125,7 @@ impl UploadCommandBuilder { pub struct UploadExec { opts: ExtrinsicOpts, + rpc: RpcClient, client: Client, code: WasmCode, signer: Keypair, @@ -138,7 +140,6 @@ impl UploadExec { /// then sends the request using the provided URL. This operation does not modify /// the state of the blockchain. pub async fn upload_code_rpc(&self) -> Result> { - let url = self.opts.url(); let storage_deposit_limit = self .opts .storage_deposit_limit() @@ -151,7 +152,7 @@ impl UploadExec { storage_deposit_limit, determinism: Determinism::Enforced, }; - state_call(&url, "ContractsApi_upload_code", call_request).await + state_call(self.rpc.clone(), "ContractsApi_upload_code", call_request).await } /// Uploads contract code to the blockchain with specified options. @@ -170,11 +171,12 @@ impl UploadExec { Determinism::Enforced, ); - let result = submit_extrinsic(&self.client, &call, &self.signer).await?; + let result = + submit_extrinsic(&self.client, self.rpc.clone(), &call, &self.signer).await?; let display_events = DisplayEvents::from_events(&result, None, &self.client.metadata())?; - let code_stored = result.find_first::()?; + let code_stored = result.find_first::()?; Ok(UploadResult { code_stored, display_events, From 25f90005967761ca524ab9aeebbe86559debc1da Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 3 Oct 2023 12:53:07 +0100 Subject: [PATCH 08/20] Clippy --- crates/cargo-contract/src/cmd/call.rs | 2 +- crates/cargo-contract/src/cmd/remove.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/cargo-contract/src/cmd/call.rs b/crates/cargo-contract/src/cmd/call.rs index feffefd50..89fc3645b 100644 --- a/crates/cargo-contract/src/cmd/call.rs +++ b/crates/cargo-contract/src/cmd/call.rs @@ -178,7 +178,7 @@ impl CallCommand { } else { display_events.display_events( self.extrinsic_cli_opts.verbosity().unwrap(), - &call_exec.token_metadata(), + call_exec.token_metadata(), )? }; println!("{output}"); diff --git a/crates/cargo-contract/src/cmd/remove.rs b/crates/cargo-contract/src/cmd/remove.rs index 67d0faec1..eefecddf0 100644 --- a/crates/cargo-contract/src/cmd/remove.rs +++ b/crates/cargo-contract/src/cmd/remove.rs @@ -67,7 +67,7 @@ impl RemoveCommand { } else { display_events.display_events( self.extrinsic_cli_opts.verbosity().unwrap(), - &remove_exec.token_metadata(), + remove_exec.token_metadata(), )? }; println!("{output}"); From 0afbdde20973dc8dcf474cd0a39f61f9f3323c05 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 3 Oct 2023 13:14:57 +0100 Subject: [PATCH 09/20] Fetch storage at best block --- crates/cargo-contract/src/cmd/info.rs | 22 +++++++++++----------- crates/extrinsics/src/lib.rs | 25 ++++++++++++++++++++----- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/crates/cargo-contract/src/cmd/info.rs b/crates/cargo-contract/src/cmd/info.rs index 56df501a7..ac430faf8 100644 --- a/crates/cargo-contract/src/cmd/info.rs +++ b/crates/cargo-contract/src/cmd/info.rs @@ -35,6 +35,7 @@ use std::{ io::Write, }; use subxt::{ + backend::rpc::RpcClient, Config, OnlineClient, }; @@ -71,14 +72,14 @@ pub struct InfoCommand { impl InfoCommand { pub async fn run(&self) -> Result<(), ErrorVariant> { - let client = - OnlineClient::::from_url(url_to_string(&self.url)).await?; + let rpc = RpcClient::from_url(url_to_string(&self.url)).await?; + let client = OnlineClient::::from_rpc_client(rpc.clone()).await?; // All flag applied if self.all { // 1000 is max allowed value const MAX_COUNT: u32 = 1000; - let contracts = fetch_all_contracts(&client, MAX_COUNT).await?; + let contracts = fetch_all_contracts(&client, rpc, MAX_COUNT).await?; if self.output_json { let contracts_json = serde_json::json!({ @@ -97,17 +98,16 @@ impl InfoCommand { .as_ref() .expect("Contract argument was not provided"); - let info_to_json = - fetch_contract_info(contract, &client) - .await? - .ok_or(anyhow!( - "No contract information was found for account id {}", - contract - ))?; + let info_to_json = fetch_contract_info(contract, rpc.clone(), &client) + .await? + .ok_or(anyhow!( + "No contract information was found for account id {}", + contract + ))?; // Binary flag applied if self.binary { - let wasm_code = fetch_wasm_code(&client, info_to_json.code_hash()) + let wasm_code = fetch_wasm_code(&client, rpc, info_to_json.code_hash()) .await? .ok_or(anyhow!( "Contract wasm code was not found for account id {}", diff --git a/crates/extrinsics/src/lib.rs b/crates/extrinsics/src/lib.rs index ea3484a6e..a2a648eeb 100644 --- a/crates/extrinsics/src/lib.rs +++ b/crates/extrinsics/src/lib.rs @@ -342,17 +342,29 @@ pub fn parse_code_hash(input: &str) -> Result<::Hash> { Ok(arr.into()) } +/// Fetch the hash of the *best* block (included but not guaranteed to be finalized). +async fn get_best_block( + rpc: RpcClient, +) -> core::result::Result<::Hash, subxt::Error> { + let rpc = LegacyRpcMethods::::new(rpc); + rpc.chain_get_block_hash(None) + .await? + .ok_or(subxt::Error::Other("Best block not found".into())) +} + /// Fetch the contract info from the storage using the provided client. pub async fn fetch_contract_info( contract: &AccountId32, + rpc: RpcClient, client: &Client, ) -> Result> { let info_contract_call = api::storage().contracts().contract_info_of(contract); + let best_block = get_best_block(rpc).await?; + let contract_info_of = client .storage() - .at_latest() - .await? + .at(best_block) .fetch(&info_contract_call) .await?; @@ -408,14 +420,15 @@ impl ContractInfo { /// Fetch the contract wasm code from the storage using the provided client and code hash. pub async fn fetch_wasm_code( client: &Client, + rpc: RpcClient, hash: &CodeHash, ) -> Result>> { let pristine_code_address = api::storage().contracts().pristine_code(hash); + let best_block = get_best_block(rpc).await?; let pristine_bytes = client .storage() - .at_latest() - .await? + .at(best_block) .fetch(&pristine_code_address) .await? .map(|v| v.0); @@ -442,11 +455,13 @@ fn parse_contract_account_address( /// requested elements starting from an optional address pub async fn fetch_all_contracts( client: &Client, + rpc: RpcClient, count: u32, ) -> Result> { let query = api::storage().contracts().contract_info_of_iter(); - let mut contracts = client.storage().at_latest().await?.iter(query).await?; + let best_block = get_best_block(rpc).await?; + let mut contracts = client.storage().at(best_block).iter(query).await?; let mut contract_accounts = Vec::new(); while let Some(result) = contracts.next().await { From a4e8e9e4e6cffc9dcc8096aa518f92b74a955e2e Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 3 Oct 2023 13:54:46 +0100 Subject: [PATCH 10/20] Fix key resolution --- crates/extrinsics/src/lib.rs | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/crates/extrinsics/src/lib.rs b/crates/extrinsics/src/lib.rs index a2a648eeb..b51699674 100644 --- a/crates/extrinsics/src/lib.rs +++ b/crates/extrinsics/src/lib.rs @@ -436,21 +436,6 @@ pub async fn fetch_wasm_code( Ok(pristine_bytes) } -/// Parse a contract account address from a storage key. Returns error if a key is -/// malformated. -fn parse_contract_account_address( - storage_contract_account_key: &[u8], - storage_contract_root_key_len: usize, -) -> Result { - // storage_contract_account_key is a concatenation of contract_info_of root key and - // Twox64Concat(AccountId) - let mut account = storage_contract_account_key - .get(storage_contract_root_key_len + 8..) - .ok_or(anyhow!("Unexpected storage key size"))?; - AccountId32::decode(&mut account) - .map_err(|err| anyhow!("AccountId deserialization error: {}", err)) -} - /// Fetch all contract addresses from the storage using the provided client and count of /// requested elements starting from an optional address pub async fn fetch_all_contracts( @@ -471,7 +456,8 @@ pub async fn fetch_all_contracts( // at the moment we are ignoring the contract info itself, this could be improved // by returning this information. let (key, _contract_info) = result?; - let contract_account = parse_contract_account_address(&key, key.len())?; + let contract_account = AccountId32::decode(&mut &key[..]) + .map_err(|err| anyhow!("AccountId deserialization error: {}", err))?; contract_accounts.push(contract_account); } From a189114e85444c4f8766a1f3411167cbcb1c6592 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 3 Oct 2023 14:47:56 +0100 Subject: [PATCH 11/20] Revert "Fix key resolution" This reverts commit a4e8e9e4e6cffc9dcc8096aa518f92b74a955e2e. --- crates/extrinsics/src/lib.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/crates/extrinsics/src/lib.rs b/crates/extrinsics/src/lib.rs index b51699674..a2a648eeb 100644 --- a/crates/extrinsics/src/lib.rs +++ b/crates/extrinsics/src/lib.rs @@ -436,6 +436,21 @@ pub async fn fetch_wasm_code( Ok(pristine_bytes) } +/// Parse a contract account address from a storage key. Returns error if a key is +/// malformated. +fn parse_contract_account_address( + storage_contract_account_key: &[u8], + storage_contract_root_key_len: usize, +) -> Result { + // storage_contract_account_key is a concatenation of contract_info_of root key and + // Twox64Concat(AccountId) + let mut account = storage_contract_account_key + .get(storage_contract_root_key_len + 8..) + .ok_or(anyhow!("Unexpected storage key size"))?; + AccountId32::decode(&mut account) + .map_err(|err| anyhow!("AccountId deserialization error: {}", err)) +} + /// Fetch all contract addresses from the storage using the provided client and count of /// requested elements starting from an optional address pub async fn fetch_all_contracts( @@ -456,8 +471,7 @@ pub async fn fetch_all_contracts( // at the moment we are ignoring the contract info itself, this could be improved // by returning this information. let (key, _contract_info) = result?; - let contract_account = AccountId32::decode(&mut &key[..]) - .map_err(|err| anyhow!("AccountId deserialization error: {}", err))?; + let contract_account = parse_contract_account_address(&key, key.len())?; contract_accounts.push(contract_account); } From cf4d4b818823a542c8c4156bd3d5fa85146eb322 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 3 Oct 2023 15:04:41 +0100 Subject: [PATCH 12/20] Fix contract info --all --- crates/extrinsics/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/extrinsics/src/lib.rs b/crates/extrinsics/src/lib.rs index a2a648eeb..4f6c73ad4 100644 --- a/crates/extrinsics/src/lib.rs +++ b/crates/extrinsics/src/lib.rs @@ -459,6 +459,7 @@ pub async fn fetch_all_contracts( count: u32, ) -> Result> { let query = api::storage().contracts().contract_info_of_iter(); + let root_key = query.to_root_bytes(); let best_block = get_best_block(rpc).await?; let mut contracts = client.storage().at(best_block).iter(query).await?; @@ -471,7 +472,7 @@ pub async fn fetch_all_contracts( // at the moment we are ignoring the contract info itself, this could be improved // by returning this information. let (key, _contract_info) = result?; - let contract_account = parse_contract_account_address(&key, key.len())?; + let contract_account = parse_contract_account_address(&key, root_key.len())?; contract_accounts.push(contract_account); } From 99bb1872413d7e52a7d38d0cd95d63ca825dec64 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 4 Oct 2023 10:00:50 +0100 Subject: [PATCH 13/20] Update crates/extrinsics/src/lib.rs Co-authored-by: Sebastian Miasojed --- crates/extrinsics/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/extrinsics/src/lib.rs b/crates/extrinsics/src/lib.rs index 4f6c73ad4..c50bec34a 100644 --- a/crates/extrinsics/src/lib.rs +++ b/crates/extrinsics/src/lib.rs @@ -325,7 +325,7 @@ async fn state_call( func: &str, args: A, ) -> Result { - let cli = subxt::backend::legacy::LegacyRpcMethods::::new(rpc); + let cli = LegacyRpcMethods::::new(rpc); let params = args.encode(); let bytes = cli.state_call(func, Some(¶ms), None).await?; Ok(R::decode(&mut bytes.as_ref())?) From bebcf291915b5888c94d5588062f6e92685732d0 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 4 Oct 2023 10:36:24 +0100 Subject: [PATCH 14/20] Only fetch keys --- crates/extrinsics/src/lib.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/crates/extrinsics/src/lib.rs b/crates/extrinsics/src/lib.rs index c50bec34a..6f1c2c90d 100644 --- a/crates/extrinsics/src/lib.rs +++ b/crates/extrinsics/src/lib.rs @@ -458,20 +458,24 @@ pub async fn fetch_all_contracts( rpc: RpcClient, count: u32, ) -> Result> { - let query = api::storage().contracts().contract_info_of_iter(); - let root_key = query.to_root_bytes(); + let root_key = api::storage() + .contracts() + .contract_info_of_iter() + .to_root_bytes(); let best_block = get_best_block(rpc).await?; - let mut contracts = client.storage().at(best_block).iter(query).await?; + let mut keys = client + .storage() + .at(best_block) + .fetch_raw_keys(root_key.clone()) + .await?; let mut contract_accounts = Vec::new(); - while let Some(result) = contracts.next().await { + while let Some(result) = keys.next().await { if contract_accounts.len() >= count as usize { break } - // at the moment we are ignoring the contract info itself, this could be improved - // by returning this information. - let (key, _contract_info) = result?; + let key = result?; let contract_account = parse_contract_account_address(&key, root_key.len())?; contract_accounts.push(contract_account); } From 1ced4bb6a7a74c19500731bd717db8e22941ed6b Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 4 Oct 2023 10:39:51 +0100 Subject: [PATCH 15/20] Remove count --- crates/cargo-contract/src/cmd/info.rs | 4 +--- crates/extrinsics/src/lib.rs | 4 ---- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/crates/cargo-contract/src/cmd/info.rs b/crates/cargo-contract/src/cmd/info.rs index ac430faf8..aff22927d 100644 --- a/crates/cargo-contract/src/cmd/info.rs +++ b/crates/cargo-contract/src/cmd/info.rs @@ -77,9 +77,7 @@ impl InfoCommand { // All flag applied if self.all { - // 1000 is max allowed value - const MAX_COUNT: u32 = 1000; - let contracts = fetch_all_contracts(&client, rpc, MAX_COUNT).await?; + let contracts = fetch_all_contracts(&client, rpc).await?; if self.output_json { let contracts_json = serde_json::json!({ diff --git a/crates/extrinsics/src/lib.rs b/crates/extrinsics/src/lib.rs index 6f1c2c90d..c957dd7e9 100644 --- a/crates/extrinsics/src/lib.rs +++ b/crates/extrinsics/src/lib.rs @@ -456,7 +456,6 @@ fn parse_contract_account_address( pub async fn fetch_all_contracts( client: &Client, rpc: RpcClient, - count: u32, ) -> Result> { let root_key = api::storage() .contracts() @@ -472,9 +471,6 @@ pub async fn fetch_all_contracts( let mut contract_accounts = Vec::new(); while let Some(result) = keys.next().await { - if contract_accounts.len() >= count as usize { - break - } let key = result?; let contract_account = parse_contract_account_address(&key, root_key.len())?; contract_accounts.push(contract_account); From 6d251a99609826276dbc8defc278a6ec6d37bb13 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 4 Oct 2023 11:17:33 +0100 Subject: [PATCH 16/20] Construct LegacyRpcMethods up front --- crates/extrinsics/src/balance.rs | 10 +++------- crates/extrinsics/src/call.rs | 12 ++++++++---- crates/extrinsics/src/instantiate.rs | 18 +++++++++++------- crates/extrinsics/src/lib.rs | 10 ++++------ crates/extrinsics/src/remove.rs | 16 ++++++++++------ crates/extrinsics/src/upload.rs | 16 ++++++++++------ 6 files changed, 46 insertions(+), 36 deletions(-) diff --git a/crates/extrinsics/src/balance.rs b/crates/extrinsics/src/balance.rs index 374bf8337..025238378 100644 --- a/crates/extrinsics/src/balance.rs +++ b/crates/extrinsics/src/balance.rs @@ -25,10 +25,7 @@ use rust_decimal::{ Decimal, }; use serde_json::json; -use subxt::backend::{ - legacy::LegacyRpcMethods, - rpc::RpcClient, -}; +use subxt::backend::legacy::LegacyRpcMethods; use super::{ Balance, @@ -78,9 +75,8 @@ pub enum UnitPrefix { impl TokenMetadata { /// Query [TokenMetadata] through the node's RPC - pub async fn query(client: RpcClient) -> Result { - let legacy_rpc = LegacyRpcMethods::::new(client); - let sys_props = legacy_rpc.system_properties().await?; + pub async fn query(client: &LegacyRpcMethods) -> Result { + let sys_props = client.system_properties().await?; let default_decimals = json!(12); let default_units = json!("UNIT"); diff --git a/crates/extrinsics/src/call.rs b/crates/extrinsics/src/call.rs index e2001c669..abc0fd306 100644 --- a/crates/extrinsics/src/call.rs +++ b/crates/extrinsics/src/call.rs @@ -44,7 +44,10 @@ use subxt_signer::sr25519::Keypair; use core::marker::PhantomData; use subxt::{ - backend::rpc::RpcClient, + backend::{ + legacy::LegacyRpcMethods, + rpc::RpcClient, + }, Config, OnlineClient, }; @@ -182,8 +185,9 @@ impl CallCommandBuilder { let url = self.opts.extrinsic_opts.url(); let rpc = RpcClient::from_url(&url).await?; let client = OnlineClient::from_rpc_client(rpc.clone()).await?; + let rpc = LegacyRpcMethods::new(rpc); - let token_metadata = TokenMetadata::query(rpc.clone()).await?; + let token_metadata = TokenMetadata::query(&rpc).await?; Ok(CallExec { contract: self.opts.contract.clone(), @@ -211,7 +215,7 @@ pub struct CallExec { gas_limit: Option, proof_size: Option, value: BalanceVariant, - rpc: RpcClient, + rpc: LegacyRpcMethods, client: Client, transcoder: ContractMessageTranscoder, call_data: Vec, @@ -276,7 +280,7 @@ impl CallExec { ); let result = - submit_extrinsic(&self.client, self.rpc.clone(), &call, &self.signer).await?; + submit_extrinsic(&self.client, &self.rpc, &call, &self.signer).await?; let display_events = DisplayEvents::from_events( &result, diff --git a/crates/extrinsics/src/instantiate.rs b/crates/extrinsics/src/instantiate.rs index 203cb2086..583d79492 100644 --- a/crates/extrinsics/src/instantiate.rs +++ b/crates/extrinsics/src/instantiate.rs @@ -47,7 +47,10 @@ use scale::Encode; use sp_core::Bytes; use sp_weights::Weight; use subxt::{ - backend::rpc::RpcClient, + backend::{ + legacy::LegacyRpcMethods, + rpc::RpcClient, + }, blocks::ExtrinsicEvents, Config, OnlineClient, @@ -175,10 +178,11 @@ impl InstantiateCommandBuilder { }; let salt = self.opts.salt.clone().map(|s| s.0).unwrap_or_default(); - let rpc = subxt::backend::rpc::RpcClient::from_url(&url).await?; - let client = OnlineClient::from_rpc_client(rpc.clone()).await?; + let rpc_cli = RpcClient::from_url(&url).await?; + let client = OnlineClient::from_rpc_client(rpc_cli.clone()).await?; + let rpc = LegacyRpcMethods::new(rpc_cli); - let token_metadata = TokenMetadata::query(rpc.clone()).await?; + let token_metadata = TokenMetadata::query(&rpc).await?; let args = InstantiateArgs { constructor: self.opts.constructor.clone(), @@ -273,7 +277,7 @@ pub struct InstantiateExec { opts: ExtrinsicOpts, args: InstantiateArgs, url: String, - rpc: RpcClient, + rpc: LegacyRpcMethods, client: Client, signer: Keypair, transcoder: ContractMessageTranscoder, @@ -365,7 +369,7 @@ impl InstantiateExec { ); let result = - submit_extrinsic(&self.client, self.rpc.clone(), &call, &self.signer).await?; + submit_extrinsic(&self.client, &self.rpc, &call, &self.signer).await?; // The CodeStored event is only raised if the contract has not already been // uploaded. @@ -400,7 +404,7 @@ impl InstantiateExec { ); let result = - submit_extrinsic(&self.client, self.rpc.clone(), &call, &self.signer).await?; + submit_extrinsic(&self.client, &self.rpc, &call, &self.signer).await?; let instantiated = result .find_first::()? diff --git a/crates/extrinsics/src/lib.rs b/crates/extrinsics/src/lib.rs index c957dd7e9..b85a97462 100644 --- a/crates/extrinsics/src/lib.rs +++ b/crates/extrinsics/src/lib.rs @@ -258,7 +258,7 @@ pub fn account_id(keypair: &Keypair) -> AccountId32 { /// future there could be a flag to wait for finality before reporting success. async fn submit_extrinsic( client: &OnlineClient, - rpc: RpcClient, + rpc: &LegacyRpcMethods, call: &Call, signer: &Signer, ) -> core::result::Result, subxt::Error> @@ -288,13 +288,12 @@ where /// release. async fn get_account_nonce( client: &OnlineClient, - rpc: RpcClient, + rpc: &LegacyRpcMethods, account_id: &T::AccountId, ) -> core::result::Result where T: Config, { - let rpc = LegacyRpcMethods::::new(rpc); let best_block = rpc .chain_get_block_hash(None) .await? @@ -321,13 +320,12 @@ where } async fn state_call( - rpc: RpcClient, + rpc: LegacyRpcMethods, func: &str, args: A, ) -> Result { - let cli = LegacyRpcMethods::::new(rpc); let params = args.encode(); - let bytes = cli.state_call(func, Some(¶ms), None).await?; + let bytes = rpc.state_call(func, Some(¶ms), None).await?; Ok(R::decode(&mut bytes.as_ref())?) } diff --git a/crates/extrinsics/src/remove.rs b/crates/extrinsics/src/remove.rs index 2d936f5a2..3a3144268 100644 --- a/crates/extrinsics/src/remove.rs +++ b/crates/extrinsics/src/remove.rs @@ -33,7 +33,10 @@ use crate::extrinsic_opts::ExtrinsicOpts; use anyhow::Result; use core::marker::PhantomData; use subxt::{ - backend::rpc::RpcClient, + backend::{ + legacy::LegacyRpcMethods, + rpc::RpcClient, + }, Config, OnlineClient, }; @@ -122,10 +125,11 @@ impl RemoveCommandBuilder { }?; let url = self.opts.extrinsic_opts.url(); - let rpc = subxt::backend::rpc::RpcClient::from_url(&url).await?; - let client = OnlineClient::from_rpc_client(rpc.clone()).await?; + let rpc_cli = RpcClient::from_url(&url).await?; + let client = OnlineClient::from_rpc_client(rpc_cli.clone()).await?; + let rpc = LegacyRpcMethods::new(rpc_cli); - let token_metadata = TokenMetadata::query(rpc.clone()).await?; + let token_metadata = TokenMetadata::query(&rpc).await?; Ok(RemoveExec { final_code_hash, @@ -142,7 +146,7 @@ impl RemoveCommandBuilder { pub struct RemoveExec { final_code_hash: [u8; 32], opts: ExtrinsicOpts, - rpc: RpcClient, + rpc: LegacyRpcMethods, client: Client, transcoder: ContractMessageTranscoder, signer: Keypair, @@ -166,7 +170,7 @@ impl RemoveExec { .remove_code(sp_core::H256(code_hash.0)); let result = - submit_extrinsic(&self.client, self.rpc.clone(), &call, &self.signer).await?; + submit_extrinsic(&self.client, &self.rpc, &call, &self.signer).await?; let display_events = DisplayEvents::from_events( &result, Some(&self.transcoder), diff --git a/crates/extrinsics/src/upload.rs b/crates/extrinsics/src/upload.rs index 923aa0cd5..257af3c14 100644 --- a/crates/extrinsics/src/upload.rs +++ b/crates/extrinsics/src/upload.rs @@ -39,7 +39,10 @@ use core::marker::PhantomData; use pallet_contracts_primitives::CodeUploadResult; use scale::Encode; use subxt::{ - backend::rpc::RpcClient, + backend::{ + legacy::LegacyRpcMethods, + rpc::RpcClient, + }, Config, OnlineClient, }; @@ -107,10 +110,11 @@ impl UploadCommandBuilder { })?; let url = self.opts.extrinsic_opts.url(); - let rpc = RpcClient::from_url(&url).await?; - let client = OnlineClient::from_rpc_client(rpc.clone()).await?; + let rpc_cli = RpcClient::from_url(&url).await?; + let client = OnlineClient::from_rpc_client(rpc_cli.clone()).await?; + let rpc = LegacyRpcMethods::new(rpc_cli); - let token_metadata = TokenMetadata::query(rpc.clone()).await?; + let token_metadata = TokenMetadata::query(&rpc).await?; Ok(UploadExec { opts: self.opts.extrinsic_opts.clone(), @@ -125,7 +129,7 @@ impl UploadCommandBuilder { pub struct UploadExec { opts: ExtrinsicOpts, - rpc: RpcClient, + rpc: LegacyRpcMethods, client: Client, code: WasmCode, signer: Keypair, @@ -172,7 +176,7 @@ impl UploadExec { ); let result = - submit_extrinsic(&self.client, self.rpc.clone(), &call, &self.signer).await?; + submit_extrinsic(&self.client, &self.rpc, &call, &self.signer).await?; let display_events = DisplayEvents::from_events(&result, None, &self.client.metadata())?; From 39d516c3ed569385c761a4679adfc0c360c0b739 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 5 Oct 2023 16:10:55 +0100 Subject: [PATCH 17/20] Review suggestions --- crates/cargo-contract/src/cmd/info.rs | 17 +++++++++++------ crates/extrinsics/src/call.rs | 2 +- crates/extrinsics/src/instantiate.rs | 2 +- crates/extrinsics/src/lib.rs | 12 +++++------- crates/extrinsics/src/upload.rs | 2 +- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/crates/cargo-contract/src/cmd/info.rs b/crates/cargo-contract/src/cmd/info.rs index aff22927d..40623fa51 100644 --- a/crates/cargo-contract/src/cmd/info.rs +++ b/crates/cargo-contract/src/cmd/info.rs @@ -35,7 +35,10 @@ use std::{ io::Write, }; use subxt::{ - backend::rpc::RpcClient, + backend::{ + legacy::LegacyRpcMethods, + rpc::RpcClient, + }, Config, OnlineClient, }; @@ -72,12 +75,14 @@ pub struct InfoCommand { impl InfoCommand { pub async fn run(&self) -> Result<(), ErrorVariant> { - let rpc = RpcClient::from_url(url_to_string(&self.url)).await?; - let client = OnlineClient::::from_rpc_client(rpc.clone()).await?; + let rpc_cli = RpcClient::from_url(url_to_string(&self.url)).await?; + let client = + OnlineClient::::from_rpc_client(rpc_cli.clone()).await?; + let rpc = LegacyRpcMethods::::new(rpc_cli.clone()); // All flag applied if self.all { - let contracts = fetch_all_contracts(&client, rpc).await?; + let contracts = fetch_all_contracts(&client, &rpc).await?; if self.output_json { let contracts_json = serde_json::json!({ @@ -96,7 +101,7 @@ impl InfoCommand { .as_ref() .expect("Contract argument was not provided"); - let info_to_json = fetch_contract_info(contract, rpc.clone(), &client) + let info_to_json = fetch_contract_info(contract, &rpc, &client) .await? .ok_or(anyhow!( "No contract information was found for account id {}", @@ -105,7 +110,7 @@ impl InfoCommand { // Binary flag applied if self.binary { - let wasm_code = fetch_wasm_code(&client, rpc, info_to_json.code_hash()) + let wasm_code = fetch_wasm_code(&client, &rpc, info_to_json.code_hash()) .await? .ok_or(anyhow!( "Contract wasm code was not found for account id {}", diff --git a/crates/extrinsics/src/call.rs b/crates/extrinsics/src/call.rs index abc0fd306..16596fd35 100644 --- a/crates/extrinsics/src/call.rs +++ b/crates/extrinsics/src/call.rs @@ -248,7 +248,7 @@ impl CallExec { storage_deposit_limit, input_data: self.call_data.clone(), }; - state_call(self.rpc.clone(), "ContractsApi_call", call_request).await + state_call(&self.rpc, "ContractsApi_call", call_request).await } /// Calls a contract on the blockchain with a specified gas limit. diff --git a/crates/extrinsics/src/instantiate.rs b/crates/extrinsics/src/instantiate.rs index 583d79492..94ba2b50c 100644 --- a/crates/extrinsics/src/instantiate.rs +++ b/crates/extrinsics/src/instantiate.rs @@ -351,7 +351,7 @@ impl InstantiateExec { data: self.args.data.clone(), salt: self.args.salt.clone(), }; - state_call(self.rpc.clone(), "ContractsApi_instantiate", &call_request).await + state_call(&self.rpc, "ContractsApi_instantiate", &call_request).await } async fn instantiate_with_code( diff --git a/crates/extrinsics/src/lib.rs b/crates/extrinsics/src/lib.rs index 432c841e8..c84a2412a 100644 --- a/crates/extrinsics/src/lib.rs +++ b/crates/extrinsics/src/lib.rs @@ -48,7 +48,6 @@ use scale::{ Encode, }; use subxt::{ - backend::rpc::RpcClient, blocks, config, tx, @@ -327,7 +326,7 @@ where } async fn state_call( - rpc: LegacyRpcMethods, + rpc: &LegacyRpcMethods, func: &str, args: A, ) -> Result { @@ -349,9 +348,8 @@ pub fn parse_code_hash(input: &str) -> Result<::Hash> { /// Fetch the hash of the *best* block (included but not guaranteed to be finalized). async fn get_best_block( - rpc: RpcClient, + rpc: &LegacyRpcMethods, ) -> core::result::Result<::Hash, subxt::Error> { - let rpc = LegacyRpcMethods::::new(rpc); rpc.chain_get_block_hash(None) .await? .ok_or(subxt::Error::Other("Best block not found".into())) @@ -360,7 +358,7 @@ async fn get_best_block( /// Fetch the contract info from the storage using the provided client. pub async fn fetch_contract_info( contract: &AccountId32, - rpc: RpcClient, + rpc: &LegacyRpcMethods, client: &Client, ) -> Result> { let info_contract_call = api::storage().contracts().contract_info_of(contract); @@ -425,7 +423,7 @@ impl ContractInfo { /// Fetch the contract wasm code from the storage using the provided client and code hash. pub async fn fetch_wasm_code( client: &Client, - rpc: RpcClient, + rpc: &LegacyRpcMethods, hash: &CodeHash, ) -> Result>> { let pristine_code_address = api::storage().contracts().pristine_code(hash); @@ -460,7 +458,7 @@ fn parse_contract_account_address( /// requested elements starting from an optional address pub async fn fetch_all_contracts( client: &Client, - rpc: RpcClient, + rpc: &LegacyRpcMethods, ) -> Result> { let root_key = api::storage() .contracts() diff --git a/crates/extrinsics/src/upload.rs b/crates/extrinsics/src/upload.rs index 257af3c14..a332895f4 100644 --- a/crates/extrinsics/src/upload.rs +++ b/crates/extrinsics/src/upload.rs @@ -156,7 +156,7 @@ impl UploadExec { storage_deposit_limit, determinism: Determinism::Enforced, }; - state_call(self.rpc.clone(), "ContractsApi_upload_code", call_request).await + state_call(&self.rpc, "ContractsApi_upload_code", call_request).await } /// Uploads contract code to the blockchain with specified options. From e0ec352f50e233a7acbe951bf3a92d59cc34e65b Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 5 Oct 2023 17:26:58 +0100 Subject: [PATCH 18/20] Update contracts node metadata --- .../src/runtime_api/contracts_runtime.scale | Bin 29868 -> 32393 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/crates/extrinsics/src/runtime_api/contracts_runtime.scale b/crates/extrinsics/src/runtime_api/contracts_runtime.scale index d61d093bafa0b24b78b62fd55c6d59b54c6fc17e..e8d10021116471a2ad497c13a682a570a6db7fbc 100644 GIT binary patch delta 5043 zcmbVQ3vg7`89x8+4Qy}&8zEtVJWgUD351XY!$1r)Az8>m-dP@^nB451WH0RAySevn zOjKs2Q(Ca46;JJynL5>0TJ0DsU2%*p9qFhQMmpfgRHjNsr}F0UCe`6 zr!$#5H|PA1?|k<^|M|{7bsqLzgXv*r%CjqLxe%6>kuUN8SQ0ErKT>&QrW1i2B@He$_6zOm}qio zi=<|ng%3ZvpZb{q(i z9MnZ##uwY8d(YX#j!(GfFYd#-vKf=Hl zKmz+^lXWBA4AZK9g&9vlE=-7D+n@zllWYXBO3Ucjnk}PPr!!jQp~hq=tfuRc)(~=% zyXG-CZP9X;zcB9~@HRek_@Cw%!#V!({AKV(eEx!;Oxp-|%7FmlmJ?~1 zu1*LTn+ob%XbiS*wyZg5oAwQDooIXhD-f~ke3gyi3%Mf14JC4-(RC|gyY8o`P zPw8J%QzHr;o!!Ej>F>fD6SMqJZ>%2-P$a&OVanmi`>-i8F-QycMb%8LsiHTe`FD1! z(Qq%*KZ3mzt=Ed_R%>>hrepD9^`_f+EiB+Yh3T+2zN7HonX#cMHex4}{XrHWc~Tbm zf{dm<26kkF>WN8;RYb$`kP?oDX#xk;`mhlvcBJUY*Ee=~aME@kZq>}#I?B`vU#HgH@PJ%V4mdMnv z4C0|Pc`3u?-)WFl1Xdpibg@uhy)ii>DUeD5tt|Z5qo{nNK-AQzd5g8E028zZ1$kpv zDfq<{{QZhsYU*u-*z0hI5VG3l%)#C4*L0S{0#()3m8*)nlzvq&g$Bpm z%YWtqW(}q_E^_6fVDacOAukd#%}K)6gs(Ag)(}LkyZg&$>)0(EOIw0{kXZ%4qPFv-&hS$yP5fG6T@EI(YQl) z2|RrJI*)B3@L#TL&8P>s?zr2UoV~trK|0Lw3}GLIYCyt^kjp&?z~%)qj5dos9w-v? zifSl+z)=VG2CPD+doWy+^+uqCrA&+#fRzHvbtiuX+pZ3IOl%X7v#A zFvjgVDJMu9wO8?Q=wP?Z!R z7sJB$5a$~f!Y)3#VKE%x?{Dawy&Isyt73D+4%R4}G9jZDz?~aw;h6PyV&k`9KQC)` z&!7=q8&m?!5dXGT936-Bz&NA_CL?{B|E75%oZ+XMm)v^VLS6I-kdp%TV?d6Nqw~;Y zIuG$>EnDnoZBBl)aRGn4#fu8 zhvR~W=Hv%E&hy(3qGlRx&&@c46()RyTDfM0hYoLLnjP1F76{nKmeaY((9b2HU$8t6 zcFcy8e5At-XZb4~ji|(K>RdhRB!JY3ryau*YyVFW(?*Zo=V5zHQ6qjZ1WGY@%zE5-m*l zRd4F5EEwl^Q23?UlC&Ni`8!!|etJ_5e99p`D{kNXrUcK#-`W-ec$Rzb zd=#GNAK&?$vy66$12h_9uXgaKwwK0=XA|<=kvYWu&%(E-T`GOyO4f8(Jh)^&ajz)5 zi8x=MJA*hk{2S-Djbsz|bJ>izf3ZA^xKI2T#~!M{$IU;-M_%(*vhtq#OyV9u8Tf4O zG-5A`@D^|9?;hGkN;-!=A|?M>@pN8garh?EJ35o(tjZ+6`rhvR*u&C(2N`up|9Wpx zlegl53NwF?}2kl;*mU3Nr`T_2_4NO7q3(h>a8Y=x^f9UIGddK zYaXEoW|QplkFUl`lM4%Dln42z*&md(^`LcNz!bn&C27sGe- z_=B>dc4H%F*y=U4rUpBBP0bV+lb-Ef5Y5fRYnqWf>M^IdG9w}pFmYW8lw*F(vjq_=yeV3d<;u|UP3_$PFxEL3eM z=~GU(FuEgZ#7rtAHxg|H7M@r)I7hM@5|<2vL&eSmh`=c z>TYKL3A+~t_}}_DnrXq??7N|bj|6wj=t!JqyI~J6P%g~bhd&4nd7&h6gR!LV!|}o$ zbvAVKhwg!c@xO;Cz?1PW!?(Z^FE~R?bsh%NI1pv}aCaa6q!B<)m5||ZMu*I#!BHSw zjpXs2+E)BMgwSR>Q1gP@<@jsM&3usOR|u1CM1N1DDtl7m~-U%aB86(N$ir i-K delta 2421 zcmb7GeNa@_6+dV92@5Q+n`Q0t{m>!76gI{5rk#=a`{jTFS}QH2)p>+TLUOH z+A>vV$duekW-u{ITU)i_lv#D4iHS_=v}xm{PD@6om@yeMW2VhitxaQ^q`mL07C>ckUkg2G4wkk^Mvw;y=de$PPq4DBxK{j+*q#gWuQZEs7s;&vL=u z=#OG?g4WtL;8A)v(L#^gM)8EEpJIA)uA_)Kw{ zS^+T0+}CH6c|-19LdgF(R)qu5ri3(FpY(i+GQ=e z0i&WN$uFrT;9&4qS$pE>@19u^`warnj4FGk<6nUV_ z37AblYFBl6btbP+IyOD8n$*nNuNgKoR{uwxgJdXfUzzSao1(@%IxBGTFwmpOa>| z^09*+Yg|DU*9>mcBv+#gH#4aQi|Fmf75WlH>T0xh12i$*W+Dgr6a&L8K&~3g8Mwi< zlY;_=2f#WkaZnzD?^k(}}bR56FRU*VG3>dgN?B?8PXT7LZV+DGkDHEOa zWK%BgqJM5`wlpE;*ZO*hM0`q>pa=i~jbLYU8IEYuZ1b~>^n>OM_D*hT$R7$LD1;Fd zmJ-}gCt5OboW9etYR#BN*4~eBNM*YVVKl6Zfu&sx(6rVze1#e|ucQ;L8yKe>t+_bK z^dILO4GSJ!8ax{6(FC2@ya^9cy}OVNmtuFO?!1l)TTL2!hg2uH?u;eG(QsYjr1EZb{b@Af@br9G@+*%g zzp^Cx$D!o*tt|yN!s0|VZhrAY5FZPi4>j^r9X<9v8@;qO1uxOLXlwA^)@vO8JorbU z5Ah^*c#h*4dfjuu$n!0p9^wu3k+*W_Yu=oF|Fi(~_FKXBvi{SE{@jZ7rpS@p?GuS$ zJF+bXj7jm)VEoO61h8FLp8>X?`n+I!+r!l1Db@Cl1#I_hOuBcZ6C6Ky(+oDz1jRr6 z8JvrafYY=3|C}GJIJgh8rMsU)_J@bPX$4siqM_Ir4=J@~IP%whBk8Yj<`|gbIQPQ2 zjpg}YBuVL`9B`)>sv<`@_Jv5@uE-PIcr4euW+eRtXO89yU+T>gvbOie?8a4JWqs($ z%z0@`#dtw;lo?)LdFDZFla5?Tt<82m0T(Th7HtE5+zh!L1;9rYLE-z!z>ivBxiJNJ z(PD?VU+7|r@RR3m=}sp7QjVQNYZn*sZ&vji&s*U5>0?n~4BjE}y5MH- zu`B6ae--9X!@wuFn*MFz5Bfx0M`w0Xwq7r-)i<%L>#)=toq;AVn{`cW1b-`ip3s2? zWiS!5pYQW~c6Rj$at}{}|CK9sEUa?(Fp9x9ck_rt!G#xA;;KY6_7R_PKSI^60Fj2e zwiD9jW&e1@KG|Rl3@Q&D#t>-Ta2l-{YRCO_a%c$0g2}_>7(b5LqHiFebg3NdvvkLv z$>rl{^7y^vVu+aCBny3t{XLqtcaM1-pJM1l>KA>Y+<)*Y($jkn=&oZhZ=@adHxT{@ Ds1eFI From 7fb7359dcac552c40c1097aaa027b2277816cde1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Oct 2023 13:09:07 +0000 Subject: [PATCH 19/20] Bump substrate-build-script-utils from 7.0.0 to 8.0.0 Bumps [substrate-build-script-utils](https://github.com/paritytech/polkadot-sdk) from 7.0.0 to 8.0.0. - [Release notes](https://github.com/paritytech/polkadot-sdk/releases) - [Commits](https://github.com/paritytech/polkadot-sdk/commits) --- updated-dependencies: - dependency-name: substrate-build-script-utils dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- crates/cargo-contract/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9d2ec86c..40cb143a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4929,9 +4929,9 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" -version = "7.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbedbf60cc336a4a65dc885e6db53fb6f6a5aeaca47f544b1c44a5c2712a326f" +checksum = "78127cdb5849eed7399ff9c730faea57c2a4e148e3b46e565abe98248432feb9" [[package]] name = "subtle" diff --git a/crates/cargo-contract/Cargo.toml b/crates/cargo-contract/Cargo.toml index 78393afd0..9bcc2ff30 100644 --- a/crates/cargo-contract/Cargo.toml +++ b/crates/cargo-contract/Cargo.toml @@ -47,7 +47,7 @@ hex = "0.4.3" [build-dependencies] anyhow = "1.0.75" -substrate-build-script-utils = "7.0.0" +substrate-build-script-utils = "8.0.0" current_platform = "0.2.0" which = "4.4.2" From 654249fd64303000955ef5e4be1b6590b9f2cd83 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 6 Oct 2023 09:57:38 +0100 Subject: [PATCH 20/20] Clippy PartialOrd suggestion --- crates/transcode/src/scon/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/transcode/src/scon/mod.rs b/crates/transcode/src/scon/mod.rs index 16cf48b55..cb5727b03 100644 --- a/crates/transcode/src/scon/mod.rs +++ b/crates/transcode/src/scon/mod.rs @@ -124,7 +124,7 @@ impl PartialEq for Map { impl PartialOrd for Map { fn partial_cmp(&self, other: &Map) -> Option { - self.iter().partial_cmp(other.iter()) + Some(self.cmp(other)) } }