chainHead: Sync events with spec (#14654)

* chainHead/events: Remove network config

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* chainHead/events: Add events for operations

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* chainHead/tests: Test chainHead events serialize/deserialize

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* chainHead/events: Remove generics from the storage event

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* chainHead/events: Rename kebab-case to camelCase

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* chainHead/events: Add methodResponse object

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
This commit is contained in:
Alexandru Vasile
2023-07-31 10:26:13 +03:00
committed by GitHub
parent 6da4e90e51
commit 6d5f0a1f1d
6 changed files with 328 additions and 124 deletions
@@ -19,7 +19,7 @@
#![allow(non_snake_case)]
//! API trait of the chain head.
use crate::chain_head::event::{ChainHeadEvent, FollowEvent, NetworkConfig, StorageQuery};
use crate::chain_head::event::{ChainHeadEvent, FollowEvent, StorageQuery};
use jsonrpsee::{core::RpcResult, proc_macros::rpc};
#[rpc(client, server)]
@@ -52,12 +52,7 @@ pub trait ChainHeadApi<Hash> {
unsubscribe = "chainHead_unstable_stopBody",
item = ChainHeadEvent<String>,
)]
fn chain_head_unstable_body(
&self,
follow_subscription: String,
hash: Hash,
network_config: Option<NetworkConfig>,
);
fn chain_head_unstable_body(&self, follow_subscription: String, hash: Hash);
/// Retrieves the header of a pinned block.
///
@@ -102,7 +97,6 @@ pub trait ChainHeadApi<Hash> {
hash: Hash,
items: Vec<StorageQuery<String>>,
child_trie: Option<String>,
network_config: Option<NetworkConfig>,
);
/// Call into the Runtime API at a specified block's state.
@@ -121,7 +115,6 @@ pub trait ChainHeadApi<Hash> {
hash: Hash,
function: String,
call_parameters: String,
network_config: Option<NetworkConfig>,
);
/// Unpin a block reported by the `follow` method.
@@ -23,7 +23,7 @@ use crate::{
api::ChainHeadApiServer,
chain_head_follow::ChainHeadFollower,
error::Error as ChainHeadRpcError,
event::{ChainHeadEvent, ChainHeadResult, ErrorEvent, FollowEvent, NetworkConfig},
event::{ChainHeadEvent, ChainHeadResult, ErrorEvent, FollowEvent},
hex_string,
subscription::{SubscriptionManagement, SubscriptionManagementError},
},
@@ -205,7 +205,6 @@ where
mut sink: SubscriptionSink,
follow_subscription: String,
hash: Block::Hash,
_network_config: Option<NetworkConfig>,
) -> SubscriptionResult {
let client = self.client.clone();
let subscriptions = self.subscriptions.clone();
@@ -294,7 +293,6 @@ where
hash: Block::Hash,
items: Vec<StorageQuery<String>>,
child_trie: Option<String>,
_network_config: Option<NetworkConfig>,
) -> SubscriptionResult {
// Gain control over parameter parsing and returned error.
let items = items
@@ -327,7 +325,7 @@ where
Ok(block) => block,
Err(SubscriptionManagementError::SubscriptionAbsent) => {
// Invalid invalid subscription ID.
let _ = sink.send(&ChainHeadStorageEvent::<String>::Disjoint);
let _ = sink.send(&ChainHeadStorageEvent::Disjoint);
return Ok(())
},
Err(SubscriptionManagementError::BlockHashAbsent) => {
@@ -336,9 +334,8 @@ where
return Ok(())
},
Err(error) => {
let _ = sink.send(&ChainHeadStorageEvent::<String>::Error(ErrorEvent {
error: error.to_string(),
}));
let _ = sink
.send(&ChainHeadStorageEvent::Error(ErrorEvent { error: error.to_string() }));
return Ok(())
},
};
@@ -362,7 +359,6 @@ where
hash: Block::Hash,
function: String,
call_parameters: String,
_network_config: Option<NetworkConfig>,
) -> SubscriptionResult {
let call_parameters = Bytes::from(parse_hex_param(&mut sink, call_parameters)?);
@@ -70,10 +70,10 @@ fn is_key_queryable(key: &[u8]) -> bool {
}
/// The result of making a query call.
type QueryResult = Result<Option<StorageResult<String>>, ChainHeadStorageEvent<String>>;
type QueryResult = Result<Option<StorageResult>, ChainHeadStorageEvent>;
/// The result of iterating over keys.
type QueryIterResult = Result<Vec<StorageResult<String>>, ChainHeadStorageEvent<String>>;
type QueryIterResult = Result<Vec<StorageResult>, ChainHeadStorageEvent>;
impl<Client, Block, BE> ChainHeadStorage<Client, Block, BE>
where
@@ -96,13 +96,13 @@ where
result
.map(|opt| {
QueryResult::Ok(opt.map(|storage_data| StorageResult::<String> {
QueryResult::Ok(opt.map(|storage_data| StorageResult {
key: hex_string(&key.0),
result: StorageResultType::Value(hex_string(&storage_data.0)),
}))
})
.unwrap_or_else(|err| {
QueryResult::Err(ChainHeadStorageEvent::<String>::Error(ErrorEvent {
QueryResult::Err(ChainHeadStorageEvent::Error(ErrorEvent {
error: err.to_string(),
}))
})
@@ -123,13 +123,13 @@ where
result
.map(|opt| {
QueryResult::Ok(opt.map(|storage_data| StorageResult::<String> {
QueryResult::Ok(opt.map(|storage_data| StorageResult {
key: hex_string(&key.0),
result: StorageResultType::Hash(hex_string(&storage_data.as_ref())),
}))
})
.unwrap_or_else(|err| {
QueryResult::Err(ChainHeadStorageEvent::<String>::Error(ErrorEvent {
QueryResult::Err(ChainHeadStorageEvent::Error(ErrorEvent {
error: err.to_string(),
}))
})
@@ -148,9 +148,7 @@ where
} else {
self.client.storage_keys(hash, Some(key), None)
}
.map_err(|err| {
ChainHeadStorageEvent::<String>::Error(ErrorEvent { error: err.to_string() })
})?;
.map_err(|err| ChainHeadStorageEvent::Error(ErrorEvent { error: err.to_string() }))?;
let mut ret = Vec::with_capacity(MAX_ITER_ITEMS);
let mut keys_iter = keys_iter.take(MAX_ITER_ITEMS);
@@ -178,7 +176,7 @@ where
) {
if let Some(child_key) = child_key.as_ref() {
if !is_key_queryable(child_key.storage_key()) {
let _ = sink.send(&ChainHeadStorageEvent::<String>::Done);
let _ = sink.send(&ChainHeadStorageEvent::Done);
return
}
}
@@ -242,6 +240,6 @@ where
let _ = sink.send(&event);
}
let _ = sink.send(&ChainHeadStorageEvent::<String>::Done);
let _ = sink.send(&ChainHeadStorageEvent::Done);
}
}
@@ -21,27 +21,6 @@
use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};
use sp_api::ApiError;
use sp_version::RuntimeVersion;
use std::num::NonZeroUsize;
/// The network config parameter is used when a function
/// needs to request the information from its peers.
///
/// These values can be tweaked depending on the urgency of the JSON-RPC function call.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct NetworkConfig {
/// The total number of peers from which the information is requested.
total_attempts: u64,
/// The maximum number of requests to perform in parallel.
///
/// # Note
///
/// A zero value is illegal.
max_parallel: NonZeroUsize,
/// The time, in milliseconds, after which a single requests towards one peer
/// is considered unsuccessful.
timeout_ms: u64,
}
/// The operation could not be processed due to an error.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
@@ -189,14 +168,76 @@ pub struct Finalized<Hash> {
pub pruned_block_hashes: Vec<Hash>,
}
/// Indicate the operation id of the event.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OperationId {
/// The operation id of the event.
pub operation_id: String,
}
/// The response of the `chainHead_body` method.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OperationBodyDone {
/// The operation id of the event.
pub operation_id: String,
/// Array of hexadecimal-encoded scale-encoded extrinsics found in the block.
pub value: Vec<String>,
}
/// The response of the `chainHead_call` method.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OperationCallDone {
/// The operation id of the event.
pub operation_id: String,
/// Hexadecimal-encoded output of the runtime function call.
pub output: String,
}
/// The response of the `chainHead_call` method.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OperationStorageItems {
/// The operation id of the event.
pub operation_id: String,
/// The resulting items.
pub items: Vec<StorageResult>,
}
/// Indicate a problem during the operation.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OperationError {
/// The operation id of the event.
pub operation_id: String,
/// The reason of the error.
pub error: String,
}
/// The event generated by the `follow` method.
///
/// The events are generated in the following order:
/// The block events are generated in the following order:
/// 1. Initialized - generated only once to signal the latest finalized block
/// 2. NewBlock - a new block was added.
/// 3. BestBlockChanged - indicate that the best block is now the one from this event. The block was
/// announced priorly with the `NewBlock` event.
/// 4. Finalized - State the finalized and pruned blocks.
///
/// The following events are related to operations:
/// - OperationBodyDone: The response of the `chianHead_body`
/// - OperationCallDone: The response of the `chianHead_call`
/// - OperationStorageItems: Items produced by the `chianHead_storage`
/// - OperationWaitingForContinue: Generated after OperationStorageItems and requires the user to
/// call `chainHead_continue`
/// - OperationStorageDone: The `chianHead_storage` method has produced all the results
/// - OperationInaccessible: The server was unable to provide the result, retries might succeed in
/// the future
/// - OperationError: The server encountered an error, retries will not succeed
///
/// The stop event indicates that the JSON-RPC server was unable to provide a consistent list of
/// the blocks at the head of the chain.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "event")]
@@ -211,6 +252,25 @@ pub enum FollowEvent<Hash> {
BestBlockChanged(BestBlockChanged<Hash>),
/// A list of finalized and pruned blocks.
Finalized(Finalized<Hash>),
/// The response of the `chainHead_body` method.
OperationBodyDone(OperationBodyDone),
/// The response of the `chainHead_call` method.
OperationCallDone(OperationCallDone),
/// Yield one or more items found in the storage.
OperationStorageItems(OperationStorageItems),
/// Ask the user to call `chainHead_continue` to produce more events
/// regarding the operation id.
OperationWaitingForContinue(OperationId),
/// The responses of the `chainHead_storage` method have been produced.
OperationStorageDone(OperationId),
/// The RPC server was unable to provide the response of the following operation id.
///
/// Repeating the same operation in the future might succeed.
OperationInaccessible(OperationId),
/// The RPC server encountered an error while processing an operation id.
///
/// Repeating the same operation in the future will not succeed.
OperationError(OperationError),
/// The subscription is dropped and no further events
/// will be generated.
Stop,
@@ -254,7 +314,7 @@ pub struct StorageQuery<Key> {
/// The type of the storage query.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[serde(rename_all = "camelCase")]
pub enum StorageQueryType {
/// Fetch the value of the provided key.
Value,
@@ -271,33 +331,33 @@ pub enum StorageQueryType {
/// The storage result.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct StorageResult<T> {
pub struct StorageResult {
/// The hex-encoded key of the result.
pub key: String,
/// The result of the query.
#[serde(flatten)]
pub result: StorageResultType<T>,
pub result: StorageResultType,
}
/// The type of the storage query.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum StorageResultType<T> {
#[serde(rename_all = "camelCase")]
pub enum StorageResultType {
/// Fetch the value of the provided key.
Value(T),
Value(String),
/// Fetch the hash of the value of the provided key.
Hash(T),
Hash(String),
/// Fetch the closest descendant merkle value.
ClosestDescendantMerkleValue(T),
ClosestDescendantMerkleValue(String),
}
/// The event generated by storage method.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[serde(tag = "event")]
pub enum ChainHeadStorageEvent<T> {
pub enum ChainHeadStorageEvent {
/// The request produced multiple result items.
Items(ItemsEvent<T>),
Items(ItemsEvent),
/// The request produced multiple result items.
WaitForContinue,
/// The request completed successfully and all the results were provided.
@@ -315,9 +375,32 @@ pub enum ChainHeadStorageEvent<T> {
/// The request produced multiple result items.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ItemsEvent<T> {
pub struct ItemsEvent {
/// The resulting items.
pub items: Vec<StorageResult<T>>,
pub items: Vec<StorageResult>,
}
/// The method respose of `chainHead_body`, `chainHead_call` and `chainHead_storage`.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "result")]
pub enum MethodResponse {
/// The method has started.
Started(MethodResponseStarted),
/// The RPC server cannot handle the request at the moment.
LimitReached,
}
/// The `started` result of a method.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MethodResponseStarted {
/// The operation id of the response.
pub operation_id: String,
/// The number of items from the back of the `chainHead_storage` that have been discarded.
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub discarded_items: Option<usize>,
}
#[cfg(test)]
@@ -477,6 +560,109 @@ mod tests {
assert_eq!(event_dec, event);
}
#[test]
fn follow_op_body_event() {
let event: FollowEvent<String> = FollowEvent::OperationBodyDone(OperationBodyDone {
operation_id: "123".into(),
value: vec!["0x1".into()],
});
let ser = serde_json::to_string(&event).unwrap();
let exp = r#"{"event":"operationBodyDone","operationId":"123","value":["0x1"]}"#;
assert_eq!(ser, exp);
let event_dec: FollowEvent<String> = serde_json::from_str(exp).unwrap();
assert_eq!(event_dec, event);
}
#[test]
fn follow_op_call_event() {
let event: FollowEvent<String> = FollowEvent::OperationCallDone(OperationCallDone {
operation_id: "123".into(),
output: "0x1".into(),
});
let ser = serde_json::to_string(&event).unwrap();
let exp = r#"{"event":"operationCallDone","operationId":"123","output":"0x1"}"#;
assert_eq!(ser, exp);
let event_dec: FollowEvent<String> = serde_json::from_str(exp).unwrap();
assert_eq!(event_dec, event);
}
#[test]
fn follow_op_storage_items_event() {
let event: FollowEvent<String> =
FollowEvent::OperationStorageItems(OperationStorageItems {
operation_id: "123".into(),
items: vec![StorageResult {
key: "0x1".into(),
result: StorageResultType::Value("0x123".to_string()),
}],
});
let ser = serde_json::to_string(&event).unwrap();
let exp = r#"{"event":"operationStorageItems","operationId":"123","items":[{"key":"0x1","value":"0x123"}]}"#;
assert_eq!(ser, exp);
let event_dec: FollowEvent<String> = serde_json::from_str(exp).unwrap();
assert_eq!(event_dec, event);
}
#[test]
fn follow_op_wait_event() {
let event: FollowEvent<String> =
FollowEvent::OperationWaitingForContinue(OperationId { operation_id: "123".into() });
let ser = serde_json::to_string(&event).unwrap();
let exp = r#"{"event":"operationWaitingForContinue","operationId":"123"}"#;
assert_eq!(ser, exp);
let event_dec: FollowEvent<String> = serde_json::from_str(exp).unwrap();
assert_eq!(event_dec, event);
}
#[test]
fn follow_op_storage_done_event() {
let event: FollowEvent<String> =
FollowEvent::OperationStorageDone(OperationId { operation_id: "123".into() });
let ser = serde_json::to_string(&event).unwrap();
let exp = r#"{"event":"operationStorageDone","operationId":"123"}"#;
assert_eq!(ser, exp);
let event_dec: FollowEvent<String> = serde_json::from_str(exp).unwrap();
assert_eq!(event_dec, event);
}
#[test]
fn follow_op_inaccessible_event() {
let event: FollowEvent<String> =
FollowEvent::OperationInaccessible(OperationId { operation_id: "123".into() });
let ser = serde_json::to_string(&event).unwrap();
let exp = r#"{"event":"operationInaccessible","operationId":"123"}"#;
assert_eq!(ser, exp);
let event_dec: FollowEvent<String> = serde_json::from_str(exp).unwrap();
assert_eq!(event_dec, event);
}
#[test]
fn follow_op_error_event() {
let event: FollowEvent<String> = FollowEvent::OperationError(OperationError {
operation_id: "123".into(),
error: "reason".into(),
});
let ser = serde_json::to_string(&event).unwrap();
let exp = r#"{"event":"operationError","operationId":"123","error":"reason"}"#;
assert_eq!(ser, exp);
let event_dec: FollowEvent<String> = serde_json::from_str(exp).unwrap();
assert_eq!(event_dec, event);
}
#[test]
fn follow_stop_event() {
let event: FollowEvent<String> = FollowEvent::Stop;
@@ -489,6 +675,45 @@ mod tests {
assert_eq!(event_dec, event);
}
#[test]
fn method_response() {
// Response of `call` and `body`
let event = MethodResponse::Started(MethodResponseStarted {
operation_id: "123".into(),
discarded_items: None,
});
let ser = serde_json::to_string(&event).unwrap();
let exp = r#"{"result":"started","operationId":"123"}"#;
assert_eq!(ser, exp);
let event_dec: MethodResponse = serde_json::from_str(exp).unwrap();
assert_eq!(event_dec, event);
// Response of `storage`
let event = MethodResponse::Started(MethodResponseStarted {
operation_id: "123".into(),
discarded_items: Some(1),
});
let ser = serde_json::to_string(&event).unwrap();
let exp = r#"{"result":"started","operationId":"123","discardedItems":1}"#;
assert_eq!(ser, exp);
let event_dec: MethodResponse = serde_json::from_str(exp).unwrap();
assert_eq!(event_dec, event);
// Limit reached.
let event = MethodResponse::LimitReached;
let ser = serde_json::to_string(&event).unwrap();
let exp = r#"{"result":"limitReached"}"#;
assert_eq!(ser, exp);
let event_dec: MethodResponse = serde_json::from_str(exp).unwrap();
assert_eq!(event_dec, event);
}
#[test]
fn chain_head_done_event() {
let event: ChainHeadEvent<String> =
@@ -539,22 +764,6 @@ mod tests {
assert_eq!(event_dec, event);
}
#[test]
fn chain_head_network_config() {
let conf = NetworkConfig {
total_attempts: 1,
max_parallel: NonZeroUsize::new(2).expect("Non zero number; qed"),
timeout_ms: 3,
};
let ser = serde_json::to_string(&conf).unwrap();
let exp = r#"{"totalAttempts":1,"maxParallel":2,"timeoutMs":3}"#;
assert_eq!(ser, exp);
let conf_dec: NetworkConfig = serde_json::from_str(exp).unwrap();
assert_eq!(conf_dec, conf);
}
#[test]
fn chain_head_storage_query() {
// Item with Value.
@@ -581,7 +790,7 @@ mod tests {
let item = StorageQuery { key: "0x1", query_type: StorageQueryType::DescendantsValues };
// Encode
let ser = serde_json::to_string(&item).unwrap();
let exp = r#"{"key":"0x1","type":"descendants-values"}"#;
let exp = r#"{"key":"0x1","type":"descendantsValues"}"#;
assert_eq!(ser, exp);
// Decode
let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
@@ -591,7 +800,7 @@ mod tests {
let item = StorageQuery { key: "0x1", query_type: StorageQueryType::DescendantsHashes };
// Encode
let ser = serde_json::to_string(&item).unwrap();
let exp = r#"{"key":"0x1","type":"descendants-hashes"}"#;
let exp = r#"{"key":"0x1","type":"descendantsHashes"}"#;
assert_eq!(ser, exp);
// Decode
let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
@@ -602,7 +811,7 @@ mod tests {
StorageQuery { key: "0x1", query_type: StorageQueryType::ClosestDescendantMerkleValue };
// Encode
let ser = serde_json::to_string(&item).unwrap();
let exp = r#"{"key":"0x1","type":"closest-descendant-merkle-value"}"#;
let exp = r#"{"key":"0x1","type":"closestDescendantMerkleValue"}"#;
assert_eq!(ser, exp);
// Decode
let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
@@ -612,36 +821,38 @@ mod tests {
#[test]
fn chain_head_storage_result() {
// Item with Value.
let item = StorageResult { key: "0x1".into(), result: StorageResultType::Value("res") };
let item =
StorageResult { key: "0x1".into(), result: StorageResultType::Value("res".into()) };
// Encode
let ser = serde_json::to_string(&item).unwrap();
let exp = r#"{"key":"0x1","value":"res"}"#;
assert_eq!(ser, exp);
// Decode
let dec: StorageResult<&str> = serde_json::from_str(exp).unwrap();
let dec: StorageResult = serde_json::from_str(exp).unwrap();
assert_eq!(dec, item);
// Item with Hash.
let item = StorageResult { key: "0x1".into(), result: StorageResultType::Hash("res") };
let item =
StorageResult { key: "0x1".into(), result: StorageResultType::Hash("res".into()) };
// Encode
let ser = serde_json::to_string(&item).unwrap();
let exp = r#"{"key":"0x1","hash":"res"}"#;
assert_eq!(ser, exp);
// Decode
let dec: StorageResult<&str> = serde_json::from_str(exp).unwrap();
let dec: StorageResult = serde_json::from_str(exp).unwrap();
assert_eq!(dec, item);
// Item with DescendantsValues.
let item = StorageResult {
key: "0x1".into(),
result: StorageResultType::ClosestDescendantMerkleValue("res"),
result: StorageResultType::ClosestDescendantMerkleValue("res".into()),
};
// Encode
let ser = serde_json::to_string(&item).unwrap();
let exp = r#"{"key":"0x1","closest-descendant-merkle-value":"res"}"#;
let exp = r#"{"key":"0x1","closestDescendantMerkleValue":"res"}"#;
assert_eq!(ser, exp);
// Decode
let dec: StorageResult<&str> = serde_json::from_str(exp).unwrap();
let dec: StorageResult = serde_json::from_str(exp).unwrap();
assert_eq!(dec, item);
}
@@ -650,8 +861,14 @@ mod tests {
// Event with Items.
let event = ChainHeadStorageEvent::Items(ItemsEvent {
items: vec![
StorageResult { key: "0x1".into(), result: StorageResultType::Value("first") },
StorageResult { key: "0x2".into(), result: StorageResultType::Hash("second") },
StorageResult {
key: "0x1".into(),
result: StorageResultType::Value("first".into()),
},
StorageResult {
key: "0x2".into(),
result: StorageResultType::Hash("second".into()),
},
],
});
// Encode
@@ -659,7 +876,7 @@ mod tests {
let exp = r#"{"event":"items","items":[{"key":"0x1","value":"first"},{"key":"0x2","hash":"second"}]}"#;
assert_eq!(ser, exp);
// Decode
let dec: ChainHeadStorageEvent<&str> = serde_json::from_str(exp).unwrap();
let dec: ChainHeadStorageEvent = serde_json::from_str(exp).unwrap();
assert_eq!(dec, event);
// Event with WaitForContinue.
@@ -669,7 +886,7 @@ mod tests {
let exp = r#"{"event":"wait-for-continue"}"#;
assert_eq!(ser, exp);
// Decode
let dec: ChainHeadStorageEvent<&str> = serde_json::from_str(exp).unwrap();
let dec: ChainHeadStorageEvent = serde_json::from_str(exp).unwrap();
assert_eq!(dec, event);
// Event with Done.
@@ -679,7 +896,7 @@ mod tests {
let exp = r#"{"event":"done"}"#;
assert_eq!(ser, exp);
// Decode
let dec: ChainHeadStorageEvent<&str> = serde_json::from_str(exp).unwrap();
let dec: ChainHeadStorageEvent = serde_json::from_str(exp).unwrap();
assert_eq!(dec, event);
// Event with Inaccessible.
@@ -689,7 +906,7 @@ mod tests {
let exp = r#"{"event":"inaccessible"}"#;
assert_eq!(ser, exp);
// Decode
let dec: ChainHeadStorageEvent<&str> = serde_json::from_str(exp).unwrap();
let dec: ChainHeadStorageEvent = serde_json::from_str(exp).unwrap();
assert_eq!(dec, event);
// Event with Inaccessible.
@@ -699,7 +916,7 @@ mod tests {
let exp = r#"{"event":"error","error":"reason"}"#;
assert_eq!(ser, exp);
// Decode
let dec: ChainHeadStorageEvent<&str> = serde_json::from_str(exp).unwrap();
let dec: ChainHeadStorageEvent = serde_json::from_str(exp).unwrap();
assert_eq!(dec, event);
}
}
@@ -40,7 +40,7 @@ pub use api::ChainHeadApiServer;
pub use chain_head::ChainHead;
pub use event::{
BestBlockChanged, ChainHeadEvent, ChainHeadResult, ErrorEvent, Finalized, FollowEvent,
Initialized, NetworkConfig, NewBlock, RuntimeEvent, RuntimeVersionEvent,
Initialized, NewBlock, RuntimeEvent, RuntimeVersionEvent,
};
use sp_core::hexdisplay::{AsBytesRef, HexDisplay};
@@ -532,8 +532,8 @@ async fn get_storage_hash() {
)
.await
.unwrap();
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
assert_eq!(event, ChainHeadStorageEvent::<String>::Disjoint);
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_eq!(event, ChainHeadStorageEvent::Disjoint);
// Valid subscription ID with invalid block hash will error.
let err = api
@@ -563,7 +563,7 @@ async fn get_storage_hash() {
)
.await
.unwrap();
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
// The `Done` event is generated directly since the key does not have any value associated.
assert_matches!(event, ChainHeadStorageEvent::Done);
@@ -597,9 +597,9 @@ async fn get_storage_hash() {
)
.await
.unwrap();
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::<String>::Items(res) if res.items.len() == 1 && res.items[0].key == key && res.items[0].result == StorageResultType::Hash(expected_hash));
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::Items(res) if res.items.len() == 1 && res.items[0].key == key && res.items[0].result == StorageResultType::Hash(expected_hash));
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::Done);
// Child value set in `setup_api`.
@@ -618,9 +618,9 @@ async fn get_storage_hash() {
)
.await
.unwrap();
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::<String>::Items(res) if res.items.len() == 1 && res.items[0].key == key && res.items[0].result == StorageResultType::Hash(expected_hash));
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::Items(res) if res.items.len() == 1 && res.items[0].key == key && res.items[0].result == StorageResultType::Hash(expected_hash));
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::Done);
}
@@ -669,13 +669,13 @@ async fn get_storage_multi_query_iter() {
)
.await
.unwrap();
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::<String>::Items(res) if res.items.len() == 2 &&
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::Items(res) if res.items.len() == 2 &&
res.items[0].key == key &&
res.items[1].key == key &&
res.items[0].result == StorageResultType::Hash(expected_hash) &&
res.items[1].result == StorageResultType::Value(expected_value));
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::Done);
// Child value set in `setup_api`.
@@ -704,13 +704,13 @@ async fn get_storage_multi_query_iter() {
)
.await
.unwrap();
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::<String>::Items(res) if res.items.len() == 2 &&
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::Items(res) if res.items.len() == 2 &&
res.items[0].key == key &&
res.items[1].key == key &&
res.items[0].result == StorageResultType::Hash(expected_hash) &&
res.items[1].result == StorageResultType::Value(expected_value));
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::Done);
}
@@ -733,8 +733,8 @@ async fn get_storage_value() {
)
.await
.unwrap();
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
assert_eq!(event, ChainHeadStorageEvent::<String>::Disjoint);
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_eq!(event, ChainHeadStorageEvent::Disjoint);
// Valid subscription ID with invalid block hash will error.
let err = api
@@ -764,7 +764,7 @@ async fn get_storage_value() {
)
.await
.unwrap();
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
// The `Done` event is generated directly since the key does not have any value associated.
assert_matches!(event, ChainHeadStorageEvent::Done);
@@ -798,9 +798,9 @@ async fn get_storage_value() {
)
.await
.unwrap();
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::<String>::Items(res) if res.items.len() == 1 && res.items[0].key == key && res.items[0].result == StorageResultType::Value(expected_value));
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::Items(res) if res.items.len() == 1 && res.items[0].key == key && res.items[0].result == StorageResultType::Value(expected_value));
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::Done);
// Child value set in `setup_api`.
@@ -819,9 +819,9 @@ async fn get_storage_value() {
)
.await
.unwrap();
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::<String>::Items(res) if res.items.len() == 1 && res.items[0].key == key && res.items[0].result == StorageResultType::Value(expected_value));
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::Items(res) if res.items.len() == 1 && res.items[0].key == key && res.items[0].result == StorageResultType::Value(expected_value));
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::Done);
}
@@ -846,7 +846,7 @@ async fn get_storage_wrong_key() {
)
.await
.unwrap();
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::Done);
// Key is prefixed by DEFAULT_CHILD_STORAGE_KEY_PREFIX.
@@ -864,7 +864,7 @@ async fn get_storage_wrong_key() {
)
.await
.unwrap();
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::Done);
// Child key is prefixed by CHILD_STORAGE_KEY_PREFIX.
@@ -883,7 +883,7 @@ async fn get_storage_wrong_key() {
)
.await
.unwrap();
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::Done);
// Child key is prefixed by DEFAULT_CHILD_STORAGE_KEY_PREFIX.
@@ -902,7 +902,7 @@ async fn get_storage_wrong_key() {
)
.await
.unwrap();
let event: ChainHeadStorageEvent<String> = get_next_event(&mut sub).await;
let event: ChainHeadStorageEvent = get_next_event(&mut sub).await;
assert_matches!(event, ChainHeadStorageEvent::Done);
}