mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-20 02:21:03 +00:00
Decouples light-sync state from chain spec (#9491)
* Decouples light-sync state from chain spec This decouples the light-sync state from chain spec. First, the light-sync state currently only works with BABE+Grandpa, so not all *Substrate* based chains can use this feature. The next problem was also that this pulled the `sc-consensus-babe` and `sc-finality-grandpa` crate into `sc-chain-spec`. If a chain now wants to support the light-sync state, it needs to add the `LightSyncStateExtension` to the chain spec as an extension. This is documented in the crate level docs of `sc-sync-state-rpc`. If this extension is not available, `SyncStateRpc` fails at initialization. * Fix compilation for browser * Fmt
This commit is contained in:
@@ -28,10 +28,7 @@ use sp_core::{
|
||||
storage::{ChildInfo, Storage, StorageChild, StorageData, StorageKey},
|
||||
Bytes,
|
||||
};
|
||||
use sp_runtime::{
|
||||
traits::{Block as BlockT, NumberFor},
|
||||
BuildStorage,
|
||||
};
|
||||
use sp_runtime::BuildStorage;
|
||||
use std::{borrow::Cow, collections::HashMap, fs::File, path::PathBuf, sync::Arc};
|
||||
|
||||
enum GenesisSource<G> {
|
||||
@@ -167,7 +164,6 @@ struct ClientSpec<E> {
|
||||
consensus_engine: (),
|
||||
#[serde(skip_serializing)]
|
||||
genesis: serde::de::IgnoredAny,
|
||||
light_sync_state: Option<SerializableLightSyncState>,
|
||||
/// Mapping from `block_hash` to `wasm_code`.
|
||||
///
|
||||
/// The given `wasm_code` will be used to substitute the on-chain wasm code from the given
|
||||
@@ -231,11 +227,16 @@ impl<G, E> ChainSpec<G, E> {
|
||||
self.client_spec.boot_nodes.push(addr)
|
||||
}
|
||||
|
||||
/// Returns a reference to defined chain spec extensions.
|
||||
/// Returns a reference to the defined chain spec extensions.
|
||||
pub fn extensions(&self) -> &E {
|
||||
&self.client_spec.extensions
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the defined chain spec extensions.
|
||||
pub fn extensions_mut(&mut self) -> &mut E {
|
||||
&mut self.client_spec.extensions
|
||||
}
|
||||
|
||||
/// Create hardcoded spec.
|
||||
pub fn from_genesis<F: Fn() -> G + 'static + Send + Sync>(
|
||||
name: &str,
|
||||
@@ -259,7 +260,6 @@ impl<G, E> ChainSpec<G, E> {
|
||||
extensions,
|
||||
consensus_engine: (),
|
||||
genesis: Default::default(),
|
||||
light_sync_state: None,
|
||||
code_substitutes: HashMap::new(),
|
||||
};
|
||||
|
||||
@@ -270,11 +270,6 @@ impl<G, E> ChainSpec<G, E> {
|
||||
fn chain_type(&self) -> ChainType {
|
||||
self.client_spec.chain_type.clone()
|
||||
}
|
||||
|
||||
/// Hardcode infomation to allow light clients to sync quickly into the chain spec.
|
||||
fn set_light_sync_state(&mut self, light_sync_state: SerializableLightSyncState) {
|
||||
self.client_spec.light_sync_state = Some(light_sync_state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<G, E: serde::de::DeserializeOwned> ChainSpec<G, E> {
|
||||
@@ -379,6 +374,10 @@ where
|
||||
ChainSpec::extensions(self) as &dyn GetExtension
|
||||
}
|
||||
|
||||
fn extensions_mut(&mut self) -> &mut dyn GetExtension {
|
||||
ChainSpec::extensions_mut(self) as &mut dyn GetExtension
|
||||
}
|
||||
|
||||
fn as_json(&self, raw: bool) -> Result<String, String> {
|
||||
ChainSpec::as_json(self, raw)
|
||||
}
|
||||
@@ -395,10 +394,6 @@ where
|
||||
self.genesis = GenesisSource::Storage(storage);
|
||||
}
|
||||
|
||||
fn set_light_sync_state(&mut self, light_sync_state: SerializableLightSyncState) {
|
||||
ChainSpec::set_light_sync_state(self, light_sync_state)
|
||||
}
|
||||
|
||||
fn code_substitutes(&self) -> std::collections::HashMap<String, Vec<u8>> {
|
||||
self.client_spec
|
||||
.code_substitutes
|
||||
@@ -408,60 +403,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Hardcoded infomation that allows light clients to sync quickly.
|
||||
pub struct LightSyncState<Block: BlockT> {
|
||||
/// The header of the best finalized block.
|
||||
pub finalized_block_header: <Block as BlockT>::Header,
|
||||
/// The epoch changes tree for babe.
|
||||
pub babe_epoch_changes: sc_consensus_epochs::EpochChangesFor<Block, sc_consensus_babe::Epoch>,
|
||||
/// The babe weight of the finalized block.
|
||||
pub babe_finalized_block_weight: sp_consensus_babe::BabeBlockWeight,
|
||||
/// The authority set for grandpa.
|
||||
pub grandpa_authority_set:
|
||||
sc_finality_grandpa::AuthoritySet<<Block as BlockT>::Hash, NumberFor<Block>>,
|
||||
}
|
||||
|
||||
impl<Block: BlockT> LightSyncState<Block> {
|
||||
/// Convert into a `SerializableLightSyncState`.
|
||||
pub fn to_serializable(&self) -> SerializableLightSyncState {
|
||||
use codec::Encode;
|
||||
|
||||
SerializableLightSyncState {
|
||||
finalized_block_header: StorageData(self.finalized_block_header.encode()),
|
||||
babe_epoch_changes: StorageData(self.babe_epoch_changes.encode()),
|
||||
babe_finalized_block_weight: self.babe_finalized_block_weight,
|
||||
grandpa_authority_set: StorageData(self.grandpa_authority_set.encode()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert from a `SerializableLightSyncState`.
|
||||
pub fn from_serializable(
|
||||
serialized: &SerializableLightSyncState,
|
||||
) -> Result<Self, codec::Error> {
|
||||
Ok(Self {
|
||||
finalized_block_header: codec::Decode::decode(
|
||||
&mut &serialized.finalized_block_header.0[..],
|
||||
)?,
|
||||
babe_epoch_changes: codec::Decode::decode(&mut &serialized.babe_epoch_changes.0[..])?,
|
||||
babe_finalized_block_weight: serialized.babe_finalized_block_weight,
|
||||
grandpa_authority_set: codec::Decode::decode(
|
||||
&mut &serialized.grandpa_authority_set.0[..],
|
||||
)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// The serializable form of `LightSyncState`. Created using `LightSyncState::serialize`.
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct SerializableLightSyncState {
|
||||
finalized_block_header: StorageData,
|
||||
babe_epoch_changes: StorageData,
|
||||
babe_finalized_block_weight: sp_consensus_babe::BabeBlockWeight,
|
||||
grandpa_authority_set: StorageData,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -126,8 +126,10 @@ pub trait Extension: Serialize + DeserializeOwned + Clone {
|
||||
|
||||
/// Get an extension of specific type.
|
||||
fn get<T: 'static>(&self) -> Option<&T>;
|
||||
/// Get an extension of specific type as refernce to `Any`
|
||||
/// Get an extension of specific type as reference to `Any`.
|
||||
fn get_any(&self, t: TypeId) -> &dyn Any;
|
||||
/// Get an extension of specific type as mutable reference to `Any`.
|
||||
fn get_any_mut(&mut self, t: TypeId) -> &mut dyn Any;
|
||||
|
||||
/// Get forkable extensions of specific type.
|
||||
fn forks<BlockNumber, T>(&self) -> Option<Forks<BlockNumber, T>>
|
||||
@@ -151,6 +153,9 @@ impl Extension for crate::NoExtension {
|
||||
fn get_any(&self, _t: TypeId) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
fn get_any_mut(&mut self, _: TypeId) -> &mut dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub trait IsForks {
|
||||
@@ -240,16 +245,26 @@ where
|
||||
type Forks = Self;
|
||||
|
||||
fn get<T: 'static>(&self) -> Option<&T> {
|
||||
match TypeId::of::<T>() {
|
||||
x if x == TypeId::of::<E>() => <dyn Any>::downcast_ref(&self.base),
|
||||
_ => self.base.get(),
|
||||
if TypeId::of::<T>() == TypeId::of::<E>() {
|
||||
<dyn Any>::downcast_ref(&self.base)
|
||||
} else {
|
||||
self.base.get()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_any(&self, t: TypeId) -> &dyn Any {
|
||||
match t {
|
||||
x if x == TypeId::of::<E>() => &self.base,
|
||||
_ => self.base.get_any(t),
|
||||
if t == TypeId::of::<E>() {
|
||||
&self.base
|
||||
} else {
|
||||
self.base.get_any(t)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_any_mut(&mut self, t: TypeId) -> &mut dyn Any {
|
||||
if t == TypeId::of::<E>() {
|
||||
&mut self.base
|
||||
} else {
|
||||
self.base.get_any_mut(t)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,20 +288,31 @@ where
|
||||
pub trait GetExtension {
|
||||
/// Get an extension of specific type.
|
||||
fn get_any(&self, t: TypeId) -> &dyn Any;
|
||||
|
||||
/// Get an extension of specific type with mutable access.
|
||||
fn get_any_mut(&mut self, t: TypeId) -> &mut dyn Any;
|
||||
}
|
||||
|
||||
impl<E: Extension> GetExtension for E {
|
||||
fn get_any(&self, t: TypeId) -> &dyn Any {
|
||||
Extension::get_any(self, t)
|
||||
}
|
||||
|
||||
fn get_any_mut(&mut self, t: TypeId) -> &mut dyn Any {
|
||||
Extension::get_any_mut(self, t)
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function that queries an extension by type from `GetExtension`
|
||||
/// trait object.
|
||||
/// Helper function that queries an extension by type from `GetExtension` trait object.
|
||||
pub fn get_extension<T: 'static>(e: &dyn GetExtension) -> Option<&T> {
|
||||
<dyn Any>::downcast_ref(GetExtension::get_any(e, TypeId::of::<T>()))
|
||||
}
|
||||
|
||||
/// Helper function that queries an extension by type from `GetExtension` trait object.
|
||||
pub fn get_extension_mut<T: 'static>(e: &mut dyn GetExtension) -> Option<&mut T> {
|
||||
<dyn Any>::downcast_mut(GetExtension::get_any_mut(e, TypeId::of::<T>()))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -110,10 +110,10 @@
|
||||
mod chain_spec;
|
||||
mod extension;
|
||||
|
||||
pub use chain_spec::{
|
||||
ChainSpec as GenericChainSpec, LightSyncState, NoExtension, SerializableLightSyncState,
|
||||
pub use chain_spec::{ChainSpec as GenericChainSpec, NoExtension};
|
||||
pub use extension::{
|
||||
get_extension, get_extension_mut, Extension, Fork, Forks, GetExtension, Group,
|
||||
};
|
||||
pub use extension::{get_extension, Extension, Fork, Forks, GetExtension, Group};
|
||||
pub use sc_chain_spec_derive::{ChainSpecExtension, ChainSpecGroup};
|
||||
|
||||
use sc_network::config::MultiaddrWithPeerId;
|
||||
@@ -169,8 +169,10 @@ pub trait ChainSpec: BuildStorage + Send + Sync {
|
||||
///
|
||||
/// Returns an empty JSON object if 'properties' not defined in config
|
||||
fn properties(&self) -> Properties;
|
||||
/// Returns a reference to defined chain spec extensions.
|
||||
/// Returns a reference to the defined chain spec extensions.
|
||||
fn extensions(&self) -> &dyn GetExtension;
|
||||
/// Returns a mutable reference to the defined chain spec extensions.
|
||||
fn extensions_mut(&mut self) -> &mut dyn GetExtension;
|
||||
/// Add a bootnode to the list.
|
||||
fn add_boot_node(&mut self, addr: MultiaddrWithPeerId);
|
||||
/// Return spec as JSON.
|
||||
@@ -183,8 +185,6 @@ pub trait ChainSpec: BuildStorage + Send + Sync {
|
||||
///
|
||||
/// This will be used as storage at genesis.
|
||||
fn set_storage(&mut self, storage: Storage);
|
||||
/// Hardcode infomation to allow light clients to sync quickly into the chain spec.
|
||||
fn set_light_sync_state(&mut self, light_sync_state: SerializableLightSyncState);
|
||||
/// Returns code substitutes that should be used for the on chain wasm.
|
||||
fn code_substitutes(&self) -> std::collections::HashMap<String, Vec<u8>>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user