mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 00:31:07 +00:00
Define StorageDoubleMapKeyProvider
Signed-off-by: Serban Iorga <serban@parity.io>
This commit is contained in:
committed by
Bastian Köcher
parent
f9af3f2d6e
commit
cd36d1e15f
@@ -80,7 +80,8 @@ struct UpdateParachainHeadArtifacts {
|
|||||||
#[frame_support::pallet]
|
#[frame_support::pallet]
|
||||||
pub mod pallet {
|
pub mod pallet {
|
||||||
use super::*;
|
use super::*;
|
||||||
use bp_runtime::{BasicOperatingMode, OwnedBridgeModule};
|
use bp_parachains::ImportedParaHeadsKeyProvider;
|
||||||
|
use bp_runtime::{BasicOperatingMode, OwnedBridgeModule, StorageDoubleMapKeyProvider};
|
||||||
use frame_support::pallet_prelude::*;
|
use frame_support::pallet_prelude::*;
|
||||||
use frame_system::pallet_prelude::*;
|
use frame_system::pallet_prelude::*;
|
||||||
|
|
||||||
@@ -165,8 +166,14 @@ pub mod pallet {
|
|||||||
|
|
||||||
/// Parachain heads which have been imported into the pallet.
|
/// Parachain heads which have been imported into the pallet.
|
||||||
#[pallet::storage]
|
#[pallet::storage]
|
||||||
pub type ImportedParaHeads<T: Config<I>, I: 'static = ()> =
|
pub type ImportedParaHeads<T: Config<I>, I: 'static = ()> = StorageDoubleMap<
|
||||||
StorageDoubleMap<_, Blake2_128Concat, ParaId, Blake2_128Concat, ParaHash, ParaHead>;
|
_,
|
||||||
|
<ImportedParaHeadsKeyProvider as StorageDoubleMapKeyProvider>::Hasher1,
|
||||||
|
<ImportedParaHeadsKeyProvider as StorageDoubleMapKeyProvider>::Key1,
|
||||||
|
<ImportedParaHeadsKeyProvider as StorageDoubleMapKeyProvider>::Hasher2,
|
||||||
|
<ImportedParaHeadsKeyProvider as StorageDoubleMapKeyProvider>::Key2,
|
||||||
|
<ImportedParaHeadsKeyProvider as StorageDoubleMapKeyProvider>::Value,
|
||||||
|
>;
|
||||||
|
|
||||||
/// A ring buffer of imported parachain head hashes. Ordered by the insertion time.
|
/// A ring buffer of imported parachain head hashes. Ordered by the insertion time.
|
||||||
#[pallet::storage]
|
#[pallet::storage]
|
||||||
@@ -513,7 +520,8 @@ mod tests {
|
|||||||
run_test, test_relay_header, Origin, TestRuntime, PARAS_PALLET_NAME, UNTRACKED_PARACHAIN_ID,
|
run_test, test_relay_header, Origin, TestRuntime, PARAS_PALLET_NAME, UNTRACKED_PARACHAIN_ID,
|
||||||
};
|
};
|
||||||
|
|
||||||
use bp_runtime::{BasicOperatingMode, OwnedBridgeModuleError};
|
use bp_parachains::ImportedParaHeadsKeyProvider;
|
||||||
|
use bp_runtime::{BasicOperatingMode, OwnedBridgeModuleError, StorageDoubleMapKeyProvider};
|
||||||
use bp_test_utils::{
|
use bp_test_utils::{
|
||||||
authority_list, generate_owned_bridge_module_tests, make_default_justification,
|
authority_list, generate_owned_bridge_module_tests, make_default_justification,
|
||||||
};
|
};
|
||||||
@@ -985,10 +993,10 @@ mod tests {
|
|||||||
ParaHash::from([21u8; 32])
|
ParaHash::from([21u8; 32])
|
||||||
)
|
)
|
||||||
.to_vec(),
|
.to_vec(),
|
||||||
bp_parachains::imported_parachain_head_storage_key_at_target(
|
ImportedParaHeadsKeyProvider::final_key(
|
||||||
"Parachains",
|
"Parachains",
|
||||||
ParaId(42),
|
&ParaId(42),
|
||||||
ParaHash::from([21u8; 32])
|
&ParaHash::from([21u8; 32])
|
||||||
)
|
)
|
||||||
.0,
|
.0,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -19,9 +19,10 @@
|
|||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
use bp_polkadot_core::{
|
use bp_polkadot_core::{
|
||||||
parachains::{ParaHash, ParaId},
|
parachains::{ParaHash, ParaHead, ParaId},
|
||||||
BlockNumber as RelayBlockNumber,
|
BlockNumber as RelayBlockNumber,
|
||||||
};
|
};
|
||||||
|
use bp_runtime::StorageDoubleMapKeyProvider;
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use frame_support::{Blake2_128Concat, RuntimeDebug, Twox64Concat};
|
use frame_support::{Blake2_128Concat, RuntimeDebug, Twox64Concat};
|
||||||
use scale_info::TypeInfo;
|
use scale_info::TypeInfo;
|
||||||
@@ -67,18 +68,16 @@ pub fn best_parachain_head_hash_storage_key_at_target(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns runtime storage key of the parachain head with given hash at the target chain.
|
/// Can be use to access the runtime storage key of the parachain head at the target chain.
|
||||||
///
|
///
|
||||||
/// The head is stored by the `pallet-bridge-parachains` pallet in the `ImportedParaHeads` map.
|
/// The head is stored by the `pallet-bridge-parachains` pallet in the `ImportedParaHeads` map.
|
||||||
pub fn imported_parachain_head_storage_key_at_target(
|
pub struct ImportedParaHeadsKeyProvider;
|
||||||
bridge_parachains_pallet_name: &str,
|
impl StorageDoubleMapKeyProvider for ImportedParaHeadsKeyProvider {
|
||||||
para_id: ParaId,
|
const MAP_NAME: &'static str = "ImportedParaHeads";
|
||||||
head_hash: ParaHash,
|
|
||||||
) -> StorageKey {
|
type Hasher1 = Blake2_128Concat;
|
||||||
bp_runtime::storage_double_map_final_key::<Blake2_128Concat, Blake2_128Concat>(
|
type Key1 = ParaId;
|
||||||
bridge_parachains_pallet_name,
|
type Hasher2 = Blake2_128Concat;
|
||||||
"ImportedParaHeads",
|
type Key2 = ParaHash;
|
||||||
¶_id.encode(),
|
type Value = ParaHead;
|
||||||
&head_hash.encode(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -246,38 +246,6 @@ pub fn storage_map_final_key<H: StorageHasher>(
|
|||||||
StorageKey(final_key)
|
StorageKey(final_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is a copy of the
|
|
||||||
/// `frame_support::storage::generator::StorageDoubleMap::storage_double_map_final_key` for maps
|
|
||||||
/// based on selected hashers.
|
|
||||||
///
|
|
||||||
/// We're using it because to call `storage_double_map_final_key` directly, we need access to the
|
|
||||||
/// runtime and pallet instance, which (sometimes) is impossible.
|
|
||||||
pub fn storage_double_map_final_key<H1: StorageHasher, H2: StorageHasher>(
|
|
||||||
pallet_prefix: &str,
|
|
||||||
map_name: &str,
|
|
||||||
key1: &[u8],
|
|
||||||
key2: &[u8],
|
|
||||||
) -> StorageKey {
|
|
||||||
let key1_hashed = H1::hash(key1);
|
|
||||||
let key2_hashed = H2::hash(key2);
|
|
||||||
let pallet_prefix_hashed = frame_support::Twox128::hash(pallet_prefix.as_bytes());
|
|
||||||
let storage_prefix_hashed = frame_support::Twox128::hash(map_name.as_bytes());
|
|
||||||
|
|
||||||
let mut final_key = Vec::with_capacity(
|
|
||||||
pallet_prefix_hashed.len() +
|
|
||||||
storage_prefix_hashed.len() +
|
|
||||||
key1_hashed.as_ref().len() +
|
|
||||||
key2_hashed.as_ref().len(),
|
|
||||||
);
|
|
||||||
|
|
||||||
final_key.extend_from_slice(&pallet_prefix_hashed[..]);
|
|
||||||
final_key.extend_from_slice(&storage_prefix_hashed[..]);
|
|
||||||
final_key.extend_from_slice(key1_hashed.as_ref());
|
|
||||||
final_key.extend_from_slice(key2_hashed.as_ref());
|
|
||||||
|
|
||||||
StorageKey(final_key)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This is how a storage key of storage parameter (`parameter_types! { storage Param: bool = false;
|
/// This is how a storage key of storage parameter (`parameter_types! { storage Param: bool = false;
|
||||||
/// }`) is computed.
|
/// }`) is computed.
|
||||||
///
|
///
|
||||||
@@ -304,6 +272,49 @@ pub fn storage_value_key(pallet_prefix: &str, value_name: &str) -> StorageKey {
|
|||||||
StorageKey(final_key)
|
StorageKey(final_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Can be use to access the runtime storage key of a `StorageDoubleMap`.
|
||||||
|
pub trait StorageDoubleMapKeyProvider {
|
||||||
|
// The name of the variable that holds the `StorageDoubleMap`
|
||||||
|
const MAP_NAME: &'static str;
|
||||||
|
|
||||||
|
// The same as `StorageDoubleMap::Hasher1`
|
||||||
|
type Hasher1: StorageHasher;
|
||||||
|
// The same as `StorageDoubleMap::Key1`
|
||||||
|
type Key1: FullCodec;
|
||||||
|
// The same as `StorageDoubleMap::Hasher2`
|
||||||
|
type Hasher2: StorageHasher;
|
||||||
|
// The same as `StorageDoubleMap::Key2`
|
||||||
|
type Key2: FullCodec;
|
||||||
|
// The same as `StorageDoubleMap::Value`
|
||||||
|
type Value: FullCodec;
|
||||||
|
|
||||||
|
/// This is a copy of the
|
||||||
|
/// `frame_support::storage::generator::StorageDoubleMap::storage_double_map_final_key`.
|
||||||
|
///
|
||||||
|
/// We're using it because to call `storage_double_map_final_key` directly, we need access
|
||||||
|
/// to the runtime and pallet instance, which (sometimes) is impossible.
|
||||||
|
fn final_key(pallet_prefix: &str, key1: &Self::Key1, key2: &Self::Key2) -> StorageKey {
|
||||||
|
let key1_hashed = Self::Hasher1::hash(&key1.encode());
|
||||||
|
let key2_hashed = Self::Hasher2::hash(&key2.encode());
|
||||||
|
let pallet_prefix_hashed = frame_support::Twox128::hash(pallet_prefix.as_bytes());
|
||||||
|
let storage_prefix_hashed = frame_support::Twox128::hash(Self::MAP_NAME.as_bytes());
|
||||||
|
|
||||||
|
let mut final_key = Vec::with_capacity(
|
||||||
|
pallet_prefix_hashed.len() +
|
||||||
|
storage_prefix_hashed.len() +
|
||||||
|
key1_hashed.as_ref().len() +
|
||||||
|
key2_hashed.as_ref().len(),
|
||||||
|
);
|
||||||
|
|
||||||
|
final_key.extend_from_slice(&pallet_prefix_hashed[..]);
|
||||||
|
final_key.extend_from_slice(&storage_prefix_hashed[..]);
|
||||||
|
final_key.extend_from_slice(key1_hashed.as_ref());
|
||||||
|
final_key.extend_from_slice(key2_hashed.as_ref());
|
||||||
|
|
||||||
|
StorageKey(final_key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Error generated by the `OwnedBridgeModule` trait.
|
/// Error generated by the `OwnedBridgeModule` trait.
|
||||||
#[derive(Encode, Decode, TypeInfo, PalletError)]
|
#[derive(Encode, Decode, TypeInfo, PalletError)]
|
||||||
pub enum OwnedBridgeModuleError {
|
pub enum OwnedBridgeModuleError {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ use crate::{
|
|||||||
|
|
||||||
use async_std::sync::{Arc, Mutex};
|
use async_std::sync::{Arc, Mutex};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use bp_runtime::HeaderIdProvider;
|
use bp_runtime::{HeaderIdProvider, StorageDoubleMapKeyProvider};
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use frame_system::AccountInfo;
|
use frame_system::AccountInfo;
|
||||||
use futures::{SinkExt, StreamExt};
|
use futures::{SinkExt, StreamExt};
|
||||||
@@ -380,6 +380,24 @@ impl<C: Chain> Client<C> {
|
|||||||
.transpose()
|
.transpose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read `DoubleMapStorage` value from runtime storage.
|
||||||
|
pub async fn storage_double_map_value<T: StorageDoubleMapKeyProvider>(
|
||||||
|
&self,
|
||||||
|
pallet_prefix: &str,
|
||||||
|
key1: &T::Key1,
|
||||||
|
key2: &T::Key2,
|
||||||
|
block_hash: Option<C::Hash>,
|
||||||
|
) -> Result<Option<T::Value>> {
|
||||||
|
let storage_key = T::final_key(pallet_prefix, key1, key2);
|
||||||
|
|
||||||
|
self.raw_storage_value(storage_key, block_hash)
|
||||||
|
.await?
|
||||||
|
.map(|encoded_value| {
|
||||||
|
T::Value::decode(&mut &encoded_value.0[..]).map_err(Error::ResponseParseFailed)
|
||||||
|
})
|
||||||
|
.transpose()
|
||||||
|
}
|
||||||
|
|
||||||
/// Read raw value from runtime storage.
|
/// Read raw value from runtime storage.
|
||||||
pub async fn raw_storage_value(
|
pub async fn raw_storage_value(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -25,10 +25,9 @@ use crate::{
|
|||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use bp_parachains::{
|
use bp_parachains::{
|
||||||
best_parachain_head_hash_storage_key_at_target, imported_parachain_head_storage_key_at_target,
|
best_parachain_head_hash_storage_key_at_target, BestParaHeadHash, ImportedParaHeadsKeyProvider,
|
||||||
BestParaHeadHash,
|
|
||||||
};
|
};
|
||||||
use bp_polkadot_core::parachains::{ParaHash, ParaHead, ParaHeadsProof, ParaId};
|
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
||||||
use bp_runtime::HeaderIdProvider;
|
use bp_runtime::HeaderIdProvider;
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use parachains_relay::{
|
use parachains_relay::{
|
||||||
@@ -131,14 +130,14 @@ where
|
|||||||
let best_para_head_hash: Option<BestParaHeadHash> =
|
let best_para_head_hash: Option<BestParaHeadHash> =
|
||||||
self.client.storage_value(best_para_head_hash_key, Some(at_block.1)).await?;
|
self.client.storage_value(best_para_head_hash_key, Some(at_block.1)).await?;
|
||||||
if let (Some(metrics), &Some(ref best_para_head_hash)) = (metrics, &best_para_head_hash) {
|
if let (Some(metrics), &Some(ref best_para_head_hash)) = (metrics, &best_para_head_hash) {
|
||||||
let imported_para_head_key = imported_parachain_head_storage_key_at_target(
|
let imported_para_head = self
|
||||||
P::SourceRelayChain::PARACHAINS_FINALITY_PALLET_NAME,
|
|
||||||
para_id,
|
|
||||||
best_para_head_hash.head_hash,
|
|
||||||
);
|
|
||||||
let imported_para_header = self
|
|
||||||
.client
|
.client
|
||||||
.storage_value::<ParaHead>(imported_para_head_key, Some(at_block.1))
|
.storage_double_map_value::<ImportedParaHeadsKeyProvider>(
|
||||||
|
P::SourceRelayChain::PARACHAINS_FINALITY_PALLET_NAME,
|
||||||
|
¶_id,
|
||||||
|
&best_para_head_hash.head_hash,
|
||||||
|
Some(at_block.1),
|
||||||
|
)
|
||||||
.await?
|
.await?
|
||||||
.and_then(|h| match HeaderOf::<P::SourceParachain>::decode(&mut &h.0[..]) {
|
.and_then(|h| match HeaderOf::<P::SourceParachain>::decode(&mut &h.0[..]) {
|
||||||
Ok(header) => Some(header),
|
Ok(header) => Some(header),
|
||||||
@@ -154,9 +153,9 @@ where
|
|||||||
None
|
None
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if let Some(imported_para_header) = imported_para_header {
|
if let Some(imported_para_head) = imported_para_head {
|
||||||
metrics
|
metrics
|
||||||
.update_best_parachain_block_at_target(para_id, *imported_para_header.number());
|
.update_best_parachain_block_at_target(para_id, *imported_para_head.number());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user