mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 17:31:05 +00:00
Metadata V16: Be more dynamic over which hasher is used. (#1974)
* Use DynamicHasher256 to support Blake2 or Keccack depending on chain * remove Config::Hash associated type, replace with HashFor<Config> alias * Fix doc links * fix wasm tests * Don't strip system pallet associated types. check System.Hashing, not Hash. Rename BlockHash trait to Hash * Tweak comment * fmt * fix merge * Fix typo
This commit is contained in:
@@ -4,8 +4,14 @@
|
||||
|
||||
use crate::custom_values::CustomValuesClient;
|
||||
use crate::{
|
||||
blocks::BlocksClient, constants::ConstantsClient, events::EventsClient,
|
||||
runtime_api::RuntimeApiClient, storage::StorageClient, tx::TxClient, Config, Metadata,
|
||||
blocks::BlocksClient,
|
||||
config::{Config, HashFor},
|
||||
constants::ConstantsClient,
|
||||
events::EventsClient,
|
||||
runtime_api::RuntimeApiClient,
|
||||
storage::StorageClient,
|
||||
tx::TxClient,
|
||||
Metadata,
|
||||
};
|
||||
|
||||
use derive_where::derive_where;
|
||||
@@ -19,11 +25,14 @@ pub trait OfflineClientT<T: Config>: Clone + Send + Sync + 'static {
|
||||
fn metadata(&self) -> Metadata;
|
||||
|
||||
/// Return the provided genesis hash.
|
||||
fn genesis_hash(&self) -> T::Hash;
|
||||
fn genesis_hash(&self) -> HashFor<T>;
|
||||
|
||||
/// Return the provided [`RuntimeVersion`].
|
||||
fn runtime_version(&self) -> RuntimeVersion;
|
||||
|
||||
/// Return the hasher used on the chain.
|
||||
fn hasher(&self) -> T::Hasher;
|
||||
|
||||
/// Return the [subxt_core::client::ClientState] (metadata, runtime version and genesis hash).
|
||||
fn client_state(&self) -> ClientState<T> {
|
||||
ClientState {
|
||||
@@ -74,19 +83,22 @@ pub trait OfflineClientT<T: Config>: Clone + Send + Sync + 'static {
|
||||
#[derive_where(Debug, Clone)]
|
||||
pub struct OfflineClient<T: Config> {
|
||||
inner: Arc<ClientState<T>>,
|
||||
hasher: T::Hasher,
|
||||
}
|
||||
|
||||
impl<T: Config> OfflineClient<T> {
|
||||
/// Construct a new [`OfflineClient`], providing
|
||||
/// the necessary runtime and compile-time arguments.
|
||||
pub fn new(
|
||||
genesis_hash: T::Hash,
|
||||
genesis_hash: HashFor<T>,
|
||||
runtime_version: RuntimeVersion,
|
||||
metadata: impl Into<Metadata>,
|
||||
) -> OfflineClient<T> {
|
||||
let metadata = metadata.into();
|
||||
let hasher = <T::Hasher as subxt_core::config::Hasher>::new(&metadata);
|
||||
|
||||
OfflineClient {
|
||||
hasher,
|
||||
inner: Arc::new(ClientState {
|
||||
genesis_hash,
|
||||
runtime_version,
|
||||
@@ -96,7 +108,7 @@ impl<T: Config> OfflineClient<T> {
|
||||
}
|
||||
|
||||
/// Return the genesis hash.
|
||||
pub fn genesis_hash(&self) -> T::Hash {
|
||||
pub fn genesis_hash(&self) -> HashFor<T> {
|
||||
self.inner.genesis_hash
|
||||
}
|
||||
|
||||
@@ -110,6 +122,11 @@ impl<T: Config> OfflineClient<T> {
|
||||
self.inner.metadata.clone()
|
||||
}
|
||||
|
||||
/// Return the hasher used for the chain.
|
||||
pub fn hasher(&self) -> T::Hasher {
|
||||
self.hasher
|
||||
}
|
||||
|
||||
// Just a copy of the most important trait methods so that people
|
||||
// don't need to import the trait for most things:
|
||||
|
||||
@@ -140,7 +157,7 @@ impl<T: Config> OfflineClient<T> {
|
||||
}
|
||||
|
||||
impl<T: Config> OfflineClientT<T> for OfflineClient<T> {
|
||||
fn genesis_hash(&self) -> T::Hash {
|
||||
fn genesis_hash(&self) -> HashFor<T> {
|
||||
self.genesis_hash()
|
||||
}
|
||||
fn runtime_version(&self) -> RuntimeVersion {
|
||||
@@ -149,6 +166,9 @@ impl<T: Config> OfflineClientT<T> for OfflineClient<T> {
|
||||
fn metadata(&self) -> Metadata {
|
||||
self.metadata()
|
||||
}
|
||||
fn hasher(&self) -> T::Hasher {
|
||||
self.hasher()
|
||||
}
|
||||
}
|
||||
|
||||
// For ergonomics; cloning a client is deliberately fairly cheap (via Arc),
|
||||
|
||||
@@ -7,13 +7,14 @@ use crate::custom_values::CustomValuesClient;
|
||||
use crate::{
|
||||
backend::{legacy::LegacyBackend, rpc::RpcClient, Backend, BackendExt, StreamOfResults},
|
||||
blocks::{BlockRef, BlocksClient},
|
||||
config::{Config, HashFor},
|
||||
constants::ConstantsClient,
|
||||
error::Error,
|
||||
events::EventsClient,
|
||||
runtime_api::RuntimeApiClient,
|
||||
storage::StorageClient,
|
||||
tx::TxClient,
|
||||
Config, Metadata,
|
||||
Metadata,
|
||||
};
|
||||
use derive_where::derive_where;
|
||||
use futures::future;
|
||||
@@ -37,9 +38,10 @@ pub struct OnlineClient<T: Config> {
|
||||
|
||||
#[derive_where(Debug)]
|
||||
struct Inner<T: Config> {
|
||||
genesis_hash: T::Hash,
|
||||
genesis_hash: HashFor<T>,
|
||||
runtime_version: RuntimeVersion,
|
||||
metadata: Metadata,
|
||||
hasher: T::Hasher,
|
||||
}
|
||||
|
||||
impl<T: Config> std::fmt::Debug for OnlineClient<T> {
|
||||
@@ -103,7 +105,7 @@ impl<T: Config> OnlineClient<T> {
|
||||
/// If you're unsure what you're doing, prefer one of the alternate methods to instantiate
|
||||
/// a client.
|
||||
pub fn from_rpc_client_with(
|
||||
genesis_hash: T::Hash,
|
||||
genesis_hash: HashFor<T>,
|
||||
runtime_version: RuntimeVersion,
|
||||
metadata: impl Into<Metadata>,
|
||||
rpc_client: impl Into<RpcClient>,
|
||||
@@ -141,16 +143,22 @@ impl<T: Config> OnlineClient<T> {
|
||||
/// If you're unsure what you're doing, prefer one of the alternate methods to instantiate
|
||||
/// a client.
|
||||
pub fn from_backend_with<B: Backend<T>>(
|
||||
genesis_hash: T::Hash,
|
||||
genesis_hash: HashFor<T>,
|
||||
runtime_version: RuntimeVersion,
|
||||
metadata: impl Into<Metadata>,
|
||||
backend: Arc<B>,
|
||||
) -> Result<OnlineClient<T>, Error> {
|
||||
use subxt_core::config::Hasher;
|
||||
|
||||
let metadata = metadata.into();
|
||||
let hasher = T::Hasher::new(&metadata);
|
||||
|
||||
Ok(OnlineClient {
|
||||
inner: Arc::new(RwLock::new(Inner {
|
||||
genesis_hash,
|
||||
runtime_version,
|
||||
metadata: metadata.into(),
|
||||
metadata,
|
||||
hasher,
|
||||
})),
|
||||
backend,
|
||||
})
|
||||
@@ -159,7 +167,7 @@ impl<T: Config> OnlineClient<T> {
|
||||
/// Fetch the metadata from substrate using the runtime API.
|
||||
async fn fetch_metadata(
|
||||
backend: &dyn Backend<T>,
|
||||
block_hash: T::Hash,
|
||||
block_hash: HashFor<T>,
|
||||
) -> Result<Metadata, Error> {
|
||||
#[cfg(feature = "unstable-metadata")]
|
||||
{
|
||||
@@ -184,7 +192,7 @@ impl<T: Config> OnlineClient<T> {
|
||||
/// Fetch the latest stable metadata from the node.
|
||||
async fn fetch_latest_stable_metadata(
|
||||
backend: &dyn Backend<T>,
|
||||
block_hash: T::Hash,
|
||||
block_hash: HashFor<T>,
|
||||
) -> Result<Metadata, Error> {
|
||||
// This is the latest stable metadata that subxt can utilize.
|
||||
const V15_METADATA_VERSION: u32 = 15;
|
||||
@@ -246,6 +254,11 @@ impl<T: Config> OnlineClient<T> {
|
||||
ClientRuntimeUpdater(self.clone())
|
||||
}
|
||||
|
||||
/// Return the hasher configured for hashing blocks and extrinsics.
|
||||
pub fn hasher(&self) -> T::Hasher {
|
||||
self.inner.read().expect("shouldn't be poisoned").hasher
|
||||
}
|
||||
|
||||
/// Return the [`Metadata`] used in this client.
|
||||
pub fn metadata(&self) -> Metadata {
|
||||
let inner = self.inner.read().expect("shouldn't be poisoned");
|
||||
@@ -264,7 +277,7 @@ impl<T: Config> OnlineClient<T> {
|
||||
}
|
||||
|
||||
/// Return the genesis hash.
|
||||
pub fn genesis_hash(&self) -> T::Hash {
|
||||
pub fn genesis_hash(&self) -> HashFor<T> {
|
||||
let inner = self.inner.read().expect("shouldn't be poisoned");
|
||||
inner.genesis_hash
|
||||
}
|
||||
@@ -275,7 +288,7 @@ impl<T: Config> OnlineClient<T> {
|
||||
///
|
||||
/// Setting a custom genesis hash may leave Subxt unable to
|
||||
/// submit valid transactions.
|
||||
pub fn set_genesis_hash(&self, genesis_hash: T::Hash) {
|
||||
pub fn set_genesis_hash(&self, genesis_hash: HashFor<T>) {
|
||||
let mut inner = self.inner.write().expect("shouldn't be poisoned");
|
||||
inner.genesis_hash = genesis_hash;
|
||||
}
|
||||
@@ -355,12 +368,15 @@ impl<T: Config> OfflineClientT<T> for OnlineClient<T> {
|
||||
fn metadata(&self) -> Metadata {
|
||||
self.metadata()
|
||||
}
|
||||
fn genesis_hash(&self) -> T::Hash {
|
||||
fn genesis_hash(&self) -> HashFor<T> {
|
||||
self.genesis_hash()
|
||||
}
|
||||
fn runtime_version(&self) -> RuntimeVersion {
|
||||
self.runtime_version()
|
||||
}
|
||||
fn hasher(&self) -> T::Hasher {
|
||||
self.hasher()
|
||||
}
|
||||
// This is provided by default, but we can optimise here and only lock once:
|
||||
fn client_state(&self) -> ClientState<T> {
|
||||
let inner = self.inner.read().expect("shouldn't be poisoned");
|
||||
@@ -501,10 +517,20 @@ impl Update {
|
||||
async fn wait_runtime_upgrade_in_finalized_block<T: Config>(
|
||||
client: &OnlineClient<T>,
|
||||
runtime_version: &RuntimeVersion,
|
||||
) -> Option<Result<BlockRef<T::Hash>, Error>> {
|
||||
) -> Option<Result<BlockRef<HashFor<T>>, Error>> {
|
||||
use scale_value::At;
|
||||
|
||||
let mut block_sub = match client.backend().stream_finalized_block_headers().await {
|
||||
let hasher = client
|
||||
.inner
|
||||
.read()
|
||||
.expect("Lock shouldn't be poisoned")
|
||||
.hasher;
|
||||
|
||||
let mut block_sub = match client
|
||||
.backend()
|
||||
.stream_finalized_block_headers(hasher)
|
||||
.await
|
||||
{
|
||||
Ok(s) => s,
|
||||
Err(err) => return Some(Err(err)),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user