Skip to content

Commit

Permalink
subxt: Switch to async::Mutex
Browse files Browse the repository at this point in the history
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
  • Loading branch information
lexnv committed May 4, 2022
1 parent 988f758 commit f5bde9b
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 35 deletions.
17 changes: 9 additions & 8 deletions subxt/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ use codec::{
Encode,
};
use derivative::Derivative;
use futures::lock::Mutex;
use parking_lot::RwLock;
use std::sync::Arc;

Expand Down Expand Up @@ -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),
})
}
Expand All @@ -136,9 +137,9 @@ impl ClientBuilder {
pub struct Client<T: Config> {
rpc: Rpc<T>,
genesis_hash: T::Hash,
metadata: Arc<RwLock<Metadata>>,
metadata: Arc<Mutex<Metadata>>,
properties: SystemProperties,
runtime_version: Arc<RwLock<RuntimeVersion>>,
runtime_version: Arc<Mutex<RuntimeVersion>>,
iter_page_size: u32,
}

Expand All @@ -163,7 +164,7 @@ impl<T: Config> Client<T> {
}

/// Returns the chain metadata.
pub fn metadata(&self) -> Arc<RwLock<Metadata>> {
pub fn metadata(&self) -> Arc<Mutex<Metadata>> {
Arc::clone(&self.metadata)
}

Expand Down Expand Up @@ -207,7 +208,7 @@ impl<T: Config> Client<T> {
}

/// Returns the client's Runtime Version.
pub fn runtime_version(&self) -> Arc<RwLock<RuntimeVersion>> {
pub fn runtime_version(&self) -> Arc<Mutex<RuntimeVersion>> {
Arc::clone(&self.runtime_version)
}
}
Expand Down Expand Up @@ -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::<C>()?);
Expand All @@ -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,
Expand Down
35 changes: 19 additions & 16 deletions subxt/src/events/events_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use codec::{
Input,
};
use derivative::Derivative;
use futures::lock::Mutex;
use parking_lot::RwLock;
use sp_core::{
storage::StorageKey,
Expand Down Expand Up @@ -93,7 +94,7 @@ fn system_events_key() -> StorageKey {
#[derive(Derivative)]
#[derivative(Debug(bound = ""))]
pub struct Events<T: Config, Evs> {
metadata: Arc<RwLock<Metadata>>,
metadata: Arc<Mutex<Metadata>>,
block_hash: T::Hash,
// Note; raw event bytes are prefixed with a Compact<u32> containing
// the number of events to be decoded. We should have stripped that off
Expand Down Expand Up @@ -180,7 +181,7 @@ impl<'a, T: Config, Evs: Decode> Events<T, Evs> {
/// 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<Item = Result<RawEventDetails, BasicError>> + '_ {
let event_bytes = &self.event_bytes;
Expand All @@ -195,6 +196,7 @@ impl<'a, T: Config, Evs: Decode> Events<T, Evs> {
None
} else {
match decode_raw_event_details::<T>(self.metadata.clone(), index, cursor)
.await
{
Ok(raw_event) => {
// Skip over decoded bytes in next iteration:
Expand Down Expand Up @@ -239,6 +241,7 @@ impl<'a, T: Config, Evs: Decode> Events<T, Evs> {
None
} else {
match decode_raw_event_details::<T>(self.metadata.clone(), index, cursor)
.await
{
Ok(raw_event) => {
// Skip over decoded bytes in next iteration:
Expand Down Expand Up @@ -334,8 +337,8 @@ impl RawEventDetails {
}

// Attempt to dynamically decode a single event from our events input.
fn decode_raw_event_details<T: Config>(
metadata: Arc<RwLock<Metadata>>,
async fn decode_raw_event_details<T: Config>(
metadata: Arc<Mutex<Metadata>>,
index: u32,
input: &mut &[u8],
) -> Result<RawEventDetails, BasicError> {
Expand All @@ -352,7 +355,7 @@ fn decode_raw_event_details<T: Config>(
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 '{}::{}'",
Expand Down Expand Up @@ -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<E: Decode + Encode>(
metadata: Arc<RwLock<Metadata>>,
metadata: Arc<Mutex<Metadata>>,
event_records: Vec<EventRecord<E>>,
) -> Events<DefaultConfig, AllEvents<E>> {
let num_events = event_records.len() as u32;
Expand All @@ -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<E: Decode + Encode>(
metadata: Arc<RwLock<Metadata>>,
metadata: Arc<Mutex<Metadata>>,
event_bytes: Vec<u8>,
num_events: u32,
) -> Events<DefaultConfig, AllEvents<E>> {
Expand Down Expand Up @@ -525,7 +528,7 @@ mod tests {
}

// Create fake metadata that knows about our single event, above:
let metadata = Arc::new(RwLock::new(metadata::<Event>()));
let metadata = Arc::new(Mutex::new(metadata::<Event>()));

// Encode our events in the format we expect back from a node, and
// construct an Events object to iterate them:
Expand Down Expand Up @@ -555,7 +558,7 @@ mod tests {
}

// Create fake metadata that knows about our single event, above:
let metadata = Arc::new(RwLock::new(metadata::<Event>()));
let metadata = Arc::new(Mutex::new(metadata::<Event>()));

// Encode our events in the format we expect back from a node, and
// construst an Events object to iterate them:
Expand Down Expand Up @@ -601,7 +604,7 @@ mod tests {
}

// Create fake metadata that knows about our single event, above:
let metadata = Arc::new(RwLock::new(metadata::<Event>()));
let metadata = Arc::new(Mutex::new(metadata::<Event>()));

// Encode 2 events:
let mut event_bytes = vec![];
Expand Down Expand Up @@ -653,7 +656,7 @@ mod tests {
}

// Create fake metadata that knows about our single event, above:
let metadata = Arc::new(RwLock::new(metadata::<Event>()));
let metadata = Arc::new(Mutex::new(metadata::<Event>()));

// Encode our events in the format we expect back from a node, and
// construst an Events object to iterate them:
Expand Down Expand Up @@ -695,7 +698,7 @@ mod tests {
}

// Create fake metadata that knows about our single event, above:
let metadata = Arc::new(RwLock::new(metadata::<Event>()));
let metadata = Arc::new(Mutex::new(metadata::<Event>()));

// Encode our events in the format we expect back from a node, and
// construst an Events object to iterate them:
Expand Down Expand Up @@ -764,7 +767,7 @@ mod tests {
}

// Create fake metadata that knows about our single event, above:
let metadata = Arc::new(RwLock::new(metadata::<Event>()));
let metadata = Arc::new(Mutex::new(metadata::<Event>()));

// Encode 2 events:
let mut event_bytes = vec![];
Expand Down Expand Up @@ -831,7 +834,7 @@ mod tests {
}

// Create fake metadata that knows about our single event, above:
let metadata = Arc::new(RwLock::new(metadata::<Event>()));
let metadata = Arc::new(Mutex::new(metadata::<Event>()));

// Encode our events in the format we expect back from a node, and
// construst an Events object to iterate them:
Expand Down Expand Up @@ -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::<Event>()));
let metadata = Arc::new(Mutex::new(metadata::<Event>()));

// Encode our events in the format we expect back from a node, and
// construct an Events object to iterate them:
Expand Down Expand Up @@ -948,7 +951,7 @@ mod tests {
}

// Create fake metadata that knows about our single event, above:
let metadata = Arc::new(RwLock::new(metadata::<Event>()));
let metadata = Arc::new(Mutex::new(metadata::<Event>()));

// Encode our events in the format we expect back from a node, and
// construct an Events object to iterate them:
Expand Down
7 changes: 4 additions & 3 deletions subxt/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use codec::{
Decode,
Encode,
};
use futures::lock::Mutex;
use parking_lot::RwLock;
use sp_core::storage::{
StorageChangeSet,
Expand Down Expand Up @@ -137,7 +138,7 @@ impl StorageMapKey {
/// Client for querying runtime storage.
pub struct StorageClient<'a, T: Config> {
rpc: &'a Rpc<T>,
metadata: Arc<RwLock<Metadata>>,
metadata: Arc<Mutex<Metadata>>,
iter_page_size: u32,
}

Expand All @@ -155,7 +156,7 @@ impl<'a, T: Config> StorageClient<'a, T> {
/// Create a new [`StorageClient`]
pub fn new(
rpc: &'a Rpc<T>,
metadata: Arc<RwLock<Metadata>>,
metadata: Arc<Mutex<Metadata>>,
iter_page_size: u32,
) -> Self {
Self {
Expand Down Expand Up @@ -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[..])
Expand Down
2 changes: 1 addition & 1 deletion subxt/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
15 changes: 8 additions & 7 deletions subxt/src/updates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: Config> {
rpc: Rpc<T>,
metadata: Arc<RwLock<Metadata>>,
runtime_version: Arc<RwLock<RuntimeVersion>>,
metadata: Arc<Mutex<Metadata>>,
runtime_version: Arc<Mutex<RuntimeVersion>>,
}

impl<T: Config> UpdateClient<T> {
/// Create a new [`UpdateClient`].
pub fn new(
rpc: Rpc<T>,
metadata: Arc<RwLock<Metadata>>,
runtime_version: Arc<RwLock<RuntimeVersion>>,
metadata: Arc<Mutex<Metadata>>,
runtime_version: Arc<Mutex<RuntimeVersion>>,
) -> Self {
Self {
rpc,
Expand Down Expand Up @@ -69,7 +70,7 @@ impl<T: Config> UpdateClient<T> {
{
// 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={}",
Expand All @@ -82,7 +83,7 @@ impl<T: Config> UpdateClient<T> {
// 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 {}",
Expand All @@ -91,7 +92,7 @@ impl<T: Config> UpdateClient<T> {
);
*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");
Expand Down

0 comments on commit f5bde9b

Please sign in to comment.