diff --git a/subxt/src/client.rs b/subxt/src/client.rs index eaa18ae64b..d567c59f03 100644 --- a/subxt/src/client.rs +++ b/subxt/src/client.rs @@ -47,6 +47,7 @@ use codec::{ Encode, }; use derivative::Derivative; +use futures::lock::Mutex; use parking_lot::RwLock; use std::sync::Arc; @@ -122,9 +123,9 @@ impl ClientBuilder { Ok(Client { rpc, genesis_hash: genesis_hash?, - metadata: Arc::new(RwLock::new(metadata)), + metadata: Arc::new(Mutex::new(metadata)), properties: properties.unwrap_or_else(|_| Default::default()), - runtime_version: Arc::new(RwLock::new(runtime_version?)), + runtime_version: Arc::new(Mutex::new(runtime_version?)), iter_page_size: self.page_size.unwrap_or(10), }) } @@ -136,9 +137,9 @@ impl ClientBuilder { pub struct Client { rpc: Rpc, genesis_hash: T::Hash, - metadata: Arc>, + metadata: Arc>, properties: SystemProperties, - runtime_version: Arc>, + runtime_version: Arc>, iter_page_size: u32, } @@ -163,7 +164,7 @@ impl Client { } /// Returns the chain metadata. - pub fn metadata(&self) -> Arc> { + pub fn metadata(&self) -> Arc> { Arc::clone(&self.metadata) } @@ -207,7 +208,7 @@ impl Client { } /// Returns the client's Runtime Version. - pub fn runtime_version(&self) -> Arc> { + pub fn runtime_version(&self) -> Arc> { Arc::clone(&self.runtime_version) } } @@ -330,7 +331,7 @@ where let call_data = { let mut bytes = Vec::new(); let locked_metadata = self.client.metadata(); - let metadata = locked_metadata.read(); + let metadata = locked_metadata.lock().await; let pallet = metadata.pallet(C::PALLET)?; bytes.push(pallet.index()); bytes.push(pallet.call_index::()?); @@ -342,7 +343,7 @@ where let additional_and_extra_params = { // Obtain spec version and transaction version from the runtime version of the client. let locked_runtime = self.client.runtime_version(); - let runtime = locked_runtime.read(); + let runtime = locked_runtime.lock().await; X::new( runtime.spec_version, runtime.transaction_version, diff --git a/subxt/src/events/events_type.rs b/subxt/src/events/events_type.rs index 57954e1a2d..792899714a 100644 --- a/subxt/src/events/events_type.rs +++ b/subxt/src/events/events_type.rs @@ -32,6 +32,7 @@ use codec::{ Input, }; use derivative::Derivative; +use futures::lock::Mutex; use parking_lot::RwLock; use sp_core::{ storage::StorageKey, @@ -93,7 +94,7 @@ fn system_events_key() -> StorageKey { #[derive(Derivative)] #[derivative(Debug(bound = ""))] pub struct Events { - metadata: Arc>, + metadata: Arc>, block_hash: T::Hash, // Note; raw event bytes are prefixed with a Compact containing // the number of events to be decoded. We should have stripped that off @@ -180,7 +181,7 @@ impl<'a, T: Config, Evs: Decode> Events { /// This method is safe to use even if you do not statically know about /// all of the possible events; it splits events up using the metadata /// obtained at runtime, which does. - pub fn iter_raw( + pub async fn iter_raw( &self, ) -> impl Iterator> + '_ { let event_bytes = &self.event_bytes; @@ -195,6 +196,7 @@ impl<'a, T: Config, Evs: Decode> Events { None } else { match decode_raw_event_details::(self.metadata.clone(), index, cursor) + .await { Ok(raw_event) => { // Skip over decoded bytes in next iteration: @@ -239,6 +241,7 @@ impl<'a, T: Config, Evs: Decode> Events { None } else { match decode_raw_event_details::(self.metadata.clone(), index, cursor) + .await { Ok(raw_event) => { // Skip over decoded bytes in next iteration: @@ -334,8 +337,8 @@ impl RawEventDetails { } // Attempt to dynamically decode a single event from our events input. -fn decode_raw_event_details( - metadata: Arc>, +async fn decode_raw_event_details( + metadata: Arc>, index: u32, input: &mut &[u8], ) -> Result { @@ -352,7 +355,7 @@ fn decode_raw_event_details( log::debug!("remaining input: {}", hex::encode(&input)); // Get metadata for the event: - let metadata = metadata.read(); + let metadata = metadata.lock().await; let event_metadata = metadata.event(pallet_index, variant_index)?; log::debug!( "Decoding Event '{}::{}'", @@ -473,7 +476,7 @@ pub(crate) mod test_utils { /// Build an `Events` object for test purposes, based on the details provided, /// and with a default block hash. pub fn events( - metadata: Arc>, + metadata: Arc>, event_records: Vec>, ) -> Events> { let num_events = event_records.len() as u32; @@ -487,7 +490,7 @@ pub(crate) mod test_utils { /// Much like [`events`], but takes pre-encoded events and event count, so that we can /// mess with the bytes in tests if we need to. pub fn events_raw( - metadata: Arc>, + metadata: Arc>, event_bytes: Vec, num_events: u32, ) -> Events> { @@ -525,7 +528,7 @@ mod tests { } // Create fake metadata that knows about our single event, above: - let metadata = Arc::new(RwLock::new(metadata::())); + let metadata = Arc::new(Mutex::new(metadata::())); // Encode our events in the format we expect back from a node, and // construct an Events object to iterate them: @@ -555,7 +558,7 @@ mod tests { } // Create fake metadata that knows about our single event, above: - let metadata = Arc::new(RwLock::new(metadata::())); + let metadata = Arc::new(Mutex::new(metadata::())); // Encode our events in the format we expect back from a node, and // construst an Events object to iterate them: @@ -601,7 +604,7 @@ mod tests { } // Create fake metadata that knows about our single event, above: - let metadata = Arc::new(RwLock::new(metadata::())); + let metadata = Arc::new(Mutex::new(metadata::())); // Encode 2 events: let mut event_bytes = vec![]; @@ -653,7 +656,7 @@ mod tests { } // Create fake metadata that knows about our single event, above: - let metadata = Arc::new(RwLock::new(metadata::())); + let metadata = Arc::new(Mutex::new(metadata::())); // Encode our events in the format we expect back from a node, and // construst an Events object to iterate them: @@ -695,7 +698,7 @@ mod tests { } // Create fake metadata that knows about our single event, above: - let metadata = Arc::new(RwLock::new(metadata::())); + let metadata = Arc::new(Mutex::new(metadata::())); // Encode our events in the format we expect back from a node, and // construst an Events object to iterate them: @@ -764,7 +767,7 @@ mod tests { } // Create fake metadata that knows about our single event, above: - let metadata = Arc::new(RwLock::new(metadata::())); + let metadata = Arc::new(Mutex::new(metadata::())); // Encode 2 events: let mut event_bytes = vec![]; @@ -831,7 +834,7 @@ mod tests { } // Create fake metadata that knows about our single event, above: - let metadata = Arc::new(RwLock::new(metadata::())); + let metadata = Arc::new(Mutex::new(metadata::())); // Encode our events in the format we expect back from a node, and // construst an Events object to iterate them: @@ -886,7 +889,7 @@ mod tests { struct CompactWrapper(u64); // Create fake metadata that knows about our single event, above: - let metadata = Arc::new(RwLock::new(metadata::())); + let metadata = Arc::new(Mutex::new(metadata::())); // Encode our events in the format we expect back from a node, and // construct an Events object to iterate them: @@ -948,7 +951,7 @@ mod tests { } // Create fake metadata that knows about our single event, above: - let metadata = Arc::new(RwLock::new(metadata::())); + let metadata = Arc::new(Mutex::new(metadata::())); // Encode our events in the format we expect back from a node, and // construct an Events object to iterate them: diff --git a/subxt/src/storage.rs b/subxt/src/storage.rs index 7d41278dbb..a867696668 100644 --- a/subxt/src/storage.rs +++ b/subxt/src/storage.rs @@ -20,6 +20,7 @@ use codec::{ Decode, Encode, }; +use futures::lock::Mutex; use parking_lot::RwLock; use sp_core::storage::{ StorageChangeSet, @@ -137,7 +138,7 @@ impl StorageMapKey { /// Client for querying runtime storage. pub struct StorageClient<'a, T: Config> { rpc: &'a Rpc, - metadata: Arc>, + metadata: Arc>, iter_page_size: u32, } @@ -155,7 +156,7 @@ impl<'a, T: Config> StorageClient<'a, T> { /// Create a new [`StorageClient`] pub fn new( rpc: &'a Rpc, - metadata: Arc>, + metadata: Arc>, iter_page_size: u32, ) -> Self { Self { @@ -207,7 +208,7 @@ impl<'a, T: Config> StorageClient<'a, T> { if let Some(data) = self.fetch(store, hash).await? { Ok(data) } else { - let metadata = self.metadata.read(); + let metadata = self.metadata.lock().await; let pallet_metadata = metadata.pallet(F::PALLET)?; let storage_metadata = pallet_metadata.storage(F::STORAGE)?; let default = Decode::decode(&mut &storage_metadata.default[..]) diff --git a/subxt/src/transaction.rs b/subxt/src/transaction.rs index cda1b3ba3e..84d2179b3b 100644 --- a/subxt/src/transaction.rs +++ b/subxt/src/transaction.rs @@ -390,7 +390,7 @@ impl<'client, T: Config, E: Decode + HasModuleError, Evs: Decode> if let Some(error_data) = dispatch_error.module_error_data() { // Error index is utilized as the first byte from the error array. let locked_metadata = self.client.metadata(); - let metadata = locked_metadata.read(); + let metadata = locked_metadata.lock().await; let details = metadata .error(error_data.pallet_index, error_data.error_index())?; return Err(Error::Module(ModuleError { diff --git a/subxt/src/updates.rs b/subxt/src/updates.rs index fb97b485ba..37c649abdf 100644 --- a/subxt/src/updates.rs +++ b/subxt/src/updates.rs @@ -25,22 +25,23 @@ use crate::{ Config, Metadata, }; +use futures::lock::Mutex; use parking_lot::RwLock; use std::sync::Arc; /// Client wrapper for performing runtime updates. pub struct UpdateClient { rpc: Rpc, - metadata: Arc>, - runtime_version: Arc>, + metadata: Arc>, + runtime_version: Arc>, } impl UpdateClient { /// Create a new [`UpdateClient`]. pub fn new( rpc: Rpc, - metadata: Arc>, - runtime_version: Arc>, + metadata: Arc>, + runtime_version: Arc>, ) -> Self { Self { rpc, @@ -69,7 +70,7 @@ impl UpdateClient { { // The Runtime Version of the client, as set during building the client // or during updates. - let runtime_version = self.runtime_version.read(); + let runtime_version = self.runtime_version.lock().await; if runtime_version.spec_version >= update_runtime_version.spec_version { log::debug!( "Runtime update not performed for spec_version={}, client has spec_version={}", @@ -82,7 +83,7 @@ impl UpdateClient { // Fetch the new metadata of the runtime node. let update_metadata = self.rpc.metadata().await?; - let mut runtime_version = self.runtime_version.write(); + let mut runtime_version = self.runtime_version.lock().await; // Update both the `RuntimeVersion` and `Metadata` of the client. log::info!( "Performing runtime update from {} to {}", @@ -91,7 +92,7 @@ impl UpdateClient { ); *runtime_version = update_runtime_version; log::debug!("Performing metadata update"); - let mut metadata = self.metadata.write(); + let mut metadata = self.metadata.lock().await; *metadata = update_metadata; log::debug!("Runtime update completed");