mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 13:31:10 +00:00
Merge branch 'rh-grandpa-dynamic2' of github.com:paritytech/substrate
This commit is contained in:
@@ -74,6 +74,9 @@ pub trait BlockImportOperation<Block, H> where
|
||||
fn reset_storage(&mut self, top: StorageMap, children: ChildrenStorageMap) -> error::Result<H::Out>;
|
||||
/// Inject changes trie data into the database.
|
||||
fn update_changes_trie(&mut self, update: MemoryDB<H>) -> error::Result<()>;
|
||||
/// Update auxiliary keys. Values are `None` if should be deleted.
|
||||
fn set_aux<I>(&mut self, ops: I) -> error::Result<()>
|
||||
where I: IntoIterator<Item=(Vec<u8>, Option<Vec<u8>>)>;
|
||||
}
|
||||
|
||||
/// Client backend. Manages the data layer.
|
||||
|
||||
@@ -602,6 +602,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
||||
body: Option<Vec<Block::Extrinsic>>,
|
||||
authorities: Option<Vec<AuthorityId>>,
|
||||
finalized: bool,
|
||||
aux: Vec<(Vec<u8>, Option<Vec<u8>>)>,
|
||||
) -> error::Result<ImportResult> where
|
||||
RA: TaggedTransactionQueue<Block>,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + Clone,
|
||||
@@ -695,6 +696,8 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
||||
if let Some(Some(changes_update)) = changes_update {
|
||||
transaction.update_changes_trie(changes_update)?;
|
||||
}
|
||||
|
||||
transaction.set_aux(aux)?;
|
||||
self.backend.commit_operation(transaction)?;
|
||||
|
||||
if make_notifications {
|
||||
@@ -880,7 +883,9 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
||||
/// TODO [snd] possibly implement this on blockchain::Backend and just redirect here
|
||||
/// Returns `Ok(None)` if `target_hash` is not found in search space.
|
||||
/// TODO [snd] write down time complexity
|
||||
pub fn best_containing(&self, target_hash: Block::Hash, maybe_max_number: Option<NumberFor<Block>>) -> error::Result<Option<Block::Hash>> {
|
||||
pub fn best_containing(&self, target_hash: Block::Hash, maybe_max_number: Option<NumberFor<Block>>)
|
||||
-> error::Result<Option<Block::Hash>>
|
||||
{
|
||||
let target_header = {
|
||||
match self.backend.blockchain().header(BlockId::Hash(target_hash))? {
|
||||
Some(x) => x,
|
||||
@@ -1016,7 +1021,8 @@ impl<B, E, Block, RA> CallApiAt<Block> for Client<B, E, Block, RA> where
|
||||
B: backend::Backend<Block, Blake2Hasher>,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Clone + Send + Sync,
|
||||
Block: BlockT<Hash=H256>,
|
||||
RA: CoreAPI<Block>
|
||||
RA: CoreAPI<Block>, // not strictly necessary at the moment
|
||||
// but we want to bound to make sure the API is actually available.
|
||||
{
|
||||
fn call_api_at(
|
||||
&self,
|
||||
@@ -1071,7 +1077,7 @@ impl<B, E, Block, RA> consensus::BlockImport<Block> for Client<B, E, Block, RA>
|
||||
post_digests,
|
||||
body,
|
||||
finalized,
|
||||
..
|
||||
auxiliary,
|
||||
} = import_block;
|
||||
let parent_hash = header.parent_hash().clone();
|
||||
|
||||
@@ -1103,6 +1109,7 @@ impl<B, E, Block, RA> consensus::BlockImport<Block> for Client<B, E, Block, RA>
|
||||
body,
|
||||
new_authorities,
|
||||
finalized,
|
||||
auxiliary,
|
||||
);
|
||||
|
||||
*self.importing_block.write() = None;
|
||||
|
||||
@@ -97,6 +97,7 @@ struct BlockchainStorage<Block: BlockT> {
|
||||
header_cht_roots: HashMap<NumberFor<Block>, Block::Hash>,
|
||||
changes_trie_cht_roots: HashMap<NumberFor<Block>, Block::Hash>,
|
||||
leaves: LeafSet<Block::Hash, NumberFor<Block>>,
|
||||
aux: HashMap<Vec<u8>, Vec<u8>>,
|
||||
}
|
||||
|
||||
/// In-memory blockchain. Supports concurrent reads.
|
||||
@@ -146,6 +147,7 @@ impl<Block: BlockT> Blockchain<Block> {
|
||||
header_cht_roots: HashMap::new(),
|
||||
changes_trie_cht_roots: HashMap::new(),
|
||||
leaves: LeafSet::new(),
|
||||
aux: HashMap::new(),
|
||||
}));
|
||||
Blockchain {
|
||||
storage: storage.clone(),
|
||||
@@ -249,6 +251,16 @@ impl<Block: BlockT> Blockchain<Block> {
|
||||
self.storage.write().finalized_hash = hash;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_aux(&self, ops: Vec<(Vec<u8>, Option<Vec<u8>>)>) {
|
||||
let mut storage = self.storage.write();
|
||||
for (k, v) in ops {
|
||||
match v {
|
||||
Some(v) => storage.aux.insert(k, v),
|
||||
None => storage.aux.remove(&k),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block: BlockT> HeaderBackend<Block> for Blockchain<Block> {
|
||||
@@ -322,6 +334,7 @@ impl<Block: BlockT> light::blockchain::Storage<Block> for Blockchain<Block>
|
||||
header: Block::Header,
|
||||
authorities: Option<Vec<AuthorityId>>,
|
||||
state: NewBlockState,
|
||||
aux_ops: Vec<(Vec<u8>, Option<Vec<u8>>)>,
|
||||
) -> error::Result<()> {
|
||||
let hash = header.hash();
|
||||
let parent_hash = *header.parent_hash();
|
||||
@@ -330,6 +343,7 @@ impl<Block: BlockT> light::blockchain::Storage<Block> for Blockchain<Block>
|
||||
self.cache.insert(parent_hash, authorities);
|
||||
}
|
||||
|
||||
self.write_aux(aux_ops);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -363,6 +377,7 @@ pub struct BlockImportOperation<Block: BlockT, H: Hasher> {
|
||||
old_state: InMemory<H>,
|
||||
new_state: Option<InMemory<H>>,
|
||||
changes_trie_update: Option<MemoryDB<H>>,
|
||||
aux: Option<Vec<(Vec<u8>, Option<Vec<u8>>)>>,
|
||||
}
|
||||
|
||||
impl<Block, H> backend::BlockImportOperation<Block, H> for BlockImportOperation<Block, H>
|
||||
@@ -433,6 +448,13 @@ where
|
||||
self.new_state = Some(InMemory::from(transaction));
|
||||
Ok(root)
|
||||
}
|
||||
|
||||
fn set_aux<I>(&mut self, ops: I) -> error::Result<()>
|
||||
where I: IntoIterator<Item=(Vec<u8>, Option<Vec<u8>>)>
|
||||
{
|
||||
self.aux = Some(ops.into_iter().collect());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// In-memory backend. Keeps all states and blocks in memory. Useful for testing.
|
||||
@@ -445,7 +467,6 @@ where
|
||||
states: RwLock<HashMap<Block::Hash, InMemory<H>>>,
|
||||
changes_trie_storage: InMemoryChangesTrieStorage<H>,
|
||||
blockchain: Blockchain<Block>,
|
||||
aux: RwLock<HashMap<Vec<u8>, Vec<u8>>>,
|
||||
}
|
||||
|
||||
impl<Block, H> Backend<Block, H>
|
||||
@@ -460,7 +481,6 @@ where
|
||||
states: RwLock::new(HashMap::new()),
|
||||
changes_trie_storage: InMemoryChangesTrieStorage::new(),
|
||||
blockchain: Blockchain::new(),
|
||||
aux: RwLock::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -488,6 +508,7 @@ where
|
||||
old_state: state,
|
||||
new_state: None,
|
||||
changes_trie_update: None,
|
||||
aux: None,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -515,6 +536,10 @@ where
|
||||
self.blockchain.cache.insert(parent_hash, operation.pending_authorities);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ops) = operation.aux {
|
||||
self.blockchain.write_aux(ops);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -542,18 +567,18 @@ where
|
||||
}
|
||||
|
||||
fn insert_aux<'a, 'b: 'a, 'c: 'a, I: IntoIterator<Item=&'a (&'c [u8], &'c [u8])>, D: IntoIterator<Item=&'a &'b [u8]>>(&self, insert: I, delete: D) -> error::Result<()> {
|
||||
let mut aux = self.aux.write();
|
||||
let mut storage = self.blockchain.storage.write();
|
||||
for (k, v) in insert {
|
||||
aux.insert(k.to_vec(), v.to_vec());
|
||||
storage.aux.insert(k.to_vec(), v.to_vec());
|
||||
}
|
||||
for k in delete {
|
||||
aux.remove(*k);
|
||||
storage.aux.remove(*k);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_aux(&self, key: &[u8]) -> error::Result<Option<Vec<u8>>> {
|
||||
Ok(self.aux.read().get(key).cloned())
|
||||
Ok(self.blockchain.storage.read().aux.get(key).cloned())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ pub struct ImportOperation<Block: BlockT, S, F> {
|
||||
header: Option<Block::Header>,
|
||||
authorities: Option<Vec<AuthorityId>>,
|
||||
leaf_state: NewBlockState,
|
||||
aux_ops: Vec<(Vec<u8>, Option<Vec<u8>>)>,
|
||||
_phantom: ::std::marker::PhantomData<(S, F)>,
|
||||
}
|
||||
|
||||
@@ -86,6 +87,7 @@ impl<S, F, Block, H> ClientBackend<Block, H> for Backend<S, F> where
|
||||
header: None,
|
||||
authorities: None,
|
||||
leaf_state: NewBlockState::Normal,
|
||||
aux_ops: Vec::new(),
|
||||
_phantom: Default::default(),
|
||||
})
|
||||
}
|
||||
@@ -96,6 +98,7 @@ impl<S, F, Block, H> ClientBackend<Block, H> for Backend<S, F> where
|
||||
header,
|
||||
operation.authorities,
|
||||
operation.leaf_state,
|
||||
operation.aux_ops,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -193,6 +196,13 @@ where
|
||||
let mut op = in_mem.begin_operation(BlockId::Hash(Default::default()))?;
|
||||
op.reset_storage(top, children)
|
||||
}
|
||||
|
||||
fn set_aux<I>(&mut self, ops: I) -> ClientResult<()>
|
||||
where I: IntoIterator<Item=(Vec<u8>, Option<Vec<u8>>)>
|
||||
{
|
||||
self.aux_ops = ops.into_iter().collect();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block, S, F, H> StateBackend<H> for OnDemandState<Block, S, F>
|
||||
|
||||
@@ -35,11 +35,15 @@ use light::fetcher::{Fetcher, RemoteHeaderRequest};
|
||||
/// Light client blockchain storage.
|
||||
pub trait Storage<Block: BlockT>: BlockchainHeaderBackend<Block> {
|
||||
/// Store new header. Should refuse to revert any finalized blocks.
|
||||
///
|
||||
/// Takes new authorities, the leaf state of the new block, and
|
||||
/// any auxiliary storage updates to place in the same operation.
|
||||
fn import_header(
|
||||
&self,
|
||||
header: Block::Header,
|
||||
authorities: Option<Vec<AuthorityId>>,
|
||||
state: NewBlockState,
|
||||
aux_ops: Vec<(Vec<u8>, Option<Vec<u8>>)>,
|
||||
) -> ClientResult<()>;
|
||||
|
||||
/// Mark historic header as finalized.
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
//! Macros for declaring and implementing the runtime APIs.
|
||||
|
||||
// these are part of the public API, so need to be re-exported
|
||||
pub use runtime_version::{ApiId, RuntimeVersion};
|
||||
|
||||
/// Declare the given API traits.
|
||||
///
|
||||
/// # Example:
|
||||
|
||||
@@ -24,12 +24,11 @@ pub use state_machine::OverlayedChanges;
|
||||
pub use runtime_primitives::{traits::Block as BlockT, generic::BlockId};
|
||||
#[cfg(feature = "std")]
|
||||
use runtime_primitives::traits::ApiRef;
|
||||
use runtime_version::ApiId;
|
||||
pub use runtime_version::ApiId;
|
||||
#[doc(hidden)]
|
||||
pub use rstd::slice;
|
||||
#[cfg(feature = "std")]
|
||||
use rstd::result;
|
||||
#[doc(hidden)]
|
||||
pub use codec::{Encode, Decode};
|
||||
#[cfg(feature = "std")]
|
||||
use error;
|
||||
@@ -73,6 +72,30 @@ pub trait CallApiAt<Block: BlockT> {
|
||||
changes: &mut OverlayedChanges,
|
||||
initialised_block: &mut Option<BlockId<Block>>,
|
||||
) -> error::Result<Vec<u8>>;
|
||||
|
||||
/// Call the given api function with strong arguments at the given block
|
||||
/// and returns the decoded result.
|
||||
fn call_api_at_strong<In: Encode, Out: Decode>(
|
||||
&self,
|
||||
at: &BlockId<Block>,
|
||||
function: &'static str,
|
||||
args: &In,
|
||||
changes: &mut OverlayedChanges,
|
||||
initialised_block: &mut Option<BlockId<Block>>,
|
||||
) -> error::Result<Out> where Self: Sized {
|
||||
let raw = self.call_api_at(
|
||||
at,
|
||||
function,
|
||||
args.encode(),
|
||||
changes,
|
||||
initialised_block,
|
||||
)?;
|
||||
|
||||
match Out::decode(&mut &raw[..]) {
|
||||
Some(out) => Ok(out),
|
||||
None => bail!(error::ErrorKind::CallResultDecode(function)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The ApiIds for the various standard runtime APIs.
|
||||
|
||||
Reference in New Issue
Block a user