Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 408e803

Browse files
kianenigmaemostov
andauthored
Inject hashed prefix for remote-ext (#8960)
* Inject for remote-ext * Update utils/frame/remote-externalities/src/lib.rs Co-authored-by: Zeke Mostov <[email protected]> * Update utils/frame/remote-externalities/src/lib.rs Co-authored-by: Zeke Mostov <[email protected]> * Apply suggestions from code review * Apply suggestions from code review Co-authored-by: Zeke Mostov <[email protected]>
1 parent 04aa0e9 commit 408e803

File tree

2 files changed

+20
-87
lines changed

2 files changed

+20
-87
lines changed

frame/system/src/offchain.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ pub trait AppCrypto<Public, Signature> {
447447
// TODO [#5663] Could this be just `T::Signature as traits::Verify>::Signer`?
448448
// Seems that this may cause issues with bounds resolution.
449449
pub trait SigningTypes: crate::Config {
450-
/// A public key that is capable of identifing `AccountId`s.
450+
/// A public key that is capable of identifying `AccountId`s.
451451
///
452452
/// Usually that's either a raw crypto public key (e.g. `sr25519::Public`) or
453453
/// an aggregate type for multiple crypto public keys, like `MulitSigner`.

utils/frame/remote-externalities/src/lib.rs

Lines changed: 19 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -19,87 +19,6 @@
1919
//!
2020
//! An equivalent of `sp_io::TestExternalities` that can load its state from a remote substrate
2121
//! based chain, or a local state snapshot file.
22-
//!
23-
//! #### Runtime to Test Against
24-
//!
25-
//! While not absolutely necessary, you most likely need a `Runtime` equivalent in your test setup
26-
//! through which you can infer storage types. There are two options here:
27-
//!
28-
//! 1. Build a mock runtime, similar how to you would build one in a pallet test (see example
29-
//! below). The very important point here is that this mock needs to hold real values for types
30-
//! that matter for you, based on the chain of interest. Some typical ones are:
31-
//!
32-
//! - `sp_runtime::AccountId32` as `AccountId`.
33-
//! - `u32` as `BlockNumber`.
34-
//! - `u128` as Balance.
35-
//!
36-
//! Once you have your `Runtime`, you can use it for storage type resolution and do things like
37-
//! `<my_pallet::Pallet<Runtime>>::storage_getter()` or `<my_pallet::StorageItem<Runtime>>::get()`.
38-
//!
39-
//! 2. Or, you can use a real runtime.
40-
//!
41-
//! ### Example
42-
//!
43-
//! With a test runtime
44-
//!
45-
//! ```ignore
46-
//! use remote_externalities::Builder;
47-
//!
48-
//! #[derive(Clone, Eq, PartialEq, Debug, Default)]
49-
//! pub struct TestRuntime;
50-
//!
51-
//! use frame_system as system;
52-
//! impl_outer_origin! {
53-
//! pub enum Origin for TestRuntime {}
54-
//! }
55-
//!
56-
//! impl frame_system::Config for TestRuntime {
57-
//! ..
58-
//! // we only care about these two for now. The rest can be mock. The block number type of
59-
//! // kusama is u32.
60-
//! type BlockNumber = u32;
61-
//! type Header = Header;
62-
//! ..
63-
//! }
64-
//!
65-
//! #[test]
66-
//! fn test_runtime_works() {
67-
//! let hash: Hash =
68-
//! hex!["f9a4ce984129569f63edc01b1c13374779f9384f1befd39931ffdcc83acf63a7"].into();
69-
//! let parent: Hash =
70-
//! hex!["540922e96a8fcaf945ed23c6f09c3e189bd88504ec945cc2171deaebeaf2f37e"].into();
71-
//! Builder::new()
72-
//! .at(hash)
73-
//! .module("System")
74-
//! .build()
75-
//! .execute_with(|| {
76-
//! assert_eq!(
77-
//! // note: the hash corresponds to 3098546. We can check only the parent.
78-
//! // https://polkascan.io/kusama/block/3098546
79-
//! <frame_system::Pallet<Runtime>>::block_hash(3098545u32),
80-
//! parent,
81-
//! )
82-
//! });
83-
//! }
84-
//! ```
85-
//!
86-
//! Or with the real kusama runtime.
87-
//!
88-
//! ```ignore
89-
//! use remote_externalities::Builder;
90-
//! use kusama_runtime::Runtime;
91-
//!
92-
//! #[test]
93-
//! fn test_runtime_works() {
94-
//! let hash: Hash =
95-
//! hex!["f9a4ce984129569f63edc01b1c13374779f9384f1befd39931ffdcc83acf63a7"].into();
96-
//! Builder::new()
97-
//! .at(hash)
98-
//! .module("Staking")
99-
//! .build()
100-
//! .execute_with(|| assert_eq!(<pallet_staking::Module<Runtime>>::validator_count(), 400));
101-
//! }
102-
//! ```
10322
10423
use std::{
10524
fs,
@@ -235,8 +154,10 @@ impl Default for SnapshotConfig {
235154

236155
/// Builder for remote-externalities.
237156
pub struct Builder<B: BlockT> {
238-
/// Pallets to inject their prefix into the externalities.
157+
/// Custom key-pairs to be injected into the externalities.
239158
inject: Vec<KeyPair>,
159+
/// Storage entry key prefixes to be injected into the externalities. The *hashed* prefix must be given.
160+
hashed_prefixes: Vec<Vec<u8>>,
240161
/// connectivity mode, online or offline.
241162
mode: Mode<B>,
242163
}
@@ -245,7 +166,7 @@ pub struct Builder<B: BlockT> {
245166
// that.
246167
impl<B: BlockT> Default for Builder<B> {
247168
fn default() -> Self {
248-
Self { inject: Default::default(), mode: Default::default() }
169+
Self { inject: Default::default(), mode: Default::default(), hashed_prefixes: Default::default() }
249170
}
250171
}
251172

@@ -394,7 +315,7 @@ impl<B: BlockT> Builder<B> {
394315

395316
/// initialize `Self` from state snapshot. Panics if the file does not exist.
396317
fn load_state_snapshot(&self, path: &Path) -> Result<Vec<KeyPair>, &'static str> {
397-
info!(target: LOG_TARGET, "scraping keypairs from state snapshot {:?}", path,);
318+
info!(target: LOG_TARGET, "scraping key-pairs from state snapshot {:?}", path,);
398319
let bytes = fs::read(path).map_err(|_| "fs::read failed.")?;
399320
Decode::decode(&mut &*bytes).map_err(|_| "decode failed")
400321
}
@@ -407,9 +328,9 @@ impl<B: BlockT> Builder<B> {
407328
.at
408329
.expect("online config must be initialized by this point; qed.")
409330
.clone();
410-
info!(target: LOG_TARGET, "scraping keypairs from remote @ {:?}", at);
331+
info!(target: LOG_TARGET, "scraping key-pairs from remote @ {:?}", at);
411332

412-
let keys_and_values = if config.modules.len() > 0 {
333+
let mut keys_and_values = if config.modules.len() > 0 {
413334
let mut filtered_kv = vec![];
414335
for f in config.modules.iter() {
415336
let hashed_prefix = StorageKey(twox_128(f.as_bytes()).to_vec());
@@ -429,6 +350,12 @@ impl<B: BlockT> Builder<B> {
429350
self.rpc_get_pairs_paged(StorageKey(vec![]), at).await?
430351
};
431352

353+
for prefix in &self.hashed_prefixes {
354+
info!(target: LOG_TARGET, "adding data for hashed prefix: {:?}", HexDisplay::from(prefix));
355+
let additional_key_values = self.rpc_get_pairs_paged(StorageKey(prefix.to_vec()), at).await?;
356+
keys_and_values.extend(additional_key_values);
357+
}
358+
432359
Ok(keys_and_values)
433360
}
434361

@@ -491,6 +418,12 @@ impl<B: BlockT> Builder<B> {
491418
self
492419
}
493420

421+
/// Inject a hashed prefix. This is treated as-is, and should be pre-hashed.
422+
pub fn inject_hashed_prefix(mut self, hashed: &[u8]) -> Self {
423+
self.hashed_prefixes.push(hashed.to_vec());
424+
self
425+
}
426+
494427
/// Configure a state snapshot to be used.
495428
pub fn mode(mut self, mode: Mode<B>) -> Self {
496429
self.mode = mode;

0 commit comments

Comments
 (0)