From 3f2a7f3cba1816e2f8b03fb016f4dff077c5b643 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Wed, 17 Oct 2018 13:05:30 -0700 Subject: [PATCH] set aux in block import --- substrate/core/client/src/backend.rs | 3 ++ substrate/core/client/src/in_mem.rs | 37 ++++++++++++++++--- substrate/core/client/src/light/backend.rs | 10 +++++ substrate/core/client/src/light/blockchain.rs | 4 ++ 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/substrate/core/client/src/backend.rs b/substrate/core/client/src/backend.rs index 615704361c..b994b1307d 100644 --- a/substrate/core/client/src/backend.rs +++ b/substrate/core/client/src/backend.rs @@ -76,6 +76,9 @@ where fn reset_storage, Vec)>>(&mut self, iter: I) -> error::Result<()>; /// Inject changes trie data into the database. fn update_changes_trie(&mut self, update: MemoryDB) -> error::Result<()>; + /// Update auxiliary keys. Values are `None` if should be deleted. + fn set_aux(&mut self, ops: I) -> error::Result<()> + where I: IntoIterator, Option>)>; } /// Client backend. Manages the data layer. diff --git a/substrate/core/client/src/in_mem.rs b/substrate/core/client/src/in_mem.rs index 5548528cc7..88f94dfbed 100644 --- a/substrate/core/client/src/in_mem.rs +++ b/substrate/core/client/src/in_mem.rs @@ -96,6 +96,7 @@ struct BlockchainStorage { genesis_hash: Block::Hash, cht_roots: HashMap, Block::Hash>, leaves: LeafSet>, + aux: HashMap, Vec>, } /// In-memory blockchain. Supports concurrent reads. @@ -144,6 +145,7 @@ impl Blockchain { genesis_hash: Default::default(), cht_roots: HashMap::new(), leaves: LeafSet::new(), + aux: HashMap::new(), })); Blockchain { storage: storage.clone(), @@ -247,6 +249,16 @@ impl Blockchain { self.storage.write().finalized_hash = hash; Ok(()) } + + fn write_aux(&self, ops: Vec<(Vec, Option>)>) { + 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 HeaderBackend for Blockchain { @@ -320,6 +332,7 @@ impl light::blockchain::Storage for Blockchain header: Block::Header, authorities: Option>, state: NewBlockState, + aux_ops: Vec<(Vec, Option>)>, ) -> error::Result<()> { let hash = header.hash(); let parent_hash = *header.parent_hash(); @@ -328,6 +341,7 @@ impl light::blockchain::Storage for Blockchain self.cache.insert(parent_hash, authorities); } + self.write_aux(aux_ops); Ok(()) } @@ -356,6 +370,7 @@ pub struct BlockImportOperation { old_state: InMemory, new_state: Option>, changes_trie_update: Option>, + aux: Option, Option>)>>, } impl backend::BlockImportOperation for BlockImportOperation @@ -404,6 +419,13 @@ where self.new_state = Some(InMemory::from(iter.collect::>())); Ok(()) } + + fn set_aux(&mut self, ops: I) -> error::Result<()> + where I: IntoIterator, Option>)> + { + self.aux = Some(ops.into_iter().collect()); + Ok(()) + } } /// In-memory backend. Keeps all states and blocks in memory. Useful for testing. @@ -417,7 +439,6 @@ where states: RwLock>>, changes_trie_storage: InMemoryChangesTrieStorage, blockchain: Blockchain, - aux: RwLock, Vec>>, } impl Backend @@ -433,7 +454,6 @@ where states: RwLock::new(HashMap::new()), changes_trie_storage: InMemoryChangesTrieStorage::new(), blockchain: Blockchain::new(), - aux: RwLock::new(HashMap::new()), } } } @@ -461,6 +481,7 @@ where old_state: state, new_state: None, changes_trie_update: None, + aux: None, }) } @@ -488,6 +509,10 @@ where self.blockchain.cache.insert(parent_hash, operation.pending_authorities); } } + + if let Some(ops) = operation.aux { + self.blockchain.write_aux(ops); + } Ok(()) } @@ -515,18 +540,18 @@ where } fn insert_aux<'a, 'b: 'a, 'c: 'a, I: IntoIterator, D: IntoIterator>(&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>> { - Ok(self.aux.read().get(key).cloned()) + Ok(self.blockchain.storage.read().aux.get(key).cloned()) } } diff --git a/substrate/core/client/src/light/backend.rs b/substrate/core/client/src/light/backend.rs index e83640aa6c..5a1cee15c6 100644 --- a/substrate/core/client/src/light/backend.rs +++ b/substrate/core/client/src/light/backend.rs @@ -45,6 +45,7 @@ pub struct ImportOperation { header: Option, authorities: Option>, leaf_state: NewBlockState, + aux_ops: Vec<(Vec, Option>)>, _phantom: ::std::marker::PhantomData<(S, F)>, } @@ -86,6 +87,7 @@ impl ClientBackend for Backend where header: None, authorities: None, leaf_state: NewBlockState::Normal, + aux_ops: Vec::new(), _phantom: Default::default(), }) } @@ -96,6 +98,7 @@ impl ClientBackend for Backend where header, operation.authorities, operation.leaf_state, + operation.aux_ops, ) } @@ -193,6 +196,13 @@ where // we're not storing anything locally => ignore changes Ok(()) } + + fn set_aux(&mut self, ops: I) -> ClientResult<()> + where I: IntoIterator, Option>)> + { + self.aux_ops = ops.into_iter().collect(); + Ok(()) + } } impl StateBackend for OnDemandState diff --git a/substrate/core/client/src/light/blockchain.rs b/substrate/core/client/src/light/blockchain.rs index 97c20ecc90..2dd7097751 100644 --- a/substrate/core/client/src/light/blockchain.rs +++ b/substrate/core/client/src/light/blockchain.rs @@ -35,11 +35,15 @@ use light::fetcher::{Fetcher, RemoteHeaderRequest}; /// Light client blockchain storage. pub trait Storage: BlockchainHeaderBackend { /// 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>, state: NewBlockState, + aux_ops: Vec<(Vec, Option>)>, ) -> ClientResult<()>; /// Mark historic header as finalized.