mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-19 20:25:40 +00:00
AuxStore on light clients (#1251)
* implement AuxStore on light clients * Update core/client/db/src/light.rs Co-Authored-By: svyatonik <svyatonik@gmail.com> * Update core/client/db/src/light.rs Co-Authored-By: svyatonik <svyatonik@gmail.com> * Update core/client/db/src/light.rs Co-Authored-By: svyatonik <svyatonik@gmail.com>
This commit is contained in:
committed by
Robert Habermeier
parent
c61d03a86f
commit
81f90ed0a4
@@ -21,7 +21,7 @@ use parking_lot::RwLock;
|
|||||||
|
|
||||||
use kvdb::{KeyValueDB, DBTransaction};
|
use kvdb::{KeyValueDB, DBTransaction};
|
||||||
|
|
||||||
use client::backend::NewBlockState;
|
use client::backend::{AuxStore, NewBlockState};
|
||||||
use client::blockchain::{BlockStatus, Cache as BlockchainCache,
|
use client::blockchain::{BlockStatus, Cache as BlockchainCache,
|
||||||
HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo};
|
HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo};
|
||||||
use client::{cht, LeafSet};
|
use client::{cht, LeafSet};
|
||||||
@@ -275,6 +275,31 @@ impl<Block: BlockT> LightStorage<Block> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Block> AuxStore for LightStorage<Block>
|
||||||
|
where Block: BlockT,
|
||||||
|
{
|
||||||
|
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) -> ClientResult<()> {
|
||||||
|
let mut transaction = DBTransaction::new();
|
||||||
|
for (k, v) in insert {
|
||||||
|
transaction.put(columns::AUX, k, v);
|
||||||
|
}
|
||||||
|
for k in delete {
|
||||||
|
transaction.delete(columns::AUX, k);
|
||||||
|
}
|
||||||
|
self.db.write(transaction).map_err(db_err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_aux(&self, key: &[u8]) -> ClientResult<Option<Vec<u8>>> {
|
||||||
|
self.db.get(columns::AUX, key).map(|r| r.map(|v| v.to_vec())).map_err(db_err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<Block> LightBlockchainStorage<Block> for LightStorage<Block>
|
impl<Block> LightBlockchainStorage<Block> for LightStorage<Block>
|
||||||
where Block: BlockT,
|
where Block: BlockT,
|
||||||
{
|
{
|
||||||
@@ -864,4 +889,28 @@ pub(crate) mod tests {
|
|||||||
assert_eq!(db.info().unwrap().best_hash, hash0);
|
assert_eq!(db.info().unwrap().best_hash, hash0);
|
||||||
assert_eq!(db.header(BlockId::Hash::<Block>(hash0)).unwrap().unwrap().hash(), hash0);
|
assert_eq!(db.header(BlockId::Hash::<Block>(hash0)).unwrap().unwrap().hash(), hash0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn aux_store_works() {
|
||||||
|
let db = LightStorage::<Block>::new_test();
|
||||||
|
|
||||||
|
// insert aux1 + aux2 using direct store access
|
||||||
|
db.insert_aux(&[(&[1][..], &[101][..]), (&[2][..], &[102][..])], ::std::iter::empty()).unwrap();
|
||||||
|
|
||||||
|
// check aux values
|
||||||
|
assert_eq!(db.get_aux(&[1]).unwrap(), Some(vec![101]));
|
||||||
|
assert_eq!(db.get_aux(&[2]).unwrap(), Some(vec![102]));
|
||||||
|
assert_eq!(db.get_aux(&[3]).unwrap(), None);
|
||||||
|
|
||||||
|
// delete aux1 + insert aux3 using import operation
|
||||||
|
db.import_header(default_header(&Default::default(), 0), None, NewBlockState::Best, vec![
|
||||||
|
(vec![3], Some(vec![103])),
|
||||||
|
(vec![1], None),
|
||||||
|
]).unwrap();
|
||||||
|
|
||||||
|
// check aux values
|
||||||
|
assert_eq!(db.get_aux(&[1]).unwrap(), None);
|
||||||
|
assert_eq!(db.get_aux(&[2]).unwrap(), Some(vec![102]));
|
||||||
|
assert_eq!(db.get_aux(&[3]).unwrap(), Some(vec![103]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -338,6 +338,29 @@ impl<Block: BlockT> blockchain::Backend<Block> for Blockchain<Block> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Block: BlockT> backend::AuxStore for Blockchain<Block> {
|
||||||
|
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 storage = self.storage.write();
|
||||||
|
for (k, v) in insert {
|
||||||
|
storage.aux.insert(k.to_vec(), v.to_vec());
|
||||||
|
}
|
||||||
|
for k in delete {
|
||||||
|
storage.aux.remove(*k);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_aux(&self, key: &[u8]) -> error::Result<Option<Vec<u8>>> {
|
||||||
|
Ok(self.storage.read().aux.get(key).cloned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<Block: BlockT> light::blockchain::Storage<Block> for Blockchain<Block>
|
impl<Block: BlockT> light::blockchain::Storage<Block> for Blockchain<Block>
|
||||||
where
|
where
|
||||||
Block::Hash: From<[u8; 32]>,
|
Block::Hash: From<[u8; 32]>,
|
||||||
@@ -511,18 +534,11 @@ where
|
|||||||
I: IntoIterator<Item=&'a(&'c [u8], &'c [u8])>,
|
I: IntoIterator<Item=&'a(&'c [u8], &'c [u8])>,
|
||||||
D: IntoIterator<Item=&'a &'b [u8]>,
|
D: IntoIterator<Item=&'a &'b [u8]>,
|
||||||
>(&self, insert: I, delete: D) -> error::Result<()> {
|
>(&self, insert: I, delete: D) -> error::Result<()> {
|
||||||
let mut storage = self.blockchain.storage.write();
|
self.blockchain.insert_aux(insert, delete)
|
||||||
for (k, v) in insert {
|
|
||||||
storage.aux.insert(k.to_vec(), v.to_vec());
|
|
||||||
}
|
|
||||||
for k in delete {
|
|
||||||
storage.aux.remove(*k);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_aux(&self, key: &[u8]) -> error::Result<Option<Vec<u8>>> {
|
fn get_aux(&self, key: &[u8]) -> error::Result<Option<Vec<u8>>> {
|
||||||
Ok(self.blockchain.storage.read().aux.get(key).cloned())
|
self.blockchain.get_aux(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ use state_machine::{Backend as StateBackend, InMemoryChangesTrieStorage, TrieBac
|
|||||||
use runtime_primitives::traits::{Block as BlockT, NumberFor};
|
use runtime_primitives::traits::{Block as BlockT, NumberFor};
|
||||||
|
|
||||||
use in_mem;
|
use in_mem;
|
||||||
use backend::{Backend as ClientBackend, BlockImportOperation, RemoteBackend, NewBlockState};
|
use backend::{AuxStore, Backend as ClientBackend, BlockImportOperation, RemoteBackend, NewBlockState};
|
||||||
use blockchain::HeaderBackend as BlockchainHeaderBackend;
|
use blockchain::HeaderBackend as BlockchainHeaderBackend;
|
||||||
use error::{Error as ClientError, ErrorKind as ClientErrorKind, Result as ClientResult};
|
use error::{Error as ClientError, ErrorKind as ClientErrorKind, Result as ClientResult};
|
||||||
use light::blockchain::{Blockchain, Storage as BlockchainStorage};
|
use light::blockchain::{Blockchain, Storage as BlockchainStorage};
|
||||||
@@ -70,19 +70,19 @@ impl<S, F> Backend<S, F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, F> ::backend::AuxStore for Backend<S, F> {
|
impl<S: AuxStore, F> AuxStore for Backend<S, F> {
|
||||||
fn insert_aux<
|
fn insert_aux<
|
||||||
'a,
|
'a,
|
||||||
'b: 'a,
|
'b: 'a,
|
||||||
'c: 'a,
|
'c: 'a,
|
||||||
I: IntoIterator<Item=&'a(&'c [u8], &'c [u8])>,
|
I: IntoIterator<Item=&'a(&'c [u8], &'c [u8])>,
|
||||||
D: IntoIterator<Item=&'a &'b [u8]>,
|
D: IntoIterator<Item=&'a &'b [u8]>,
|
||||||
>(&self, _insert: I, _delete: D) -> ClientResult<()> {
|
>(&self, insert: I, delete: D) -> ClientResult<()> {
|
||||||
Err(ClientErrorKind::NotAvailableOnLightClient.into())
|
self.blockchain.storage().insert_aux(insert, delete)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_aux(&self, _key: &[u8]) -> ClientResult<Option<Vec<u8>>> {
|
fn get_aux(&self, key: &[u8]) -> ClientResult<Option<Vec<u8>>> {
|
||||||
Err(ClientErrorKind::NotAvailableOnLightClient.into())
|
self.blockchain.storage().get_aux(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ use primitives::AuthorityId;
|
|||||||
use runtime_primitives::{Justification, generic::BlockId};
|
use runtime_primitives::{Justification, generic::BlockId};
|
||||||
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT,NumberFor, Zero};
|
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT,NumberFor, Zero};
|
||||||
|
|
||||||
use backend::NewBlockState;
|
use backend::{AuxStore, NewBlockState};
|
||||||
use blockchain::{Backend as BlockchainBackend, BlockStatus, Cache as BlockchainCache,
|
use blockchain::{Backend as BlockchainBackend, BlockStatus, Cache as BlockchainCache,
|
||||||
HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo};
|
HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo};
|
||||||
use cht;
|
use cht;
|
||||||
@@ -33,7 +33,7 @@ use error::{ErrorKind as ClientErrorKind, Result as ClientResult};
|
|||||||
use light::fetcher::{Fetcher, RemoteHeaderRequest};
|
use light::fetcher::{Fetcher, RemoteHeaderRequest};
|
||||||
|
|
||||||
/// Light client blockchain storage.
|
/// Light client blockchain storage.
|
||||||
pub trait Storage<Block: BlockT>: BlockchainHeaderBackend<Block> {
|
pub trait Storage<Block: BlockT>: AuxStore + BlockchainHeaderBackend<Block> {
|
||||||
/// Store new header. Should refuse to revert any finalized blocks.
|
/// Store new header. Should refuse to revert any finalized blocks.
|
||||||
///
|
///
|
||||||
/// Takes new authorities, the leaf state of the new block, and
|
/// Takes new authorities, the leaf state of the new block, and
|
||||||
@@ -207,6 +207,22 @@ pub mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AuxStore for DummyStorage {
|
||||||
|
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) -> ClientResult<()> {
|
||||||
|
Err(ClientErrorKind::Backend("Test error".into()).into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_aux(&self, _key: &[u8]) -> ClientResult<Option<Vec<u8>>> {
|
||||||
|
Err(ClientErrorKind::Backend("Test error".into()).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Storage<Block> for DummyStorage {
|
impl Storage<Block> for DummyStorage {
|
||||||
fn import_header(
|
fn import_header(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
Reference in New Issue
Block a user