test alex's PR

This commit is contained in:
Niklas Adolfsson
2022-06-28 17:46:01 +02:00
parent 43062cb1bb
commit 5ee0bb5ca5
7 changed files with 84 additions and 107 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ chameleon = "0.1.0"
scale-info = { version = "1.0.0", features = ["bit-vec"] } scale-info = { version = "1.0.0", features = ["bit-vec"] }
futures = "0.3.13" futures = "0.3.13"
hex = "0.4.3" hex = "0.4.3"
jsonrpsee = { version = "0.8.0", features = ["macros", "async-client", "client-ws-transport"] } jsonrpsee = { git = "https://github.com/paritytech/jsonrpsee", branch = "696_trait_bounds", features = ["macros", "async-client", "client-ws-transport"] }
log = "0.4.14" log = "0.4.14"
num-traits = { version = "0.2.14", default-features = false } num-traits = { version = "0.2.14", default-features = false }
serde = { version = "1.0.124", features = ["derive"] } serde = { version = "1.0.124", features = ["derive"] }
+10 -22
View File
@@ -94,17 +94,10 @@ impl ClientBuilder {
}; };
let rpc = Rpc::new(client); let rpc = Rpc::new(client);
let (metadata_bytes, genesis_hash, runtime_version, properties) = future::join4( let (metadata_bytes, genesis_hash, runtime_version, properties) = future::join4(
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::metadata(rpc.inner()), SubxtRpcApiClient::<T>::metadata(rpc.inner()),
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::genesis_hash( SubxtRpcApiClient::<T>::genesis_hash(rpc.inner()),
rpc.inner(), SubxtRpcApiClient::<T>::runtime_version(rpc.inner(), None),
), SubxtRpcApiClient::<T>::system_properties(rpc.inner()),
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::runtime_version(
rpc.inner(),
None,
),
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::system_properties(
rpc.inner(),
),
) )
.await; .await;
let metadata_bytes = metadata_bytes?; let metadata_bytes = metadata_bytes?;
@@ -247,11 +240,9 @@ where
let bytes = extrinsic.encode().into(); let bytes = extrinsic.encode().into();
// Submit and watch for transaction progress. // Submit and watch for transaction progress.
let sub = SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::watch_extrinsic( let sub =
self.client.rpc().inner(), SubxtRpcApiClient::<T>::watch_extrinsic(self.client.rpc().inner(), bytes)
bytes, .await?;
)
.await?;
Ok(TransactionProgress::new(sub, self.client, ext_hash)) Ok(TransactionProgress::new(sub, self.client, ext_hash))
} }
@@ -280,12 +271,9 @@ where
.encode() .encode()
.into(); .into();
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::submit_extrinsic( SubxtRpcApiClient::<T>::submit_extrinsic(self.client.rpc().inner(), bytes)
self.client.rpc().inner(), .await
bytes, .map_err(Into::into)
)
.await
.map_err(Into::into)
} }
/// Creates a signed extrinsic. /// Creates a signed extrinsic.
+1 -8
View File
@@ -78,14 +78,7 @@ pub trait Config: 'static {
type Signature: Verify + Encode + Send + Sync + 'static; type Signature: Verify + Encode + Send + Sync + 'static;
/// Extrinsic type within blocks. /// Extrinsic type within blocks.
// TODO(niklasad1): I have no idea if this ok or not ^^ => won't work otherwise type Extrinsic: Parameter + Extrinsic + Debug + MaybeSerializeDeserialize;
// because `jsonrpsee` requires `Deserialize + Send + Sync` for the return types.
type Extrinsic: Parameter
+ Extrinsic
+ Debug
+ MaybeSerializeDeserialize
+ Send
+ Sync;
} }
/// Parameter trait copied from `substrate::frame_support` /// Parameter trait copied from `substrate::frame_support`
+45 -30
View File
@@ -79,14 +79,18 @@ use sp_runtime::generic::{
}; };
/// subxt RPC API. /// subxt RPC API.
#[rpc(client)] #[rpc(
pub trait SubxtRpcApi<Hash, Header, Xt: Serialize> { client,
client_bounds(
C::Hash: DeserializeOwned + Serialize, C::Header: Serialize, C::Extrinsic: Serialize)
)]
pub trait SubxtRpcApi<C: Config> {
/// Fetch a storage key /// Fetch a storage key
#[method(name = "state_getStorage")] #[method(name = "state_getStorage")]
async fn storage( async fn storage(
&self, &self,
key: &StorageKey, key: &StorageKey,
hash: Option<Hash>, hash: Option<C::Hash>,
) -> RpcResult<Option<StorageData>>; ) -> RpcResult<Option<StorageData>>;
/// Returns the keys with prefix with pagination support. /// Returns the keys with prefix with pagination support.
@@ -98,7 +102,7 @@ pub trait SubxtRpcApi<Hash, Header, Xt: Serialize> {
prefix: Option<StorageKey>, prefix: Option<StorageKey>,
count: u32, count: u32,
start_key: Option<StorageKey>, start_key: Option<StorageKey>,
hash: Option<Hash>, hash: Option<C::Hash>,
) -> RpcResult<Vec<StorageKey>>; ) -> RpcResult<Vec<StorageKey>>;
/// Query historical storage entries /// Query historical storage entries
@@ -106,21 +110,21 @@ pub trait SubxtRpcApi<Hash, Header, Xt: Serialize> {
async fn query_storage( async fn query_storage(
&self, &self,
keys: Vec<StorageKey>, keys: Vec<StorageKey>,
from: Hash, from: C::Hash,
to: Option<Hash>, to: Option<C::Hash>,
) -> RpcResult<Vec<StorageChangeSet<Hash>>>; ) -> RpcResult<Vec<StorageChangeSet<C::Hash>>>;
/// Query historical storage entries /// Query historical storage entries
#[method(name = "state_queryStorageAt")] #[method(name = "state_queryStorageAt")]
async fn query_storage_at( async fn query_storage_at(
&self, &self,
keys: &[StorageKey], keys: &[StorageKey],
at: Option<Hash>, at: Option<C::Hash>,
) -> RpcResult<Vec<StorageChangeSet<Hash>>>; ) -> RpcResult<Vec<StorageChangeSet<C::Hash>>>;
/// Fetch the genesis hash /// Fetch the genesis hash
#[method(name = "chain_getBlockHash")] #[method(name = "chain_getBlockHash")]
async fn genesis_hash(&self) -> RpcResult<Hash>; async fn genesis_hash(&self) -> RpcResult<C::Hash>;
/// Fetch the metadata as bytes. /// Fetch the metadata as bytes.
#[method(name = "state_getMetadata")] #[method(name = "state_getMetadata")]
@@ -144,37 +148,37 @@ pub trait SubxtRpcApi<Hash, Header, Xt: Serialize> {
/// Fetch the runtime version /// Fetch the runtime version
#[method(name = "state_getRuntimeVersion")] #[method(name = "state_getRuntimeVersion")]
async fn runtime_version(&self, at: Option<Hash>) -> RpcResult<RuntimeVersion>; async fn runtime_version(&self, at: Option<C::Hash>) -> RpcResult<RuntimeVersion>;
/// Get a header /// Get a header
#[method(name = "state_getRuntimeVersion")] #[method(name = "state_getRuntimeVersion")]
async fn header(&self, hash: Option<Hash>) -> RpcResult<Option<Header>>; async fn header(&self, hash: Option<C::Hash>) -> RpcResult<Option<C::Header>>;
/// Get a block hash, returns hash of latest block by default /// Get a block hash, returns hash of latest block by default
#[method(name = "chain_getBlockHash")] #[method(name = "chain_getBlockHash")]
async fn block_hash( async fn block_hash(
&self, &self,
block_number: Option<BlockNumber>, block_number: Option<BlockNumber>,
) -> RpcResult<Option<Hash>>; ) -> RpcResult<Option<C::Hash>>;
/// Get a block hash of the latest finalized block /// Get a block hash of the latest finalized block
#[method(name = "chain_getFinalizedHead")] #[method(name = "chain_getFinalizedHead")]
async fn finalized_head(&self) -> RpcResult<Hash>; async fn finalized_head(&self) -> RpcResult<C::Hash>;
/// Get proof of storage entries at a specific block's state. /// Get proof of storage entries at a specific block's state.
#[method(name = "state_getReadProof")] #[method(name = "state_getReadProof")]
async fn read_proof( async fn read_proof(
&self, &self,
keys: Vec<StorageKey>, keys: Vec<StorageKey>,
hash: Option<Hash>, hash: Option<C::Hash>,
) -> RpcResult<ReadProof<Hash>>; ) -> RpcResult<ReadProof<C::Hash>>;
/// Get a Block /// Get a Block
#[method(name = "chain_getBlock")] #[method(name = "chain_getBlock")]
async fn block( async fn block(
&self, &self,
hash: Option<Hash>, hash: Option<C::Hash>,
) -> RpcResult<Option<SignedBlock<Block<Header, Xt>>>>; ) -> RpcResult<Option<SignedBlock<Block<C::Header, C::Extrinsic>>>>;
/// Insert a key into the keystore. /// Insert a key into the keystore.
#[method(name = "author_insertKey")] #[method(name = "author_insertKey")]
@@ -205,30 +209,41 @@ pub trait SubxtRpcApi<Hash, Header, Xt: Serialize> {
/// Create and submit an extrinsic and return corresponding Hash if successful /// Create and submit an extrinsic and return corresponding Hash if successful
#[method(name = "author_submitExtrinsic")] #[method(name = "author_submitExtrinsic")]
async fn submit_extrinsic(&self, extrinsic: Bytes) -> RpcResult<Hash>; async fn submit_extrinsic(&self, extrinsic: Bytes) -> RpcResult<C::Hash>;
/// Subscribe to System Events that are imported into blocks. /// Subscribe to System Events that are imported into blocks.
/// ///
/// *WARNING* these may not be included in the finalized chain, use /// *WARNING* these may not be included in the finalized chain, use
/// `subscribe_finalized_events` to ensure events are finalized. /// `subscribe_finalized_events` to ensure events are finalized.
#[subscription(name = "state_subscribeStorage", item = StorageChangeSet<Hash>)] #[subscription(
fn subscribe_events(&self) -> RpcResult<()>; name = "state_subscribeStorage",
unsubscribe = "state_unsubscribeStorage",
item = StorageChangeSet<C::Hash>
)]
fn subscribe_events(&self);
/// Subscribe to blocks. /// Subscribe to blocks.
#[subscription(name = "chain_subscribeNewHeads", item = Header)] #[subscription(
fn subscribe_blocks(&self) -> RpcResult<()>; name = "chain_subscribeNewHeads",
unsubscribe = "chain_unsubscribeNewHeads",
item = C::Header)]
fn subscribe_blocks(&self);
/// Subscribe to finalized blocks. /// Subscribe to finalized blocks.
#[subscription(name = "chain_subscribeFinalizedHeads", item = Header)] #[subscription(
fn subscribe_finalized_blocks(&self) -> RpcResult<()>; name = "chain_subscribeFinalizedHeads",
unsubscribe = "chain_unsubscribeFinalizedHeads",
item = C::Header
)]
fn subscribe_finalized_blocks(&self);
/// Create and submit an extrinsic and return a subscription to the events triggered. /// Create and submit an extrinsic and return a subscription to the events triggered.
#[subscription( #[subscription(
name = "author_submitAndWatchExtrinsic", name = "author_submitAndWatchExtrinsic",
unsubscribe_aliases = ["author_unwatchExtrinsic"], unsubscribe = "author_unwatchExtrinsic",
item = SubstrateTransactionStatus<Hash, Hash> item = SubstrateTransactionStatus<C::Hash, C::Hash>
)] )]
fn watch_extrinsic<X: Encode>(&self, xt: Bytes) -> RpcResult<()>; fn watch_extrinsic<X: Encode>(&self, xt: Bytes);
} }
/// A number type that can be serialized both as a number or a string that encodes a number in a /// A number type that can be serialized both as a number or a string that encodes a number in a
@@ -393,7 +408,7 @@ impl<T: Config> Rpc<T> {
Ok(EventStorageSubscription::Finalized( Ok(EventStorageSubscription::Finalized(
FinalizedEventStorageSubscription::new( FinalizedEventStorageSubscription::new(
self.clone(), self.clone(),
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::subscribe_finalized_blocks(&*self.client).await?, SubxtRpcApiClient::<T>::subscribe_finalized_blocks(&*self.client).await?,
), ),
)) ))
} }
@@ -404,7 +419,7 @@ pub async fn ws_client(url: &str) -> Result<RpcClient, RpcError> {
let (sender, receiver) = ws_transport(url).await?; let (sender, receiver) = ws_transport(url).await?;
Ok(RpcClientBuilder::default() Ok(RpcClientBuilder::default()
.max_notifs_per_subscription(4096) .max_notifs_per_subscription(4096)
.build(sender, receiver)) .build_with_tokio(sender, receiver))
} }
async fn ws_transport(url: &str) -> Result<(WsSender, WsReceiver), RpcError> { async fn ws_transport(url: &str) -> Result<(WsSender, WsReceiver), RpcError> {
+24 -43
View File
@@ -168,12 +168,7 @@ impl<'a, T: Config> StorageClient<'a, T> {
hash: Option<T::Hash>, hash: Option<T::Hash>,
) -> Result<Option<V>, BasicError> { ) -> Result<Option<V>, BasicError> {
if let Some(data) = if let Some(data) =
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::storage( SubxtRpcApiClient::<T>::storage(&*self.rpc.client, &key, hash).await?
&*self.rpc.client,
&key,
hash,
)
.await?
{ {
Ok(Some(Decode::decode(&mut &data.0[..])?)) Ok(Some(Decode::decode(&mut &data.0[..])?))
} else { } else {
@@ -187,13 +182,9 @@ impl<'a, T: Config> StorageClient<'a, T> {
key: StorageKey, key: StorageKey,
hash: Option<T::Hash>, hash: Option<T::Hash>,
) -> Result<Option<StorageData>, BasicError> { ) -> Result<Option<StorageData>, BasicError> {
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::storage( SubxtRpcApiClient::<T>::storage(&*self.rpc.client, &key, hash)
&*self.rpc.client, .await
&key, .map_err(Into::into)
hash,
)
.await
.map_err(Into::into)
} }
/// Fetch a StorageKey with an optional block hash. /// Fetch a StorageKey with an optional block hash.
@@ -231,14 +222,9 @@ impl<'a, T: Config> StorageClient<'a, T> {
from: T::Hash, from: T::Hash,
to: Option<T::Hash>, to: Option<T::Hash>,
) -> Result<Vec<StorageChangeSet<T::Hash>>, BasicError> { ) -> Result<Vec<StorageChangeSet<T::Hash>>, BasicError> {
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::query_storage( SubxtRpcApiClient::<T>::query_storage(&*self.rpc.client, keys, from, to)
&*self.rpc.client, .await
keys, .map_err(Into::into)
from,
to,
)
.await
.map_err(Into::into)
} }
/// Fetch up to `count` keys for a storage map in lexicographic order. /// Fetch up to `count` keys for a storage map in lexicographic order.
@@ -251,15 +237,14 @@ impl<'a, T: Config> StorageClient<'a, T> {
hash: Option<T::Hash>, hash: Option<T::Hash>,
) -> Result<Vec<StorageKey>, BasicError> { ) -> Result<Vec<StorageKey>, BasicError> {
let prefix = StorageKeyPrefix::new::<F>().to_storage_key(); let prefix = StorageKeyPrefix::new::<F>().to_storage_key();
let keys = let keys = SubxtRpcApiClient::<T>::storage_keys_paged(
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::storage_keys_paged( &*self.rpc.client,
&*self.rpc.client, Some(prefix),
Some(prefix), count,
count, start_key,
start_key, hash,
hash, )
) .await?;
.await?;
Ok(keys) Ok(keys)
} }
@@ -271,12 +256,9 @@ impl<'a, T: Config> StorageClient<'a, T> {
let hash = if let Some(hash) = hash { let hash = if let Some(hash) = hash {
hash hash
} else { } else {
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::block_hash( SubxtRpcApiClient::<T>::block_hash(&*self.rpc.client, None)
&*self.rpc.client, .await?
None, .expect("didn't pass a block number; qed")
)
.await?
.expect("didn't pass a block number; qed")
}; };
Ok(KeyIter { Ok(KeyIter {
client: self.clone(), client: self.clone(),
@@ -317,13 +299,12 @@ impl<'a, T: Config, F: StorageEntry> KeyIter<'a, T, F> {
self.start_key = keys.last().cloned(); self.start_key = keys.last().cloned();
let change_sets = let change_sets = SubxtRpcApiClient::<T>::query_storage_at(
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::query_storage_at( &*self.client.rpc.client,
&*self.client.rpc.client, &keys,
&keys, Some(self.hash),
Some(self.hash), )
) .await?;
.await?;
for change_set in change_sets { for change_set in change_sets {
for (k, v) in change_set.changes { for (k, v) in change_set.changes {
if let Some(v) = v { if let Some(v) = v {
+1 -1
View File
@@ -248,7 +248,7 @@ impl<T: Config> FinalizedEventStorageSubscription<T> {
read_subscription_response("HeaderSubscription", &mut self.subscription) read_subscription_response("HeaderSubscription", &mut self.subscription)
.await?; .await?;
self.storage_changes.extend( self.storage_changes.extend(
SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::query_storage_at( SubxtRpcApiClient::<T>::query_storage_at(
&*self.rpc.client, &*self.rpc.client,
&[self.storage_key.clone()], &[self.storage_key.clone()],
Some(header.hash()), Some(header.hash()),
+2 -2
View File
@@ -392,7 +392,7 @@ impl<'client, T: Config, E: Decode> TransactionInBlock<'client, T, E> {
/// **Note:** This has to download block details from the node and decode events /// **Note:** This has to download block details from the node and decode events
/// from them. /// from them.
pub async fn fetch_events(&self) -> Result<TransactionEvents<T>, BasicError> { pub async fn fetch_events(&self) -> Result<TransactionEvents<T>, BasicError> {
let block = SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::block( let block = SubxtRpcApiClient::<T>::block(
&*self.client.rpc().client, &*self.client.rpc().client,
Some(self.block_hash), Some(self.block_hash),
) )
@@ -409,7 +409,7 @@ impl<'client, T: Config, E: Decode> TransactionInBlock<'client, T, E> {
// extrinsic, the extrinsic should be in there somewhere.. // extrinsic, the extrinsic should be in there somewhere..
.ok_or(BasicError::Transaction(TransactionError::BlockHashNotFound))?; .ok_or(BasicError::Transaction(TransactionError::BlockHashNotFound))?;
let raw_events = SubxtRpcApiClient::<T::Hash, T::Header, T::Extrinsic>::storage( let raw_events = SubxtRpcApiClient::<T>::storage(
&*self.client.rpc().client, &*self.client.rpc().client,
&StorageKey::from(SystemEvents::new()), &StorageKey::from(SystemEvents::new()),
Some(self.block_hash), Some(self.block_hash),