mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-19 19:21:03 +00:00
Introduce Backend trait to allow different RPC (or other) backends to be implemented (#1126)
* WIP backend trait * WIP converting higher level stuff to using Backend impl * more implementing new backend trait, mainly storage focused * Get core code compiling with new backend bits * subxt crate checks passing * fix tests * cargo fmt * clippy/fixes * merging and other fixes * fix test * fix lightclient code * Fix some broken doc links * another book link fix * fix broken test when moving default_rpc_client * fix dry_run test * fix more tests; lightclient and wasm * fix wasm tests * fix some doc examples * use next() instead of next_item() * missing next_item() -> next()s * move legacy RPc methods to LegacyRpcMethods type to host generic param instead of RpcClient * standardise on all RpcClient types prefixed with Rpc, and 'raw' trait types prefixed with RawRpc so it's less ocnfusing which is which * rename fixes * doc fixes * Add back system_dryRun RPC method and rename tx.dry_run() to tx.validate(), to signal that the calls are different * Add a test that we return the correct extrinsic hash from submit() * add TransactionValid details back, and protect against out of range bytes * add test for decoding transaction validation from empty bytes * fix clippy warning
This commit is contained in:
@@ -2,7 +2,8 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
use crate::{client::OnlineClientT, error::Error, events::Events, rpc::types::StorageKey, Config};
|
||||
use crate::backend::{Backend, BackendExt, BlockRef};
|
||||
use crate::{client::OnlineClientT, error::Error, events::Events, Config};
|
||||
use derivative::Derivative;
|
||||
use std::future::Future;
|
||||
|
||||
@@ -38,12 +39,12 @@ where
|
||||
/// but may run into errors attempting to work with them.
|
||||
pub fn at(
|
||||
&self,
|
||||
block_hash: T::Hash,
|
||||
block_ref: impl Into<BlockRef<T::Hash>>,
|
||||
) -> impl Future<Output = Result<Events<T>, Error>> + Send + 'static {
|
||||
self.at_or_latest(Some(block_hash))
|
||||
self.at_or_latest(Some(block_ref.into()))
|
||||
}
|
||||
|
||||
/// Obtain events at the latest block hash.
|
||||
/// Obtain events for the latest block.
|
||||
pub fn at_latest(&self) -> impl Future<Output = Result<Events<T>, Error>> + Send + 'static {
|
||||
self.at_or_latest(None)
|
||||
}
|
||||
@@ -51,49 +52,45 @@ where
|
||||
/// Obtain events at some block hash.
|
||||
fn at_or_latest(
|
||||
&self,
|
||||
block_hash: Option<T::Hash>,
|
||||
block_ref: Option<BlockRef<T::Hash>>,
|
||||
) -> impl Future<Output = Result<Events<T>, Error>> + Send + 'static {
|
||||
// Clone and pass the client in like this so that we can explicitly
|
||||
// return a Future that's Send + 'static, rather than tied to &self.
|
||||
let client = self.client.clone();
|
||||
async move {
|
||||
// If block hash is not provided, get the hash
|
||||
// for the latest block and use that.
|
||||
let block_hash = match block_hash {
|
||||
Some(hash) => hash,
|
||||
None => client
|
||||
.rpc()
|
||||
.block_hash(None)
|
||||
.await?
|
||||
.expect("didn't pass a block number; qed"),
|
||||
// If a block ref isn't provided, we'll get the latest best block to use.
|
||||
let block_ref = match block_ref {
|
||||
Some(r) => r,
|
||||
None => client.backend().latest_best_block_ref().await?,
|
||||
};
|
||||
|
||||
let event_bytes = get_event_bytes(&client, Some(block_hash)).await?;
|
||||
Ok(Events::new(client.metadata(), block_hash, event_bytes))
|
||||
let event_bytes = get_event_bytes(client.backend(), block_ref.hash()).await?;
|
||||
Ok(Events::new(
|
||||
client.metadata(),
|
||||
block_ref.hash(),
|
||||
event_bytes,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The storage key needed to access events.
|
||||
fn system_events_key() -> StorageKey {
|
||||
let mut storage_key = sp_core_hashing::twox_128(b"System").to_vec();
|
||||
storage_key.extend(sp_core_hashing::twox_128(b"Events").to_vec());
|
||||
StorageKey(storage_key)
|
||||
fn system_events_key() -> [u8; 32] {
|
||||
let a = sp_core_hashing::twox_128(b"System");
|
||||
let b = sp_core_hashing::twox_128(b"Events");
|
||||
let mut res = [0; 32];
|
||||
res[0..16].clone_from_slice(&a);
|
||||
res[16..32].clone_from_slice(&b);
|
||||
res
|
||||
}
|
||||
|
||||
// Get the event bytes from the provided client, at the provided block hash.
|
||||
pub(crate) async fn get_event_bytes<T, Client>(
|
||||
client: &Client,
|
||||
block_hash: Option<T::Hash>,
|
||||
) -> Result<Vec<u8>, Error>
|
||||
where
|
||||
T: Config,
|
||||
Client: OnlineClientT<T>,
|
||||
{
|
||||
Ok(client
|
||||
.rpc()
|
||||
.storage(&system_events_key().0, block_hash)
|
||||
pub(crate) async fn get_event_bytes<T: Config>(
|
||||
backend: &dyn Backend<T>,
|
||||
block_hash: T::Hash,
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
Ok(backend
|
||||
.storage_fetch_value(system_events_key().to_vec(), block_hash)
|
||||
.await?
|
||||
.map(|e| e.0)
|
||||
.unwrap_or_else(Vec::new))
|
||||
.unwrap_or_default())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user