From d2ad280664ce171a17575ce9a750bd29738a5d98 Mon Sep 17 00:00:00 2001 From: Falco Hirschenberger Date: Thu, 29 Jul 2021 16:13:01 +0200 Subject: [PATCH 01/16] Add storage query functions for multiple keys fixes #9203 --- client/rpc-api/src/child_state/mod.rs | 9 ++++ client/rpc/src/state/mod.rs | 24 +++++++++ client/rpc/src/state/state_full.rs | 45 +++++++++++++++- client/rpc/src/state/state_light.rs | 68 ++++++++++++++++++++++- client/rpc/src/state/tests.rs | 78 +++++++++++++++++++++++++++ 5 files changed, 222 insertions(+), 2 deletions(-) diff --git a/client/rpc-api/src/child_state/mod.rs b/client/rpc-api/src/child_state/mod.rs index 7abda0a63134d..d7edbc4f0a220 100644 --- a/client/rpc-api/src/child_state/mod.rs +++ b/client/rpc-api/src/child_state/mod.rs @@ -66,6 +66,15 @@ pub trait ChildStateApi { hash: Option, ) -> FutureResult>; + /// Returns child storage entries for multiple keys at a specific block's state. + #[rpc(name = "childstate_getStorages")] + fn storages( + &self, + child_storage_key: PrefixedStorageKey, + keys: Vec, + hash: Option, + ) -> FutureResult>>; + /// Returns the hash of a child storage entry at a block's state. #[rpc(name = "childstate_getStorageHash")] fn storage_hash( diff --git a/client/rpc/src/state/mod.rs b/client/rpc/src/state/mod.rs index 9137404df3ee2..0cbf2eca1b13a 100644 --- a/client/rpc/src/state/mod.rs +++ b/client/rpc/src/state/mod.rs @@ -96,6 +96,13 @@ where key: StorageKey, ) -> FutureResult>; + /// Returns storage entries for multiple keys at a specific block's state. + fn storages( + &self, + block: Option, + keys: Vec, + ) -> FutureResult>>; + /// Returns the hash of a storage entry at a block's state. fn storage_hash( &self, @@ -462,6 +469,14 @@ where key: StorageKey, ) -> FutureResult>; + /// Returns child storage entries at a specific block's state. + fn storages( + &self, + block: Option, + storage_key: PrefixedStorageKey, + keys: Vec, + ) -> FutureResult>>; + /// Returns the hash of a child storage entry at a block's state. fn storage_hash( &self, @@ -511,6 +526,15 @@ where self.backend.storage(block, storage_key, key) } + fn storages( + &self, + storage_key: PrefixedStorageKey, + keys: Vec, + block: Option, + ) -> FutureResult>> { + self.backend.storages(block, storage_key, keys) + } + fn storage_keys( &self, storage_key: PrefixedStorageKey, diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index 313e89bdf80b4..d553e94e98617 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -22,7 +22,10 @@ use futures::{future, StreamExt as _, TryStreamExt as _}; use jsonrpc_pubsub::{manager::SubscriptionManager, typed::Subscriber, SubscriptionId}; use log::warn; use rpc::{ - futures::{future::result, stream, Future, Sink, Stream}, + futures::{ + future::{join_all, result}, + stream, Future, Sink, Stream, + }, Result as RpcResult, }; use std::{ @@ -358,6 +361,22 @@ where )) } + fn storages( + &self, + block: Option, + keys: Vec, + ) -> FutureResult>> { + let block = match self.block_or_best(block) { + Ok(b) => b, + Err(e) => return Box::new(result(Err(client_err(e)))), + }; + let client = self.client.clone(); + Box::new(join_all( + keys.into_iter() + .map(move |key| client.storage(&BlockId::Hash(block), &key).map_err(client_err)), + )) + } + fn storage_size( &self, block: Option, @@ -722,6 +741,30 @@ where )) } + fn storages( + &self, + block: Option, + storage_key: PrefixedStorageKey, + keys: Vec, + ) -> FutureResult>> { + let block = match self.block_or_best(block) { + Ok(b) => b, + Err(e) => return Box::new(result(Err(client_err(e)))), + }; + let client = self.client.clone(); + Box::new( + join_all(keys.into_iter().map(move |key| { + let child_info = match ChildType::from_prefixed_key(&storage_key) { + Some((ChildType::ParentKeyId, storage_key)) => + ChildInfo::new_default(storage_key), + None => return Err(sp_blockchain::Error::InvalidChildStorageKey), + }; + client.child_storage(&BlockId::Hash(block), &child_info, &key) + })) + .map_err(client_err), + ) + } + fn storage_hash( &self, block: Option, diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index 274eabe376d98..e18652cbcbd96 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -30,7 +30,7 @@ use log::warn; use parking_lot::Mutex; use rpc::{ futures::{ - future::{result, Future}, + future::{join_all, result, Future}, stream::Stream, Sink, }, @@ -245,6 +245,26 @@ where ) } + fn storages( + &self, + block: Option, + keys: Vec, + ) -> FutureResult>> { + let remote_blockchain = self.remote_blockchain.clone(); + let fetcher = self.fetcher.clone(); + let block = self.block_or_best(block); + Box::new(join_all(keys.into_iter().map(move |key| { + storage(&*remote_blockchain, fetcher.clone(), block, vec![key.0.clone()]) + .boxed() + .compat() + .map(move |mut values| { + values + .remove(&key) + .expect("successful request has entries for all requested keys; qed") + }) + }))) + } + fn storage_hash( &self, block: Option, @@ -563,6 +583,52 @@ where Box::new(child_storage.boxed().compat()) } + fn storages( + &self, + block: Option, + storage_key: PrefixedStorageKey, + keys: Vec, + ) -> FutureResult>> { + let block = self.block_or_best(block); + let fetcher = self.fetcher.clone(); + let remote_blockchain = self.remote_blockchain.clone(); + Box::new(join_all(keys.into_iter().map(move |key| { + let storage_key = storage_key.clone(); + let fetcher2 = fetcher.clone(); + let child_storage = + resolve_header(&*remote_blockchain, &*fetcher, block).then(move |result| { + match result { + Ok(header) => Either::Left( + fetcher2 + .remote_read_child(RemoteReadChildRequest { + block, + header, + storage_key, + keys: vec![key.0.clone()], + retry_count: Default::default(), + }) + .then(move |result| { + ready( + result + .map(|mut data| { + data.remove(&key.0) + .expect( + "successful result has entry for all keys; qed", + ) + .map(StorageData) + }) + .map_err(client_err), + ) + }), + ), + Err(error) => Either::Right(ready(Err(error))), + } + }); + + Box::new(child_storage.boxed().compat()) + }))) + } + fn storage_hash( &self, block: Option, diff --git a/client/rpc/src/state/tests.rs b/client/rpc/src/state/tests.rs index dd99360bafba9..a30670bdf688e 100644 --- a/client/rpc/src/state/tests.rs +++ b/client/rpc/src/state/tests.rs @@ -98,6 +98,41 @@ fn should_return_storage() { ); } +#[test] +fn should_return_storages() { + const KEY1: &[u8] = b":mock"; + const KEY2: &[u8] = b":turtle"; + const VALUE: &[u8] = b"hello world"; + const CHILD_VALUE1: &[u8] = b"hello world !"; + const CHILD_VALUE2: &[u8] = b"hello world !"; + + let child_info = ChildInfo::new_default(STORAGE_KEY); + let client = TestClientBuilder::new() + .add_extra_storage(KEY1.to_vec(), VALUE.to_vec()) + .add_extra_child_storage(&child_info, KEY1.to_vec(), CHILD_VALUE1.to_vec()) + .add_extra_child_storage(&child_info, KEY2.to_vec(), CHILD_VALUE2.to_vec()) + .build(); + let genesis_hash = client.genesis_hash(); + let (_client, child) = new_full( + Arc::new(client), + SubscriptionManager::new(Arc::new(TaskExecutor)), + DenyUnsafe::No, + None, + ); + let keys = &[StorageKey(KEY1.to_vec()), StorageKey(KEY2.to_vec())]; + + assert_eq!( + executor::block_on( + child + .storages(prefixed_storage_key(), keys.to_vec(), Some(genesis_hash).into()) + .map(|x| x.into_iter().map(|x| x.map(|y| y.0.len()).unwrap()).sum::()) + .compat(), + ) + .unwrap(), + CHILD_VALUE1.len() + CHILD_VALUE2.len(), + ); +} + #[test] fn should_return_child_storage() { let child_info = ChildInfo::new_default(STORAGE_KEY); @@ -130,6 +165,49 @@ fn should_return_child_storage() { assert_matches!(child.storage_size(child_key.clone(), key.clone(), None).wait(), Ok(Some(1))); } +#[test] +fn should_return_child_storages() { + let child_info = ChildInfo::new_default(STORAGE_KEY); + let client = Arc::new( + substrate_test_runtime_client::TestClientBuilder::new() + .add_child_storage(&child_info, "key1", vec![42_u8]) + .add_child_storage(&child_info, "key2", vec![43_u8, 44]) + .build(), + ); + let genesis_hash = client.genesis_hash(); + let (_client, child) = + new_full(client, SubscriptionManager::new(Arc::new(TaskExecutor)), DenyUnsafe::No, None); + let child_key = prefixed_storage_key(); + let keys = vec![StorageKey(b"key1".to_vec()), StorageKey(b"key2".to_vec())]; + + let res = child + .storages(child_key.clone(), keys.clone(), Some(genesis_hash).into()) + .wait() + .unwrap(); + + assert_matches!( + res[0], + Some(StorageData(ref d)) + if d[0] == 42 && d.len() == 1 + ); + assert_matches!( + res[1], + Some(StorageData(ref d)) + if d[0] == 43 && d[1] == 44 && d.len() == 2 + ); + assert_matches!( + child + .storage_hash(child_key.clone(), keys[0].clone(), Some(genesis_hash).into(),) + .wait() + .map(|x| x.is_some()), + Ok(true) + ); + assert_matches!( + child.storage_size(child_key.clone(), keys[0].clone(), None).wait(), + Ok(Some(1)) + ); +} + #[test] fn should_call_contract() { let client = Arc::new(substrate_test_runtime_client::new()); From ab725c8091b0e804da80d6716a135d8ae960a315 Mon Sep 17 00:00:00 2001 From: Falco Hirschenberger Date: Tue, 3 Aug 2021 15:15:21 +0200 Subject: [PATCH 02/16] Query all keys in one request and add more tests --- client/rpc-api/src/child_state/mod.rs | 4 +- client/rpc/src/state/mod.rs | 8 +- client/rpc/src/state/state_full.rs | 4 +- client/rpc/src/state/state_light.rs | 105 +++++++++++++------------- client/rpc/src/state/tests.rs | 44 ++++++++--- 5 files changed, 94 insertions(+), 71 deletions(-) diff --git a/client/rpc-api/src/child_state/mod.rs b/client/rpc-api/src/child_state/mod.rs index d7edbc4f0a220..de94790d09907 100644 --- a/client/rpc-api/src/child_state/mod.rs +++ b/client/rpc-api/src/child_state/mod.rs @@ -67,8 +67,8 @@ pub trait ChildStateApi { ) -> FutureResult>; /// Returns child storage entries for multiple keys at a specific block's state. - #[rpc(name = "childstate_getStorages")] - fn storages( + #[rpc(name = "childstate_getStorageEntries")] + fn storage_entries( &self, child_storage_key: PrefixedStorageKey, keys: Vec, diff --git a/client/rpc/src/state/mod.rs b/client/rpc/src/state/mod.rs index 0cbf2eca1b13a..f6d70745cf8d4 100644 --- a/client/rpc/src/state/mod.rs +++ b/client/rpc/src/state/mod.rs @@ -97,7 +97,7 @@ where ) -> FutureResult>; /// Returns storage entries for multiple keys at a specific block's state. - fn storages( + fn storage_entries( &self, block: Option, keys: Vec, @@ -470,7 +470,7 @@ where ) -> FutureResult>; /// Returns child storage entries at a specific block's state. - fn storages( + fn storage_entries( &self, block: Option, storage_key: PrefixedStorageKey, @@ -526,13 +526,13 @@ where self.backend.storage(block, storage_key, key) } - fn storages( + fn storage_entries( &self, storage_key: PrefixedStorageKey, keys: Vec, block: Option, ) -> FutureResult>> { - self.backend.storages(block, storage_key, keys) + self.backend.storage_entries(block, storage_key, keys) } fn storage_keys( diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index d553e94e98617..aa0990f6b5882 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -361,7 +361,7 @@ where )) } - fn storages( + fn storage_entries( &self, block: Option, keys: Vec, @@ -741,7 +741,7 @@ where )) } - fn storages( + fn storage_entries( &self, block: Option, storage_key: PrefixedStorageKey, diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index e18652cbcbd96..78a8d255942f1 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -30,7 +30,7 @@ use log::warn; use parking_lot::Mutex; use rpc::{ futures::{ - future::{join_all, result, Future}, + future::{result, Future}, stream::Stream, Sink, }, @@ -245,24 +245,23 @@ where ) } - fn storages( + fn storage_entries( &self, block: Option, keys: Vec, ) -> FutureResult>> { - let remote_blockchain = self.remote_blockchain.clone(); - let fetcher = self.fetcher.clone(); - let block = self.block_or_best(block); - Box::new(join_all(keys.into_iter().map(move |key| { - storage(&*remote_blockchain, fetcher.clone(), block, vec![key.0.clone()]) - .boxed() - .compat() - .map(move |mut values| { - values - .remove(&key) - .expect("successful request has entries for all requested keys; qed") - }) - }))) + let keys = keys.iter().map(|k| k.0.clone()).collect::>(); + Box::new( + storage( + &*self.remote_blockchain, + self.fetcher.clone(), + self.block_or_best(block), + keys, + ) + .boxed() + .compat() + .map(|v| v.into_values().collect::>()), + ) } fn storage_hash( @@ -583,7 +582,7 @@ where Box::new(child_storage.boxed().compat()) } - fn storages( + fn storage_entries( &self, block: Option, storage_key: PrefixedStorageKey, @@ -591,42 +590,46 @@ where ) -> FutureResult>> { let block = self.block_or_best(block); let fetcher = self.fetcher.clone(); - let remote_blockchain = self.remote_blockchain.clone(); - Box::new(join_all(keys.into_iter().map(move |key| { - let storage_key = storage_key.clone(); - let fetcher2 = fetcher.clone(); - let child_storage = - resolve_header(&*remote_blockchain, &*fetcher, block).then(move |result| { - match result { - Ok(header) => Either::Left( - fetcher2 - .remote_read_child(RemoteReadChildRequest { - block, - header, - storage_key, - keys: vec![key.0.clone()], - retry_count: Default::default(), - }) - .then(move |result| { - ready( - result - .map(|mut data| { - data.remove(&key.0) - .expect( - "successful result has entry for all keys; qed", - ) - .map(StorageData) - }) - .map_err(client_err), - ) - }), - ), - Err(error) => Either::Right(ready(Err(error))), - } - }); + let keys = keys.iter().map(|k| k.0.clone()).collect::>(); + let child_storage = + resolve_header(&*self.remote_blockchain, &*self.fetcher, block).then(move |result| { + match result { + Ok(header) => Either::Left( + fetcher + .remote_read_child(RemoteReadChildRequest { + block, + header, + storage_key, + keys: keys.clone(), + retry_count: Default::default(), + }) + .then(move |result| { + ready( + result + .map(|data| { + data.iter() + .filter_map(|(k, d)| { + if keys.contains(k) { + if let Some(d) = d { + return Some(Some(StorageData( + d.to_vec(), + ))) + } + }; + + None + }) + .collect::>() + }) + .map_err(client_err), + ) + }), + ), + Err(error) => Either::Right(ready(Err(error))), + } + }); - Box::new(child_storage.boxed().compat()) - }))) + Box::new(child_storage.boxed().compat()) } fn storage_hash( diff --git a/client/rpc/src/state/tests.rs b/client/rpc/src/state/tests.rs index d2aab2f3e7d37..1374046f4b1ff 100644 --- a/client/rpc/src/state/tests.rs +++ b/client/rpc/src/state/tests.rs @@ -100,7 +100,7 @@ fn should_return_storage() { } #[test] -fn should_return_storages() { +fn should_return_storage_entries() { const KEY1: &[u8] = b":mock"; const KEY2: &[u8] = b":turtle"; const VALUE: &[u8] = b"hello world"; @@ -120,17 +120,26 @@ fn should_return_storages() { DenyUnsafe::No, None, ); - let keys = &[StorageKey(KEY1.to_vec()), StorageKey(KEY2.to_vec())]; + let keys = &[StorageKey(KEY1.to_vec()), StorageKey(KEY2.to_vec())]; assert_eq!( - executor::block_on( - child - .storages(prefixed_storage_key(), keys.to_vec(), Some(genesis_hash).into()) - .map(|x| x.into_iter().map(|x| x.map(|y| y.0.len()).unwrap()).sum::()) - .compat(), - ) - .unwrap(), - CHILD_VALUE1.len() + CHILD_VALUE2.len(), + child + .storage_entries(prefixed_storage_key(), keys.to_vec(), Some(genesis_hash).into()) + .wait() + .map(|x| x.into_iter().map(|x| x.map(|x| x.0.len()).unwrap()).sum::()) + .unwrap(), + CHILD_VALUE1.len() + CHILD_VALUE2.len() + ); + + // should fail if not all keys exist. + let mut failing_keys = vec![StorageKey(b":soup".to_vec())]; + failing_keys.extend_from_slice(keys); + assert_matches!( + child + .storage_entries(prefixed_storage_key(), failing_keys, Some(genesis_hash).into()) + .wait() + .map(|x| x.iter().all(|x| x.is_some())), + Ok(false) ); } @@ -156,6 +165,17 @@ fn should_return_child_storage() { ).wait(), Ok(Some(StorageData(ref d))) if d[0] == 42 && d.len() == 1 ); + + // should fail if key does not exist. + let failing_key = StorageKey(b":soup".to_vec()); + assert_matches!( + child + .storage(prefixed_storage_key(), failing_key, Some(genesis_hash).into()) + .wait() + .map(|x| x.is_some()), + Ok(false) + ); + assert_matches!( child .storage_hash(child_key.clone(), key.clone(), Some(genesis_hash).into(),) @@ -167,7 +187,7 @@ fn should_return_child_storage() { } #[test] -fn should_return_child_storages() { +fn should_return_child_storage_entries() { let child_info = ChildInfo::new_default(STORAGE_KEY); let client = Arc::new( substrate_test_runtime_client::TestClientBuilder::new() @@ -182,7 +202,7 @@ fn should_return_child_storages() { let keys = vec![StorageKey(b"key1".to_vec()), StorageKey(b"key2".to_vec())]; let res = child - .storages(child_key.clone(), keys.clone(), Some(genesis_hash).into()) + .storage_entries(child_key.clone(), keys.clone(), Some(genesis_hash).into()) .wait() .unwrap(); From a23ed693bb269c4eab9f52c6798c1d84e1b7e928 Mon Sep 17 00:00:00 2001 From: Falco Hirschenberger Date: Tue, 3 Aug 2021 16:01:59 +0200 Subject: [PATCH 03/16] Make it compatible with stable release channel --- client/rpc/src/state/state_light.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index 78a8d255942f1..0e42b2cc01924 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -260,7 +260,7 @@ where ) .boxed() .compat() - .map(|v| v.into_values().collect::>()), + .map(|v| v.into_iter().map(|x| x.1).collect::>()), ) } From d73a745580ba1e28f2b9d1d36dc5be284db0ce9a Mon Sep 17 00:00:00 2001 From: Falco Hirschenberger Date: Tue, 31 Aug 2021 20:11:00 +0200 Subject: [PATCH 04/16] Update to new futures --- client/rpc/src/state/state_full.rs | 55 ++++++++++++++++------------- client/rpc/src/state/state_light.rs | 14 ++------ client/rpc/src/state/tests.rs | 54 ++++++++++++++++------------ 3 files changed, 65 insertions(+), 58 deletions(-) diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index 99f6ed4385ec4..0b73995e95f31 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -18,16 +18,14 @@ //! State API backend for full nodes. -use futures::{future, stream, FutureExt, SinkExt, StreamExt}; +use futures::{ + future, + future::{err, try_join_all}, + stream, FutureExt, SinkExt, StreamExt, +}; use jsonrpc_pubsub::{manager::SubscriptionManager, typed::Subscriber, SubscriptionId}; use log::warn; -use rpc::{ - futures::{ - future::{join_all, result}, - stream, Future, Sink, Stream, - }, - Result as RpcResult, -}; +use rpc::Result as RpcResult; use std::{ collections::{BTreeMap, HashMap}, ops::Range, @@ -369,13 +367,15 @@ where ) -> FutureResult>> { let block = match self.block_or_best(block) { Ok(b) => b, - Err(e) => return Box::new(result(Err(client_err(e)))), + Err(e) => return Box::pin(err(client_err(e))), }; let client = self.client.clone(); - Box::new(join_all( - keys.into_iter() - .map(move |key| client.storage(&BlockId::Hash(block), &key).map_err(client_err)), - )) + try_join_all(keys.into_iter().map(move |key| { + let client = client.clone(); + + async move { client.clone().storage(&BlockId::Hash(block), &key).map_err(client_err) } + })) + .boxed() } fn storage_size( @@ -743,22 +743,27 @@ where storage_key: PrefixedStorageKey, keys: Vec, ) -> FutureResult>> { + let child_info = match ChildType::from_prefixed_key(&storage_key) { + Some((ChildType::ParentKeyId, storage_key)) => + Arc::new(ChildInfo::new_default(storage_key)), + None => return Box::pin(err(client_err(sp_blockchain::Error::InvalidChildStorageKey))), + }; let block = match self.block_or_best(block) { Ok(b) => b, - Err(e) => return Box::new(result(Err(client_err(e)))), + Err(e) => return Box::pin(err(client_err(e))), }; let client = self.client.clone(); - Box::new( - join_all(keys.into_iter().map(move |key| { - let child_info = match ChildType::from_prefixed_key(&storage_key) { - Some((ChildType::ParentKeyId, storage_key)) => - ChildInfo::new_default(storage_key), - None => return Err(sp_blockchain::Error::InvalidChildStorageKey), - }; - client.child_storage(&BlockId::Hash(block), &child_info, &key) - })) - .map_err(client_err), - ) + try_join_all(keys.into_iter().map(move |key| { + let client = client.clone(); + let child_info = child_info.clone(); + async move { + client + .clone() + .child_storage(&BlockId::Hash(block), &child_info, &key) + .map_err(client_err) + } + })) + .boxed() } fn storage_hash( diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index bffb807e82137..fad2472530495 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -239,17 +239,9 @@ where keys: Vec, ) -> FutureResult>> { let keys = keys.iter().map(|k| k.0.clone()).collect::>(); - Box::new( - storage( - &*self.remote_blockchain, - self.fetcher.clone(), - self.block_or_best(block), - keys, - ) + storage(&*self.remote_blockchain, self.fetcher.clone(), self.block_or_best(block), keys) + .map_ok(|v| v.into_iter().map(|x| x.1).collect::>()) .boxed() - .compat() - .map(|v| v.into_iter().map(|x| x.1).collect::>()), - ) } fn storage_hash( @@ -597,7 +589,7 @@ where } }); - Box::new(child_storage.boxed().compat()) + Box::pin(child_storage.boxed()) } fn storage_hash( diff --git a/client/rpc/src/state/tests.rs b/client/rpc/src/state/tests.rs index 20e64b6ebf2bb..712fe00c54386 100644 --- a/client/rpc/src/state/tests.rs +++ b/client/rpc/src/state/tests.rs @@ -117,11 +117,13 @@ fn should_return_storage_entries() { let keys = &[StorageKey(KEY1.to_vec()), StorageKey(KEY2.to_vec())]; assert_eq!( - child - .storage_entries(prefixed_storage_key(), keys.to_vec(), Some(genesis_hash).into()) - .wait() - .map(|x| x.into_iter().map(|x| x.map(|x| x.0.len()).unwrap()).sum::()) - .unwrap(), + executor::block_on(child.storage_entries( + prefixed_storage_key(), + keys.to_vec(), + Some(genesis_hash).into() + )) + .map(|x| x.into_iter().map(|x| x.map(|x| x.0.len()).unwrap()).sum::()) + .unwrap(), CHILD_VALUE1.len() + CHILD_VALUE2.len() ); @@ -129,10 +131,12 @@ fn should_return_storage_entries() { let mut failing_keys = vec![StorageKey(b":soup".to_vec())]; failing_keys.extend_from_slice(keys); assert_matches!( - child - .storage_entries(prefixed_storage_key(), failing_keys, Some(genesis_hash).into()) - .wait() - .map(|x| x.iter().all(|x| x.is_some())), + executor::block_on(child.storage_entries( + prefixed_storage_key(), + failing_keys, + Some(genesis_hash).into() + )) + .map(|x| x.iter().all(|x| x.is_some())), Ok(false) ); } @@ -163,10 +167,12 @@ fn should_return_child_storage() { // should fail if key does not exist. let failing_key = StorageKey(b":soup".to_vec()); assert_matches!( - child - .storage(prefixed_storage_key(), failing_key, Some(genesis_hash).into()) - .wait() - .map(|x| x.is_some()), + executor::block_on(child.storage( + prefixed_storage_key(), + failing_key, + Some(genesis_hash).into() + )) + .map(|x| x.is_some()), Ok(false) ); @@ -200,10 +206,12 @@ fn should_return_child_storage_entries() { let child_key = prefixed_storage_key(); let keys = vec![StorageKey(b"key1".to_vec()), StorageKey(b"key2".to_vec())]; - let res = child - .storage_entries(child_key.clone(), keys.clone(), Some(genesis_hash).into()) - .wait() - .unwrap(); + let res = executor::block_on(child.storage_entries( + child_key.clone(), + keys.clone(), + Some(genesis_hash).into(), + )) + .unwrap(); assert_matches!( res[0], @@ -216,14 +224,16 @@ fn should_return_child_storage_entries() { if d[0] == 43 && d[1] == 44 && d.len() == 2 ); assert_matches!( - child - .storage_hash(child_key.clone(), keys[0].clone(), Some(genesis_hash).into(),) - .wait() - .map(|x| x.is_some()), + executor::block_on(child.storage_hash( + child_key.clone(), + keys[0].clone(), + Some(genesis_hash).into() + )) + .map(|x| x.is_some()), Ok(true) ); assert_matches!( - child.storage_size(child_key.clone(), keys[0].clone(), None).wait(), + executor::block_on(child.storage_size(child_key.clone(), keys[0].clone(), None)), Ok(Some(1)) ); } From 0cbe5eb07a565cdb0fdb9ae083ddd9f76617363b Mon Sep 17 00:00:00 2001 From: Falco Hirschenberger Date: Thu, 9 Sep 2021 11:58:01 +0200 Subject: [PATCH 05/16] Update client/rpc/src/state/state_full.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- client/rpc/src/state/state_full.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index 0b73995e95f31..5251f4d33a5a1 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -367,7 +367,7 @@ where ) -> FutureResult>> { let block = match self.block_or_best(block) { Ok(b) => b, - Err(e) => return Box::pin(err(client_err(e))), + Err(e) => return err(client_err(e)).boxed(), }; let client = self.client.clone(); try_join_all(keys.into_iter().map(move |key| { From cd4c158395294bcb1bb1f08d8cfb721d9c16dc13 Mon Sep 17 00:00:00 2001 From: Falco Hirschenberger Date: Thu, 9 Sep 2021 11:58:53 +0200 Subject: [PATCH 06/16] Update client/rpc/src/state/state_full.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- client/rpc/src/state/state_full.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index 5251f4d33a5a1..c499e72f4a08b 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -371,9 +371,9 @@ where }; let client = self.client.clone(); try_join_all(keys.into_iter().map(move |key| { - let client = client.clone(); + let res = client.storage(&BlockId::Hash(block), &key).map_err(client_err); - async move { client.clone().storage(&BlockId::Hash(block), &key).map_err(client_err) } + async move { res } })) .boxed() } From 3199a10c8818a8b29e235df509dd49168a0e62e0 Mon Sep 17 00:00:00 2001 From: Falco Hirschenberger Date: Thu, 9 Sep 2021 11:59:46 +0200 Subject: [PATCH 07/16] Update client/rpc/src/state/state_full.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- client/rpc/src/state/state_full.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index c499e72f4a08b..33ed4867c145f 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -746,7 +746,7 @@ where let child_info = match ChildType::from_prefixed_key(&storage_key) { Some((ChildType::ParentKeyId, storage_key)) => Arc::new(ChildInfo::new_default(storage_key)), - None => return Box::pin(err(client_err(sp_blockchain::Error::InvalidChildStorageKey))), + None => return err(client_err(sp_blockchain::Error::InvalidChildStorageKey)).boxed(), }; let block = match self.block_or_best(block) { Ok(b) => b, From a1b6eed00abbe6147f138d63ca8a5bd7c478fed2 Mon Sep 17 00:00:00 2001 From: Falco Hirschenberger Date: Thu, 9 Sep 2021 11:59:56 +0200 Subject: [PATCH 08/16] Update client/rpc/src/state/state_full.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- client/rpc/src/state/state_full.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index 33ed4867c145f..bcf035e72cdc1 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -750,7 +750,7 @@ where }; let block = match self.block_or_best(block) { Ok(b) => b, - Err(e) => return Box::pin(err(client_err(e))), + Err(e) => return err(client_err(e)).boxed(), }; let client = self.client.clone(); try_join_all(keys.into_iter().map(move |key| { From 83251ade7ad4da05916608afad83023a80832ddd Mon Sep 17 00:00:00 2001 From: Falco Hirschenberger Date: Thu, 9 Sep 2021 12:00:25 +0200 Subject: [PATCH 09/16] Update client/rpc/src/state/state_full.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- client/rpc/src/state/state_full.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index bcf035e72cdc1..acb5195f7cdc0 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -754,13 +754,13 @@ where }; let client = self.client.clone(); try_join_all(keys.into_iter().map(move |key| { - let client = client.clone(); - let child_info = child_info.clone(); - async move { - client + let res = client .clone() .child_storage(&BlockId::Hash(block), &child_info, &key) - .map_err(client_err) + .map_err(client_err); + + async move { + res } })) .boxed() From 58fe359e32a393e2d6a3bbe38407d9760fdad4f1 Mon Sep 17 00:00:00 2001 From: Falco Hirschenberger Date: Thu, 9 Sep 2021 12:00:54 +0200 Subject: [PATCH 10/16] Update client/rpc/src/state/state_light.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- client/rpc/src/state/state_light.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index fad2472530495..64dcfdc393dd3 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -569,15 +569,7 @@ where .map(|data| { data.iter() .filter_map(|(k, d)| { - if keys.contains(k) { - if let Some(d) = d { - return Some(Some(StorageData( - d.to_vec(), - ))) - } - }; - - None + keys.contains(k).then(|| d.map(|v| StorageData(v.to_vec()))) }) .collect::>() }) From f3e3ce335cef50900cf43f3487b619bccdf19162 Mon Sep 17 00:00:00 2001 From: Falco Hirschenberger Date: Thu, 9 Sep 2021 12:01:04 +0200 Subject: [PATCH 11/16] Update client/rpc/src/state/state_light.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- client/rpc/src/state/state_light.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index 64dcfdc393dd3..74fb74c2296dc 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -581,7 +581,7 @@ where } }); - Box::pin(child_storage.boxed()) + child_storage.boxed() } fn storage_hash( From d6187048665b936befaddb2a6b84221843e9df35 Mon Sep 17 00:00:00 2001 From: Falco Hirschenberger Date: Thu, 9 Sep 2021 12:12:50 +0200 Subject: [PATCH 12/16] Satisfy borrowck --- client/rpc/src/state/state_light.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index 74fb74c2296dc..fde461f5d2d20 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -569,7 +569,7 @@ where .map(|data| { data.iter() .filter_map(|(k, d)| { - keys.contains(k).then(|| d.map(|v| StorageData(v.to_vec()))) + keys.contains(k).then(|| d.as_ref().map(|v| StorageData(v.to_vec()))) }) .collect::>() }) From d840015c59ce865f879178594088c79082e8d151 Mon Sep 17 00:00:00 2001 From: Falco Hirschenberger Date: Thu, 9 Sep 2021 13:47:55 +0200 Subject: [PATCH 13/16] Remove non-RPC `storage_entries` functions. --- client/rpc/src/state/mod.rs | 7 ------- client/rpc/src/state/state_full.rs | 20 +------------------- client/rpc/src/state/state_light.rs | 11 ----------- 3 files changed, 1 insertion(+), 37 deletions(-) diff --git a/client/rpc/src/state/mod.rs b/client/rpc/src/state/mod.rs index 72c5c4ddb085e..80eccc2c97deb 100644 --- a/client/rpc/src/state/mod.rs +++ b/client/rpc/src/state/mod.rs @@ -94,13 +94,6 @@ where key: StorageKey, ) -> FutureResult>; - /// Returns storage entries for multiple keys at a specific block's state. - fn storage_entries( - &self, - block: Option, - keys: Vec, - ) -> FutureResult>>; - /// Returns the hash of a storage entry at a block's state. fn storage_hash( &self, diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index acb5195f7cdc0..2b996633be011 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -360,24 +360,6 @@ where async move { r }.boxed() } - fn storage_entries( - &self, - block: Option, - keys: Vec, - ) -> FutureResult>> { - let block = match self.block_or_best(block) { - Ok(b) => b, - Err(e) => return err(client_err(e)).boxed(), - }; - let client = self.client.clone(); - try_join_all(keys.into_iter().map(move |key| { - let res = client.storage(&BlockId::Hash(block), &key).map_err(client_err); - - async move { res } - })) - .boxed() - } - fn storage_size( &self, block: Option, @@ -758,7 +740,7 @@ where .clone() .child_storage(&BlockId::Hash(block), &child_info, &key) .map_err(client_err); - + async move { res } diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index fde461f5d2d20..45f97604f6f4c 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -233,17 +233,6 @@ where .boxed() } - fn storage_entries( - &self, - block: Option, - keys: Vec, - ) -> FutureResult>> { - let keys = keys.iter().map(|k| k.0.clone()).collect::>(); - storage(&*self.remote_blockchain, self.fetcher.clone(), self.block_or_best(block), keys) - .map_ok(|v| v.into_iter().map(|x| x.1).collect::>()) - .boxed() - } - fn storage_hash( &self, block: Option, From 5813b439a4b467e022c627e3fe60cf2fa5520db4 Mon Sep 17 00:00:00 2001 From: Falco Hirschenberger Date: Thu, 9 Sep 2021 13:51:58 +0200 Subject: [PATCH 14/16] Revert "Remove non-RPC `storage_entries` functions." This reverts commit d840015c59ce865f879178594088c79082e8d151. --- client/rpc/src/state/mod.rs | 7 +++++++ client/rpc/src/state/state_full.rs | 20 +++++++++++++++++++- client/rpc/src/state/state_light.rs | 11 +++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/client/rpc/src/state/mod.rs b/client/rpc/src/state/mod.rs index 80eccc2c97deb..72c5c4ddb085e 100644 --- a/client/rpc/src/state/mod.rs +++ b/client/rpc/src/state/mod.rs @@ -94,6 +94,13 @@ where key: StorageKey, ) -> FutureResult>; + /// Returns storage entries for multiple keys at a specific block's state. + fn storage_entries( + &self, + block: Option, + keys: Vec, + ) -> FutureResult>>; + /// Returns the hash of a storage entry at a block's state. fn storage_hash( &self, diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index 2b996633be011..acb5195f7cdc0 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -360,6 +360,24 @@ where async move { r }.boxed() } + fn storage_entries( + &self, + block: Option, + keys: Vec, + ) -> FutureResult>> { + let block = match self.block_or_best(block) { + Ok(b) => b, + Err(e) => return err(client_err(e)).boxed(), + }; + let client = self.client.clone(); + try_join_all(keys.into_iter().map(move |key| { + let res = client.storage(&BlockId::Hash(block), &key).map_err(client_err); + + async move { res } + })) + .boxed() + } + fn storage_size( &self, block: Option, @@ -740,7 +758,7 @@ where .clone() .child_storage(&BlockId::Hash(block), &child_info, &key) .map_err(client_err); - + async move { res } diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index 45f97604f6f4c..fde461f5d2d20 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -233,6 +233,17 @@ where .boxed() } + fn storage_entries( + &self, + block: Option, + keys: Vec, + ) -> FutureResult>> { + let keys = keys.iter().map(|k| k.0.clone()).collect::>(); + storage(&*self.remote_blockchain, self.fetcher.clone(), self.block_or_best(block), keys) + .map_ok(|v| v.into_iter().map(|x| x.1).collect::>()) + .boxed() + } + fn storage_hash( &self, block: Option, From a001771c3bd774448cab1b52cb44dbaaea90711f Mon Sep 17 00:00:00 2001 From: Falco Hirschenberger Date: Thu, 9 Sep 2021 13:57:27 +0200 Subject: [PATCH 15/16] Revert "Revert "Remove non-RPC `storage_entries` functions."" This reverts commit 5813b439a4b467e022c627e3fe60cf2fa5520db4. --- client/rpc/src/state/mod.rs | 7 ------- client/rpc/src/state/state_full.rs | 20 +------------------- client/rpc/src/state/state_light.rs | 11 ----------- 3 files changed, 1 insertion(+), 37 deletions(-) diff --git a/client/rpc/src/state/mod.rs b/client/rpc/src/state/mod.rs index 72c5c4ddb085e..80eccc2c97deb 100644 --- a/client/rpc/src/state/mod.rs +++ b/client/rpc/src/state/mod.rs @@ -94,13 +94,6 @@ where key: StorageKey, ) -> FutureResult>; - /// Returns storage entries for multiple keys at a specific block's state. - fn storage_entries( - &self, - block: Option, - keys: Vec, - ) -> FutureResult>>; - /// Returns the hash of a storage entry at a block's state. fn storage_hash( &self, diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index acb5195f7cdc0..2b996633be011 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -360,24 +360,6 @@ where async move { r }.boxed() } - fn storage_entries( - &self, - block: Option, - keys: Vec, - ) -> FutureResult>> { - let block = match self.block_or_best(block) { - Ok(b) => b, - Err(e) => return err(client_err(e)).boxed(), - }; - let client = self.client.clone(); - try_join_all(keys.into_iter().map(move |key| { - let res = client.storage(&BlockId::Hash(block), &key).map_err(client_err); - - async move { res } - })) - .boxed() - } - fn storage_size( &self, block: Option, @@ -758,7 +740,7 @@ where .clone() .child_storage(&BlockId::Hash(block), &child_info, &key) .map_err(client_err); - + async move { res } diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index fde461f5d2d20..45f97604f6f4c 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -233,17 +233,6 @@ where .boxed() } - fn storage_entries( - &self, - block: Option, - keys: Vec, - ) -> FutureResult>> { - let keys = keys.iter().map(|k| k.0.clone()).collect::>(); - storage(&*self.remote_blockchain, self.fetcher.clone(), self.block_or_best(block), keys) - .map_ok(|v| v.into_iter().map(|x| x.1).collect::>()) - .boxed() - } - fn storage_hash( &self, block: Option, From 19f5d248c896827f9da09bdcc6381f758441e8d9 Mon Sep 17 00:00:00 2001 From: Falco Hirschenberger Date: Thu, 9 Sep 2021 14:15:15 +0200 Subject: [PATCH 16/16] Finally some formatting --- client/rpc/src/state/state_full.rs | 10 ++++------ client/rpc/src/state/state_light.rs | 4 +++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index 2b996633be011..97f77a4077962 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -737,13 +737,11 @@ where let client = self.client.clone(); try_join_all(keys.into_iter().map(move |key| { let res = client - .clone() - .child_storage(&BlockId::Hash(block), &child_info, &key) - .map_err(client_err); + .clone() + .child_storage(&BlockId::Hash(block), &child_info, &key) + .map_err(client_err); - async move { - res - } + async move { res } })) .boxed() } diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index 45f97604f6f4c..749e57c365cc0 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -558,7 +558,9 @@ where .map(|data| { data.iter() .filter_map(|(k, d)| { - keys.contains(k).then(|| d.as_ref().map(|v| StorageData(v.to_vec()))) + keys.contains(k).then(|| { + d.as_ref().map(|v| StorageData(v.to_vec())) + }) }) .collect::>() })