mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 08:47:57 +00:00
Inject hashed prefix for remote-ext (#8960)
* Inject for remote-ext * Update utils/frame/remote-externalities/src/lib.rs Co-authored-by: Zeke Mostov <32168567+emostov@users.noreply.github.com> * Update utils/frame/remote-externalities/src/lib.rs Co-authored-by: Zeke Mostov <32168567+emostov@users.noreply.github.com> * Apply suggestions from code review * Apply suggestions from code review Co-authored-by: Zeke Mostov <32168567+emostov@users.noreply.github.com>
This commit is contained in:
@@ -19,87 +19,6 @@
|
||||
//!
|
||||
//! An equivalent of `sp_io::TestExternalities` that can load its state from a remote substrate
|
||||
//! based chain, or a local state snapshot file.
|
||||
//!
|
||||
//! #### Runtime to Test Against
|
||||
//!
|
||||
//! While not absolutely necessary, you most likely need a `Runtime` equivalent in your test setup
|
||||
//! through which you can infer storage types. There are two options here:
|
||||
//!
|
||||
//! 1. Build a mock runtime, similar how to you would build one in a pallet test (see example
|
||||
//! below). The very important point here is that this mock needs to hold real values for types
|
||||
//! that matter for you, based on the chain of interest. Some typical ones are:
|
||||
//!
|
||||
//! - `sp_runtime::AccountId32` as `AccountId`.
|
||||
//! - `u32` as `BlockNumber`.
|
||||
//! - `u128` as Balance.
|
||||
//!
|
||||
//! Once you have your `Runtime`, you can use it for storage type resolution and do things like
|
||||
//! `<my_pallet::Pallet<Runtime>>::storage_getter()` or `<my_pallet::StorageItem<Runtime>>::get()`.
|
||||
//!
|
||||
//! 2. Or, you can use a real runtime.
|
||||
//!
|
||||
//! ### Example
|
||||
//!
|
||||
//! With a test runtime
|
||||
//!
|
||||
//! ```ignore
|
||||
//! use remote_externalities::Builder;
|
||||
//!
|
||||
//! #[derive(Clone, Eq, PartialEq, Debug, Default)]
|
||||
//! pub struct TestRuntime;
|
||||
//!
|
||||
//! use frame_system as system;
|
||||
//! impl_outer_origin! {
|
||||
//! pub enum Origin for TestRuntime {}
|
||||
//! }
|
||||
//!
|
||||
//! impl frame_system::Config for TestRuntime {
|
||||
//! ..
|
||||
//! // we only care about these two for now. The rest can be mock. The block number type of
|
||||
//! // kusama is u32.
|
||||
//! type BlockNumber = u32;
|
||||
//! type Header = Header;
|
||||
//! ..
|
||||
//! }
|
||||
//!
|
||||
//! #[test]
|
||||
//! fn test_runtime_works() {
|
||||
//! let hash: Hash =
|
||||
//! hex!["f9a4ce984129569f63edc01b1c13374779f9384f1befd39931ffdcc83acf63a7"].into();
|
||||
//! let parent: Hash =
|
||||
//! hex!["540922e96a8fcaf945ed23c6f09c3e189bd88504ec945cc2171deaebeaf2f37e"].into();
|
||||
//! Builder::new()
|
||||
//! .at(hash)
|
||||
//! .module("System")
|
||||
//! .build()
|
||||
//! .execute_with(|| {
|
||||
//! assert_eq!(
|
||||
//! // note: the hash corresponds to 3098546. We can check only the parent.
|
||||
//! // https://polkascan.io/kusama/block/3098546
|
||||
//! <frame_system::Pallet<Runtime>>::block_hash(3098545u32),
|
||||
//! parent,
|
||||
//! )
|
||||
//! });
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! Or with the real kusama runtime.
|
||||
//!
|
||||
//! ```ignore
|
||||
//! use remote_externalities::Builder;
|
||||
//! use kusama_runtime::Runtime;
|
||||
//!
|
||||
//! #[test]
|
||||
//! fn test_runtime_works() {
|
||||
//! let hash: Hash =
|
||||
//! hex!["f9a4ce984129569f63edc01b1c13374779f9384f1befd39931ffdcc83acf63a7"].into();
|
||||
//! Builder::new()
|
||||
//! .at(hash)
|
||||
//! .module("Staking")
|
||||
//! .build()
|
||||
//! .execute_with(|| assert_eq!(<pallet_staking::Module<Runtime>>::validator_count(), 400));
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use std::{
|
||||
fs,
|
||||
@@ -235,8 +154,10 @@ impl Default for SnapshotConfig {
|
||||
|
||||
/// Builder for remote-externalities.
|
||||
pub struct Builder<B: BlockT> {
|
||||
/// Pallets to inject their prefix into the externalities.
|
||||
/// Custom key-pairs to be injected into the externalities.
|
||||
inject: Vec<KeyPair>,
|
||||
/// Storage entry key prefixes to be injected into the externalities. The *hashed* prefix must be given.
|
||||
hashed_prefixes: Vec<Vec<u8>>,
|
||||
/// connectivity mode, online or offline.
|
||||
mode: Mode<B>,
|
||||
}
|
||||
@@ -245,7 +166,7 @@ pub struct Builder<B: BlockT> {
|
||||
// that.
|
||||
impl<B: BlockT> Default for Builder<B> {
|
||||
fn default() -> Self {
|
||||
Self { inject: Default::default(), mode: Default::default() }
|
||||
Self { inject: Default::default(), mode: Default::default(), hashed_prefixes: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,7 +315,7 @@ impl<B: BlockT> Builder<B> {
|
||||
|
||||
/// initialize `Self` from state snapshot. Panics if the file does not exist.
|
||||
fn load_state_snapshot(&self, path: &Path) -> Result<Vec<KeyPair>, &'static str> {
|
||||
info!(target: LOG_TARGET, "scraping keypairs from state snapshot {:?}", path,);
|
||||
info!(target: LOG_TARGET, "scraping key-pairs from state snapshot {:?}", path,);
|
||||
let bytes = fs::read(path).map_err(|_| "fs::read failed.")?;
|
||||
Decode::decode(&mut &*bytes).map_err(|_| "decode failed")
|
||||
}
|
||||
@@ -407,9 +328,9 @@ impl<B: BlockT> Builder<B> {
|
||||
.at
|
||||
.expect("online config must be initialized by this point; qed.")
|
||||
.clone();
|
||||
info!(target: LOG_TARGET, "scraping keypairs from remote @ {:?}", at);
|
||||
info!(target: LOG_TARGET, "scraping key-pairs from remote @ {:?}", at);
|
||||
|
||||
let keys_and_values = if config.modules.len() > 0 {
|
||||
let mut keys_and_values = if config.modules.len() > 0 {
|
||||
let mut filtered_kv = vec![];
|
||||
for f in config.modules.iter() {
|
||||
let hashed_prefix = StorageKey(twox_128(f.as_bytes()).to_vec());
|
||||
@@ -429,6 +350,12 @@ impl<B: BlockT> Builder<B> {
|
||||
self.rpc_get_pairs_paged(StorageKey(vec![]), at).await?
|
||||
};
|
||||
|
||||
for prefix in &self.hashed_prefixes {
|
||||
info!(target: LOG_TARGET, "adding data for hashed prefix: {:?}", HexDisplay::from(prefix));
|
||||
let additional_key_values = self.rpc_get_pairs_paged(StorageKey(prefix.to_vec()), at).await?;
|
||||
keys_and_values.extend(additional_key_values);
|
||||
}
|
||||
|
||||
Ok(keys_and_values)
|
||||
}
|
||||
|
||||
@@ -491,6 +418,12 @@ impl<B: BlockT> Builder<B> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Inject a hashed prefix. This is treated as-is, and should be pre-hashed.
|
||||
pub fn inject_hashed_prefix(mut self, hashed: &[u8]) -> Self {
|
||||
self.hashed_prefixes.push(hashed.to_vec());
|
||||
self
|
||||
}
|
||||
|
||||
/// Configure a state snapshot to be used.
|
||||
pub fn mode(mut self, mode: Mode<B>) -> Self {
|
||||
self.mode = mode;
|
||||
|
||||
Reference in New Issue
Block a user