mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 03:31:10 +00:00
Adapt RemoteExternalities and its related types to be used with generic hash parameters (#3953)
Closes https://github.com/paritytech/polkadot-sdk/issues/3737 --------- Co-authored-by: command-bot <> Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: Bastian Köcher <git@kchr.de>
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
|
||||||
|
# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
|
||||||
|
|
||||||
|
title: Adapt RemoteExternalities and its related types to be used with generic hash parameters
|
||||||
|
|
||||||
|
doc:
|
||||||
|
- audience: Node Dev
|
||||||
|
description: |
|
||||||
|
Modify `RemoteExternalities`, `Mode`, `OnlineConfig` and`Snapshot` to rely now on generic parameter, instead of `BlockT`.
|
||||||
|
Adjust in consequence their implementation to be compatible with types `Hash`, or if possible any generic.
|
||||||
|
Adapt Builder struct and implementation for these bounds.
|
||||||
|
|
||||||
|
crates:
|
||||||
|
- name: frame-remote-externalities
|
||||||
|
bump: major
|
||||||
|
- name: pallet-state-trie-migration
|
||||||
|
bump: patch
|
||||||
|
- name: try-runtime-cli
|
||||||
|
bump: patch
|
||||||
@@ -1698,8 +1698,10 @@ pub(crate) mod remote_tests {
|
|||||||
///
|
///
|
||||||
/// This will print some very useful statistics, make sure [`crate::LOG_TARGET`] is enabled.
|
/// This will print some very useful statistics, make sure [`crate::LOG_TARGET`] is enabled.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) async fn run_with_limits<Runtime, Block>(limits: MigrationLimits, mode: Mode<Block>)
|
pub(crate) async fn run_with_limits<Runtime, Block>(
|
||||||
where
|
limits: MigrationLimits,
|
||||||
|
mode: Mode<Block::Hash>,
|
||||||
|
) where
|
||||||
Runtime: crate::Config<Hash = H256>,
|
Runtime: crate::Config<Hash = H256>,
|
||||||
Block: BlockT<Hash = H256> + DeserializeOwned,
|
Block: BlockT<Hash = H256> + DeserializeOwned,
|
||||||
Block::Header: serde::de::DeserializeOwned,
|
Block::Header: serde::de::DeserializeOwned,
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ use sp_core::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
traits::{Block as BlockT, HashingFor},
|
traits::{Block as BlockT, Hash, HashingFor},
|
||||||
StateVersion,
|
StateVersion,
|
||||||
};
|
};
|
||||||
use sp_state_machine::TestExternalities;
|
use sp_state_machine::TestExternalities;
|
||||||
@@ -63,21 +63,21 @@ const SNAPSHOT_VERSION: SnapshotVersion = Compact(3);
|
|||||||
|
|
||||||
/// The snapshot that we store on disk.
|
/// The snapshot that we store on disk.
|
||||||
#[derive(Decode, Encode)]
|
#[derive(Decode, Encode)]
|
||||||
struct Snapshot<B: BlockT> {
|
struct Snapshot<H> {
|
||||||
snapshot_version: SnapshotVersion,
|
snapshot_version: SnapshotVersion,
|
||||||
state_version: StateVersion,
|
state_version: StateVersion,
|
||||||
block_hash: B::Hash,
|
block_hash: H,
|
||||||
// <Vec<Key, (Value, MemoryDbRefCount)>>
|
// <Vec<Key, (Value, MemoryDbRefCount)>>
|
||||||
raw_storage: Vec<(Vec<u8>, (Vec<u8>, i32))>,
|
raw_storage: Vec<(Vec<u8>, (Vec<u8>, i32))>,
|
||||||
storage_root: B::Hash,
|
storage_root: H,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: BlockT> Snapshot<B> {
|
impl<H: Decode> Snapshot<H> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
state_version: StateVersion,
|
state_version: StateVersion,
|
||||||
block_hash: B::Hash,
|
block_hash: H,
|
||||||
raw_storage: Vec<(Vec<u8>, (Vec<u8>, i32))>,
|
raw_storage: Vec<(Vec<u8>, (Vec<u8>, i32))>,
|
||||||
storage_root: B::Hash,
|
storage_root: H,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
snapshot_version: SNAPSHOT_VERSION,
|
snapshot_version: SNAPSHOT_VERSION,
|
||||||
@@ -88,7 +88,7 @@ impl<B: BlockT> Snapshot<B> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load(path: &PathBuf) -> Result<Snapshot<B>, &'static str> {
|
fn load(path: &PathBuf) -> Result<Snapshot<H>, &'static str> {
|
||||||
let bytes = fs::read(path).map_err(|_| "fs::read failed.")?;
|
let bytes = fs::read(path).map_err(|_| "fs::read failed.")?;
|
||||||
// The first item in the SCALE encoded struct bytes is the snapshot version. We decode and
|
// The first item in the SCALE encoded struct bytes is the snapshot version. We decode and
|
||||||
// check that first, before proceeding to decode the rest of the snapshot.
|
// check that first, before proceeding to decode the rest of the snapshot.
|
||||||
@@ -105,21 +105,21 @@ impl<B: BlockT> Snapshot<B> {
|
|||||||
|
|
||||||
/// An externalities that acts exactly the same as [`sp_io::TestExternalities`] but has a few extra
|
/// An externalities that acts exactly the same as [`sp_io::TestExternalities`] but has a few extra
|
||||||
/// bits and pieces to it, and can be loaded remotely.
|
/// bits and pieces to it, and can be loaded remotely.
|
||||||
pub struct RemoteExternalities<B: BlockT> {
|
pub struct RemoteExternalities<H: Hash> {
|
||||||
/// The inner externalities.
|
/// The inner externalities.
|
||||||
pub inner_ext: TestExternalities<HashingFor<B>>,
|
pub inner_ext: TestExternalities<H>,
|
||||||
/// The block hash it which we created this externality env.
|
/// The block hash with which we created this externality env.
|
||||||
pub block_hash: B::Hash,
|
pub block_hash: H::Out,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: BlockT> Deref for RemoteExternalities<B> {
|
impl<H: Hash> Deref for RemoteExternalities<H> {
|
||||||
type Target = TestExternalities<HashingFor<B>>;
|
type Target = TestExternalities<H>;
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.inner_ext
|
&self.inner_ext
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: BlockT> DerefMut for RemoteExternalities<B> {
|
impl<H: Hash> DerefMut for RemoteExternalities<H> {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
&mut self.inner_ext
|
&mut self.inner_ext
|
||||||
}
|
}
|
||||||
@@ -127,16 +127,16 @@ impl<B: BlockT> DerefMut for RemoteExternalities<B> {
|
|||||||
|
|
||||||
/// The execution mode.
|
/// The execution mode.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum Mode<B: BlockT> {
|
pub enum Mode<H> {
|
||||||
/// Online. Potentially writes to a snapshot file.
|
/// Online. Potentially writes to a snapshot file.
|
||||||
Online(OnlineConfig<B>),
|
Online(OnlineConfig<H>),
|
||||||
/// Offline. Uses a state snapshot file and needs not any client config.
|
/// Offline. Uses a state snapshot file and needs not any client config.
|
||||||
Offline(OfflineConfig),
|
Offline(OfflineConfig),
|
||||||
/// Prefer using a snapshot file if it exists, else use a remote server.
|
/// Prefer using a snapshot file if it exists, else use a remote server.
|
||||||
OfflineOrElseOnline(OfflineConfig, OnlineConfig<B>),
|
OfflineOrElseOnline(OfflineConfig, OnlineConfig<H>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: BlockT> Default for Mode<B> {
|
impl<H> Default for Mode<H> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Mode::Online(OnlineConfig::default())
|
Mode::Online(OnlineConfig::default())
|
||||||
}
|
}
|
||||||
@@ -221,10 +221,10 @@ impl From<HttpClient> for Transport {
|
|||||||
///
|
///
|
||||||
/// A state snapshot config may be present and will be written to in that case.
|
/// A state snapshot config may be present and will be written to in that case.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct OnlineConfig<B: BlockT> {
|
pub struct OnlineConfig<H> {
|
||||||
/// The block hash at which to get the runtime state. Will be latest finalized head if not
|
/// The block hash at which to get the runtime state. Will be latest finalized head if not
|
||||||
/// provided.
|
/// provided.
|
||||||
pub at: Option<B::Hash>,
|
pub at: Option<H>,
|
||||||
/// An optional state snapshot file to WRITE to, not for reading. Not written if set to `None`.
|
/// An optional state snapshot file to WRITE to, not for reading. Not written if set to `None`.
|
||||||
pub state_snapshot: Option<SnapshotConfig>,
|
pub state_snapshot: Option<SnapshotConfig>,
|
||||||
/// The pallets to scrape. These values are hashed and added to `hashed_prefix`.
|
/// The pallets to scrape. These values are hashed and added to `hashed_prefix`.
|
||||||
@@ -240,7 +240,7 @@ pub struct OnlineConfig<B: BlockT> {
|
|||||||
pub hashed_keys: Vec<Vec<u8>>,
|
pub hashed_keys: Vec<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: BlockT> OnlineConfig<B> {
|
impl<H: Clone> OnlineConfig<H> {
|
||||||
/// Return rpc (http) client reference.
|
/// Return rpc (http) client reference.
|
||||||
fn rpc_client(&self) -> &HttpClient {
|
fn rpc_client(&self) -> &HttpClient {
|
||||||
self.transport
|
self.transport
|
||||||
@@ -248,12 +248,12 @@ impl<B: BlockT> OnlineConfig<B> {
|
|||||||
.expect("http client must have been initialized by now; qed.")
|
.expect("http client must have been initialized by now; qed.")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn at_expected(&self) -> B::Hash {
|
fn at_expected(&self) -> H {
|
||||||
self.at.expect("block at must be initialized; qed")
|
self.at.clone().expect("block at must be initialized; qed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: BlockT> Default for OnlineConfig<B> {
|
impl<H> Default for OnlineConfig<H> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
transport: Transport::from(DEFAULT_HTTP_ENDPOINT.to_owned()),
|
transport: Transport::from(DEFAULT_HTTP_ENDPOINT.to_owned()),
|
||||||
@@ -267,7 +267,7 @@ impl<B: BlockT> Default for OnlineConfig<B> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: BlockT> From<String> for OnlineConfig<B> {
|
impl<H> From<String> for OnlineConfig<H> {
|
||||||
fn from(t: String) -> Self {
|
fn from(t: String) -> Self {
|
||||||
Self { transport: t.into(), ..Default::default() }
|
Self { transport: t.into(), ..Default::default() }
|
||||||
}
|
}
|
||||||
@@ -307,7 +307,7 @@ pub struct Builder<B: BlockT> {
|
|||||||
/// The keys that will be excluded from the final externality. The *hashed* key must be given.
|
/// The keys that will be excluded from the final externality. The *hashed* key must be given.
|
||||||
hashed_blacklist: Vec<Vec<u8>>,
|
hashed_blacklist: Vec<Vec<u8>>,
|
||||||
/// Connectivity mode, online or offline.
|
/// Connectivity mode, online or offline.
|
||||||
mode: Mode<B>,
|
mode: Mode<B::Hash>,
|
||||||
/// If provided, overwrite the state version with this. Otherwise, the state_version of the
|
/// If provided, overwrite the state version with this. Otherwise, the state_version of the
|
||||||
/// remote node is used. All cache files also store their state version.
|
/// remote node is used. All cache files also store their state version.
|
||||||
///
|
///
|
||||||
@@ -328,7 +328,7 @@ impl<B: BlockT> Default for Builder<B> {
|
|||||||
|
|
||||||
// Mode methods
|
// Mode methods
|
||||||
impl<B: BlockT> Builder<B> {
|
impl<B: BlockT> Builder<B> {
|
||||||
fn as_online(&self) -> &OnlineConfig<B> {
|
fn as_online(&self) -> &OnlineConfig<B::Hash> {
|
||||||
match &self.mode {
|
match &self.mode {
|
||||||
Mode::Online(config) => config,
|
Mode::Online(config) => config,
|
||||||
Mode::OfflineOrElseOnline(_, config) => config,
|
Mode::OfflineOrElseOnline(_, config) => config,
|
||||||
@@ -336,7 +336,7 @@ impl<B: BlockT> Builder<B> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_online_mut(&mut self) -> &mut OnlineConfig<B> {
|
fn as_online_mut(&mut self) -> &mut OnlineConfig<B::Hash> {
|
||||||
match &mut self.mode {
|
match &mut self.mode {
|
||||||
Mode::Online(config) => config,
|
Mode::Online(config) => config,
|
||||||
Mode::OfflineOrElseOnline(_, config) => config,
|
Mode::OfflineOrElseOnline(_, config) => config,
|
||||||
@@ -1055,7 +1055,7 @@ where
|
|||||||
// If we need to save a snapshot, save the raw storage and root hash to the snapshot.
|
// If we need to save a snapshot, save the raw storage and root hash to the snapshot.
|
||||||
if let Some(path) = self.as_online().state_snapshot.clone().map(|c| c.path) {
|
if let Some(path) = self.as_online().state_snapshot.clone().map(|c| c.path) {
|
||||||
let (raw_storage, storage_root) = pending_ext.into_raw_snapshot();
|
let (raw_storage, storage_root) = pending_ext.into_raw_snapshot();
|
||||||
let snapshot = Snapshot::<B>::new(
|
let snapshot = Snapshot::<B::Hash>::new(
|
||||||
state_version,
|
state_version,
|
||||||
self.as_online()
|
self.as_online()
|
||||||
.at
|
.at
|
||||||
@@ -1083,7 +1083,7 @@ where
|
|||||||
Ok(pending_ext)
|
Ok(pending_ext)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn do_load_remote(&mut self) -> Result<RemoteExternalities<B>, &'static str> {
|
async fn do_load_remote(&mut self) -> Result<RemoteExternalities<HashingFor<B>>, &'static str> {
|
||||||
self.init_remote_client().await?;
|
self.init_remote_client().await?;
|
||||||
let block_hash = self.as_online().at_expected();
|
let block_hash = self.as_online().at_expected();
|
||||||
let inner_ext = self.load_remote_and_maybe_save().await?;
|
let inner_ext = self.load_remote_and_maybe_save().await?;
|
||||||
@@ -1093,12 +1093,12 @@ where
|
|||||||
fn do_load_offline(
|
fn do_load_offline(
|
||||||
&mut self,
|
&mut self,
|
||||||
config: OfflineConfig,
|
config: OfflineConfig,
|
||||||
) -> Result<RemoteExternalities<B>, &'static str> {
|
) -> Result<RemoteExternalities<HashingFor<B>>, &'static str> {
|
||||||
let mut sp = Spinner::with_timer(Spinners::Dots, "Loading snapshot...".into());
|
let mut sp = Spinner::with_timer(Spinners::Dots, "Loading snapshot...".into());
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
info!(target: LOG_TARGET, "Loading snapshot from {:?}", &config.state_snapshot.path);
|
info!(target: LOG_TARGET, "Loading snapshot from {:?}", &config.state_snapshot.path);
|
||||||
let Snapshot { snapshot_version: _, block_hash, state_version, raw_storage, storage_root } =
|
let Snapshot { snapshot_version: _, block_hash, state_version, raw_storage, storage_root } =
|
||||||
Snapshot::<B>::load(&config.state_snapshot.path)?;
|
Snapshot::<B::Hash>::load(&config.state_snapshot.path)?;
|
||||||
|
|
||||||
let inner_ext = TestExternalities::from_raw_snapshot(
|
let inner_ext = TestExternalities::from_raw_snapshot(
|
||||||
raw_storage,
|
raw_storage,
|
||||||
@@ -1110,7 +1110,9 @@ where
|
|||||||
Ok(RemoteExternalities { inner_ext, block_hash })
|
Ok(RemoteExternalities { inner_ext, block_hash })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn pre_build(mut self) -> Result<RemoteExternalities<B>, &'static str> {
|
pub(crate) async fn pre_build(
|
||||||
|
mut self,
|
||||||
|
) -> Result<RemoteExternalities<HashingFor<B>>, &'static str> {
|
||||||
let mut ext = match self.mode.clone() {
|
let mut ext = match self.mode.clone() {
|
||||||
Mode::Offline(config) => self.do_load_offline(config)?,
|
Mode::Offline(config) => self.do_load_offline(config)?,
|
||||||
Mode::Online(_) => self.do_load_remote().await?,
|
Mode::Online(_) => self.do_load_remote().await?,
|
||||||
@@ -1175,7 +1177,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Configure a state snapshot to be used.
|
/// Configure a state snapshot to be used.
|
||||||
pub fn mode(mut self, mode: Mode<B>) -> Self {
|
pub fn mode(mut self, mode: Mode<B::Hash>) -> Self {
|
||||||
self.mode = mode;
|
self.mode = mode;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -1186,7 +1188,7 @@ where
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn build(self) -> Result<RemoteExternalities<B>, &'static str> {
|
pub async fn build(self) -> Result<RemoteExternalities<HashingFor<B>>, &'static str> {
|
||||||
let mut ext = self.pre_build().await?;
|
let mut ext = self.pre_build().await?;
|
||||||
ext.commit_all().unwrap();
|
ext.commit_all().unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ impl State {
|
|||||||
executor: &WasmExecutor<HostFns>,
|
executor: &WasmExecutor<HostFns>,
|
||||||
state_snapshot: Option<SnapshotConfig>,
|
state_snapshot: Option<SnapshotConfig>,
|
||||||
try_runtime_check: bool,
|
try_runtime_check: bool,
|
||||||
) -> sc_cli::Result<RemoteExternalities<Block>>
|
) -> sc_cli::Result<RemoteExternalities<HashingFor<Block>>>
|
||||||
where
|
where
|
||||||
Block::Header: DeserializeOwned,
|
Block::Header: DeserializeOwned,
|
||||||
<Block::Hash as FromStr>::Err: Debug,
|
<Block::Hash as FromStr>::Err: Debug,
|
||||||
|
|||||||
Reference in New Issue
Block a user