Light friendly storage tracking: changes trie + extending over ranges (#628)

* changes_trie

* changs_trie: continue

* changes_trie: adding tests

* fixed TODO

* removed obsolete ExtrinsicChanges

* encodable ChangesTrieConfiguration

* removed polkadot fle

* fixed grumbles

* ext_storage_changes_root returns u32

* moved changes trie root to digest

* removed commented code

* read storage values from native code

* fixed grumbles

* fixed grumbles

* missing comma
This commit is contained in:
Svyatoslav Nikolsky
2018-09-18 10:14:41 +03:00
committed by Gav Wood
parent 24479cd7f5
commit 7fa337afbc
64 changed files with 3130 additions and 788 deletions
+37 -7
View File
@@ -24,13 +24,16 @@ use backend;
use light;
use primitives::AuthorityId;
use runtime_primitives::generic::BlockId;
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, Zero, NumberFor, As};
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, Zero,
NumberFor, As, Digest, DigestItem};
use runtime_primitives::bft::Justification;
use blockchain::{self, BlockStatus};
use state_machine::backend::{Backend as StateBackend, InMemory};
use state_machine::InMemoryChangesTrieStorage;
use patricia_trie::NodeCodec;
use hashdb::Hasher;
use heapsize::HeapSizeOf;
use memorydb::MemoryDB;
struct PendingBlock<B: BlockT> {
block: StoredBlock<B>,
@@ -85,9 +88,9 @@ impl<B: BlockT> StoredBlock<B> {
#[derive(Clone)]
struct BlockchainStorage<Block: BlockT> {
blocks: HashMap<Block::Hash, StoredBlock<Block>>,
hashes: HashMap<<<Block as BlockT>::Header as HeaderT>::Number, Block::Hash>,
hashes: HashMap<NumberFor<Block>, Block::Hash>,
best_hash: Block::Hash,
best_number: <<Block as BlockT>::Header as HeaderT>::Number,
best_number: NumberFor<Block>,
genesis_hash: Block::Hash,
cht_roots: HashMap<NumberFor<Block>, Block::Hash>,
}
@@ -275,6 +278,7 @@ pub struct BlockImportOperation<Block: BlockT, H: Hasher, C: NodeCodec<H>> {
pending_authorities: Option<Vec<AuthorityId>>,
old_state: InMemory<H, C>,
new_state: Option<InMemory<H, C>>,
changes_trie_update: Option<MemoryDB<H>>,
}
impl<Block, H, C> backend::BlockImportOperation<Block, H, C> for BlockImportOperation<Block, H, C>
@@ -314,6 +318,11 @@ where
Ok(())
}
fn update_changes_trie(&mut self, update: MemoryDB<H>) -> error::Result<()> {
self.changes_trie_update = Some(update);
Ok(())
}
fn reset_storage<I: Iterator<Item=(Vec<u8>, Vec<u8>)>>(&mut self, iter: I) -> error::Result<()> {
self.new_state = Some(InMemory::from(iter.collect::<HashMap<_, _>>()));
Ok(())
@@ -325,9 +334,11 @@ pub struct Backend<Block, H, C>
where
Block: BlockT,
H: Hasher,
C: NodeCodec<H>
C: NodeCodec<H>,
H::Out: HeapSizeOf + From<Block::Hash>,
{
states: RwLock<HashMap<Block::Hash, InMemory<H, C>>>,
changes_trie_storage: InMemoryChangesTrieStorage<H>,
blockchain: Blockchain<Block>,
}
@@ -335,12 +346,14 @@ impl<Block, H, C> Backend<Block, H, C>
where
Block: BlockT,
H: Hasher,
C: NodeCodec<H>
C: NodeCodec<H>,
H::Out: HeapSizeOf + From<Block::Hash>,
{
/// Create a new instance of in-mem backend.
pub fn new() -> Backend<Block, H, C> {
Backend {
states: RwLock::new(HashMap::new()),
changes_trie_storage: InMemoryChangesTrieStorage::new(),
blockchain: Blockchain::new(),
}
}
@@ -350,12 +363,13 @@ impl<Block, H, C> backend::Backend<Block, H, C> for Backend<Block, H, C>
where
Block: BlockT,
H: Hasher,
H::Out: HeapSizeOf,
H::Out: HeapSizeOf + From<Block::Hash>,
C: NodeCodec<H> + Send + Sync,
{
type BlockImportOperation = BlockImportOperation<Block, H, C>;
type Blockchain = Blockchain<Block>;
type State = InMemory<H, C>;
type ChangesTrieStorage = InMemoryChangesTrieStorage<H>;
fn begin_operation(&self, block: BlockId<Block>) -> error::Result<Self::BlockImportOperation> {
let state = match block {
@@ -368,6 +382,7 @@ where
pending_authorities: None,
old_state: state,
new_state: None,
changes_trie_update: None,
})
}
@@ -375,10 +390,21 @@ where
if let Some(pending_block) = operation.pending_block {
let old_state = &operation.old_state;
let (header, body, justification) = pending_block.block.into_inner();
let hash = header.hash();
let parent_hash = *header.parent_hash();
self.states.write().insert(hash, operation.new_state.unwrap_or_else(|| old_state.clone()));
let changes_trie_root = header.digest().logs().iter()
.find(|log| log.as_changes_trie_root().is_some())
.and_then(DigestItem::as_changes_trie_root)
.cloned();
if let Some(changes_trie_root) = changes_trie_root {
if let Some(changes_trie_update) = operation.changes_trie_update {
let changes_trie_root: H::Out = changes_trie_root.into();
self.changes_trie_storage.insert(header.number().as_(), changes_trie_root, changes_trie_update);
}
}
self.blockchain.insert(hash, header, justification, body, pending_block.is_best);
// dumb implementation - store value for each block
if pending_block.is_best {
@@ -392,6 +418,10 @@ where
&self.blockchain
}
fn changes_trie_storage(&self) -> Option<&Self::ChangesTrieStorage> {
Some(&self.changes_trie_storage)
}
fn state_at(&self, block: BlockId<Block>) -> error::Result<Self::State> {
match self.blockchain.id(block).and_then(|id| self.states.read().get(&id).cloned()) {
Some(state) => Ok(state),
@@ -408,7 +438,7 @@ impl<Block, H, C> backend::LocalBackend<Block, H, C> for Backend<Block, H, C>
where
Block: BlockT,
H: Hasher,
H::Out: HeapSizeOf,
H::Out: HeapSizeOf + From<Block::Hash>,
C: NodeCodec<H> + Send + Sync,
{}