Subscribe to Runtime upgrades for proper extrinsic construction (#513)

* subxt: Add subscription to runtime upgrades

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Synchronize and expose inner `RuntimeVersion` of the `Client`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* examples: Add runtime update example

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Expose `RuntimeVersion` as locked

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Expose `Metadata` as locked

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt/storage: Use locked metadata

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Use parking lot RwLock variant for locked metadata

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Utilize locked metadata variant

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt/transaction: Use locked metadata variant

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update subxt to use locked version of the Metadata

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Add runtime update client wrapper

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* examples: Modify runtime update example

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Fix clippy

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Fix cargo check

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* codegen: Keep consistency with cargo check fix

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Remove unnecessary Arc

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Remove MetadataInner and use parking_lot::RwLock

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update polkadot.rs

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update polkadot.rs generation comment

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Switch to async::Mutex

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Block executor while decoding dynamic events

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* codegen: Use async API to handle async locking

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Remove unused dependencies

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update examples and integration-tests

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Fix test deadlock

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Revert back to sync lock

Revert "Fix test deadlock"

This reverts commit 4a79933df23e81573611cb14be6c5b5b2b56d4df.

Revert "Update examples and integration-tests"

This reverts commit 5423f6eb4131582909d5a4ca70adff75e27cdd0e.

Revert "Remove unused dependencies"

This reverts commit e8ecbabb5b01a7ba4ae83b8bde36295a3f64daf7.

Revert "codegen: Use async API to handle async locking"

This reverts commit ced4646541c431adcb973369b1061b7b3cbfaae1.

Revert "subxt: Block executor while decoding dynamic events"

This reverts commit 8b3ba4a5eabb29f77ac1ca671450956fc479a33d.

Revert "subxt: Switch to async::Mutex"

This reverts commit f5bde9b79394a6bf61b6b9daefc36ceaa84b82be.

* subxt: Perform RuntimeVersion update before fetching metadata

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Reintroduce MetadataInner

* Use parking lot instead of std::RwLock

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Reduce lock metadata time when decoding events

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* codegen: Update `validate_metdata` locking pattern

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt/examples: Update polkadot download link

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* tests: Wrap metadata in a helper function

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update examples/examples/subscribe_runtime_updates.rs

Co-authored-by: James Wilson <james@jsdw.me>

* subxt/updates: Update runtime if version is different

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

Co-authored-by: James Wilson <james@jsdw.me>
This commit is contained in:
Alexandru Vasile
2022-05-11 14:44:43 +03:00
committed by GitHub
parent 199cfa744b
commit 115073a33d
30 changed files with 6444 additions and 3369 deletions
+10 -14
View File
@@ -165,7 +165,7 @@ impl<'client, T: Config, E: Decode + HasModuleError, Evs: Decode>
/// level [`TransactionProgress::next_item()`] API if you'd like to handle these statuses yourself.
pub async fn wait_for_finalized_success(
self,
) -> Result<TransactionEvents<'client, T, Evs>, Error<E>> {
) -> Result<TransactionEvents<T, Evs>, Error<E>> {
let evs = self.wait_for_finalized().await?.wait_for_success().await?;
Ok(evs)
}
@@ -379,9 +379,7 @@ impl<'client, T: Config, E: Decode + HasModuleError, Evs: Decode>
///
/// **Note:** This has to download block details from the node and decode events
/// from them.
pub async fn wait_for_success(
&self,
) -> Result<TransactionEvents<'client, T, Evs>, Error<E>> {
pub async fn wait_for_success(&self) -> Result<TransactionEvents<T, Evs>, Error<E>> {
let events = self.fetch_events().await?;
// Try to find any errors; return the first one we encounter.
@@ -391,9 +389,9 @@ impl<'client, T: Config, E: Decode + HasModuleError, Evs: Decode>
let dispatch_error = E::decode(&mut &*ev.data)?;
if let Some(error_data) = dispatch_error.module_error_data() {
// Error index is utilized as the first byte from the error array.
let details = self
.client
.metadata()
let locked_metadata = self.client.metadata();
let metadata = locked_metadata.read();
let details = metadata
.error(error_data.pallet_index, error_data.error_index())?;
return Err(Error::Module(ModuleError {
pallet: details.pallet().to_string(),
@@ -416,9 +414,7 @@ impl<'client, T: Config, E: Decode + HasModuleError, Evs: Decode>
///
/// **Note:** This has to download block details from the node and decode events
/// from them.
pub async fn fetch_events(
&self,
) -> Result<TransactionEvents<'client, T, Evs>, BasicError> {
pub async fn fetch_events(&self) -> Result<TransactionEvents<T, Evs>, BasicError> {
let block = self
.client
.rpc()
@@ -450,13 +446,13 @@ impl<'client, T: Config, E: Decode + HasModuleError, Evs: Decode>
/// We can iterate over the events, or look for a specific one.
#[derive(Derivative)]
#[derivative(Debug(bound = ""))]
pub struct TransactionEvents<'client, T: Config, Evs: Decode> {
pub struct TransactionEvents<T: Config, Evs: Decode> {
ext_hash: T::Hash,
ext_idx: u32,
events: Events<'client, T, Evs>,
events: Events<T, Evs>,
}
impl<'client, T: Config, Evs: Decode> TransactionEvents<'client, T, Evs> {
impl<T: Config, Evs: Decode> TransactionEvents<T, Evs> {
/// Return the hash of the block that the transaction has made it into.
pub fn block_hash(&self) -> T::Hash {
self.events.block_hash()
@@ -468,7 +464,7 @@ impl<'client, T: Config, Evs: Decode> TransactionEvents<'client, T, Evs> {
}
/// Return all of the events in the block that the transaction made it into.
pub fn all_events_in_block(&self) -> &events::Events<'client, T, Evs> {
pub fn all_events_in_block(&self) -> &events::Events<T, Evs> {
&self.events
}