Fetching multiple remote values using single message (#3612)

* multiple remote values in single message

* keys_str: String ->keys_str: closure
This commit is contained in:
Svyatoslav Nikolsky
2019-09-16 13:30:21 +03:00
committed by GitHub
parent c45a15e559
commit 849e824652
11 changed files with 273 additions and 190 deletions
+27 -21
View File
@@ -17,7 +17,7 @@
//! Light client data fetcher. Fetches requested data from remote full nodes.
use std::sync::Arc;
use std::collections::BTreeMap;
use std::collections::{BTreeMap, HashMap};
use std::marker::PhantomData;
use std::future::Future;
@@ -73,7 +73,7 @@ pub struct RemoteReadRequest<Header: HeaderT> {
/// Header of block at which read is performed.
pub header: Header,
/// Storage key to read.
pub key: Vec<u8>,
pub keys: Vec<Vec<u8>>,
/// Number of times to retry request. None means that default RETRY_COUNT is used.
pub retry_count: Option<usize>,
}
@@ -88,7 +88,7 @@ pub struct RemoteReadChildRequest<Header: HeaderT> {
/// Storage key for child.
pub storage_key: Vec<u8>,
/// Child storage key to read.
pub key: Vec<u8>,
pub keys: Vec<Vec<u8>>,
/// Number of times to retry request. None means that default RETRY_COUNT is used.
pub retry_count: Option<usize>,
}
@@ -147,7 +147,7 @@ pub trait Fetcher<Block: BlockT>: Send + Sync {
/// Remote header future.
type RemoteHeaderResult: Future<Output = Result<Block::Header, ClientError>> + Send + 'static;
/// Remote storage read future.
type RemoteReadResult: Future<Output = Result<Option<Vec<u8>>, ClientError>> + Send + 'static;
type RemoteReadResult: Future<Output = Result<HashMap<Vec<u8>, Option<Vec<u8>>>, ClientError>> + Send + 'static;
/// Remote call result future.
type RemoteCallResult: Future<Output = Result<Vec<u8>, ClientError>> + Send + 'static;
/// Remote changes result future.
@@ -193,13 +193,13 @@ pub trait FetchChecker<Block: BlockT>: Send + Sync {
&self,
request: &RemoteReadRequest<Block::Header>,
remote_proof: Vec<Vec<u8>>
) -> ClientResult<Option<Vec<u8>>>;
) -> ClientResult<HashMap<Vec<u8>, Option<Vec<u8>>>>;
/// Check remote storage read proof.
fn check_read_child_proof(
&self,
request: &RemoteReadChildRequest<Block::Header>,
remote_proof: Vec<Vec<u8>>
) -> ClientResult<Option<Vec<u8>>>;
) -> ClientResult<HashMap<Vec<u8>, Option<Vec<u8>>>>;
/// Check remote method execution proof.
fn check_execution_proof(
&self,
@@ -395,23 +395,26 @@ impl<E, Block, H, S> FetchChecker<Block> for LightDataChecker<E, H, Block, S>
fn check_read_proof(
&self,
request: &RemoteReadRequest<Block::Header>,
remote_proof: Vec<Vec<u8>>
) -> ClientResult<Option<Vec<u8>>> {
read_proof_check::<H>(convert_hash(request.header.state_root()), remote_proof, &request.key)
.map_err(Into::into)
remote_proof: Vec<Vec<u8>>,
) -> ClientResult<HashMap<Vec<u8>, Option<Vec<u8>>>> {
read_proof_check::<H, _>(
convert_hash(request.header.state_root()),
remote_proof,
request.keys.iter(),
).map_err(Into::into)
}
fn check_read_child_proof(
&self,
request: &RemoteReadChildRequest<Block::Header>,
remote_proof: Vec<Vec<u8>>
) -> ClientResult<Option<Vec<u8>>> {
read_child_proof_check::<H>(
) -> ClientResult<HashMap<Vec<u8>, Option<Vec<u8>>>> {
read_child_proof_check::<H, _>(
convert_hash(request.header.state_root()),
remote_proof,
&request.storage_key,
&request.key)
.map_err(Into::into)
request.keys.iter(),
).map_err(Into::into)
}
fn check_execution_proof(
@@ -529,7 +532,7 @@ pub mod tests {
impl Fetcher<Block> for OkCallFetcher {
type RemoteHeaderResult = Ready<Result<Header, ClientError>>;
type RemoteReadResult = Ready<Result<Option<Vec<u8>>, ClientError>>;
type RemoteReadResult = Ready<Result<HashMap<Vec<u8>, Option<Vec<u8>>>, ClientError>>;
type RemoteCallResult = Ready<Result<Vec<u8>, ClientError>>;
type RemoteChangesResult = Ready<Result<Vec<(NumberFor<Block>, u32)>, ClientError>>;
type RemoteBodyResult = Ready<Result<Vec<Extrinsic>, ClientError>>;
@@ -579,7 +582,10 @@ pub mod tests {
let heap_pages = remote_client.storage(&remote_block_id, &StorageKey(well_known_keys::HEAP_PAGES.to_vec()))
.unwrap()
.and_then(|v| Decode::decode(&mut &v.0[..]).ok()).unwrap();
let remote_read_proof = remote_client.read_proof(&remote_block_id, well_known_keys::HEAP_PAGES).unwrap();
let remote_read_proof = remote_client.read_proof(
&remote_block_id,
&[well_known_keys::HEAP_PAGES],
).unwrap();
// check remote read proof locally
let local_storage = InMemoryBlockchain::<Block>::new();
@@ -618,7 +624,7 @@ pub mod tests {
let remote_read_proof = remote_client.read_child_proof(
&remote_block_id,
b":child_storage:default:child1",
b"key1",
&[b"key1"],
).unwrap();
// check locally
@@ -676,9 +682,9 @@ pub mod tests {
assert_eq!((&local_checker as &dyn FetchChecker<Block>).check_read_proof(&RemoteReadRequest::<Header> {
block: remote_block_header.hash(),
header: remote_block_header,
key: well_known_keys::HEAP_PAGES.to_vec(),
keys: vec![well_known_keys::HEAP_PAGES.to_vec()],
retry_count: None,
}, remote_read_proof).unwrap().unwrap()[0], heap_pages as u8);
}, remote_read_proof).unwrap().remove(well_known_keys::HEAP_PAGES).unwrap().unwrap()[0], heap_pages as u8);
}
#[test]
@@ -694,11 +700,11 @@ pub mod tests {
block: remote_block_header.hash(),
header: remote_block_header,
storage_key: b":child_storage:default:child1".to_vec(),
key: b"key1".to_vec(),
keys: vec![b"key1".to_vec()],
retry_count: None,
},
remote_read_proof
).unwrap().unwrap(), result);
).unwrap().remove(b"key1".as_ref()).unwrap().unwrap(), result);
}
#[test]