mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-08-02 21:35:41 +00:00
chainHead_storage: Backport queries for value types (#14551)
* chainHead/events: Add storage params and events Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * chainHead/tests: Check storage events serialization / deserialization Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * chainHead/error: Add error for invalid WaitForContinue storage call Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * chainHead/storage: Use new items params Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * chainHead/tests: Adjust storage tests to the new API Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * chainHead/events: Generalize StorageQuery by provided key Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * chain_head: Add dedicated ChainHeadStorage client for queries Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * chainHead/storage: Implement queries for hashes of values Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * chainHead/tests: Check storage queries for hashes of values Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * chainHead: Improve API documentation wrt multiple entries Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * chainHead/event: Rename StorageQueue ty to queue_ty Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * chianHead: Add helper to encode chainHead results as hex str Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update client/rpc-spec-v2/src/chain_head/error.rs Co-authored-by: Sebastian Kunert <skunert49@gmail.com> * chainHead: Change the `queryResult` to a plain `Result` Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * chainHead: Stop producing events after the first error Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * chainHead: Change child_key to child_trie API param Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> --------- Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> Co-authored-by: Sebastian Kunert <skunert49@gmail.com>
This commit is contained in:
@@ -241,6 +241,85 @@ pub enum ChainHeadEvent<T> {
|
||||
Disjoint,
|
||||
}
|
||||
|
||||
/// The storage item received as paramter.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct StorageQuery<Key> {
|
||||
/// The provided key.
|
||||
pub key: Key,
|
||||
/// The type of the storage query.
|
||||
#[serde(rename = "type")]
|
||||
pub queue_type: StorageQueryType,
|
||||
}
|
||||
|
||||
/// The type of the storage query.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum StorageQueryType {
|
||||
/// Fetch the value of the provided key.
|
||||
Value,
|
||||
/// Fetch the hash of the value of the provided key.
|
||||
Hash,
|
||||
/// Fetch the closest descendant merkle value.
|
||||
ClosestDescendantMerkleValue,
|
||||
/// Fetch the values of all descendants of they provided key.
|
||||
DescendantsValues,
|
||||
/// Fetch the hashes of the values of all descendants of they provided key.
|
||||
DescendantsHashes,
|
||||
}
|
||||
|
||||
/// The storage result.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct StorageResult<T> {
|
||||
/// The hex-encoded key of the result.
|
||||
pub key: String,
|
||||
/// The result of the query.
|
||||
#[serde(flatten)]
|
||||
pub result: StorageResultType<T>,
|
||||
}
|
||||
|
||||
/// The type of the storage query.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum StorageResultType<T> {
|
||||
/// Fetch the value of the provided key.
|
||||
Value(T),
|
||||
/// Fetch the hash of the value of the provided key.
|
||||
Hash(T),
|
||||
/// Fetch the closest descendant merkle value.
|
||||
ClosestDescendantMerkleValue(T),
|
||||
}
|
||||
|
||||
/// The event generated by storage method.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
#[serde(tag = "event")]
|
||||
pub enum ChainHeadStorageEvent<T> {
|
||||
/// The request produced multiple result items.
|
||||
Items(ItemsEvent<T>),
|
||||
/// The request produced multiple result items.
|
||||
WaitForContinue,
|
||||
/// The request completed successfully and all the results were provided.
|
||||
Done,
|
||||
/// The resources requested are inaccessible.
|
||||
///
|
||||
/// Resubmitting the request later might succeed.
|
||||
Inaccessible,
|
||||
/// An error occurred. This is definitive.
|
||||
Error(ErrorEvent),
|
||||
/// The provided subscription ID is stale or invalid.
|
||||
Disjoint,
|
||||
}
|
||||
|
||||
/// The request produced multiple result items.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ItemsEvent<T> {
|
||||
/// The resulting items.
|
||||
pub items: Vec<StorageResult<T>>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -475,4 +554,152 @@ mod tests {
|
||||
let conf_dec: NetworkConfig = serde_json::from_str(exp).unwrap();
|
||||
assert_eq!(conf_dec, conf);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chain_head_storage_query() {
|
||||
// Item with Value.
|
||||
let item = StorageQuery { key: "0x1", queue_type: StorageQueryType::Value };
|
||||
// Encode
|
||||
let ser = serde_json::to_string(&item).unwrap();
|
||||
let exp = r#"{"key":"0x1","type":"value"}"#;
|
||||
assert_eq!(ser, exp);
|
||||
// Decode
|
||||
let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
|
||||
assert_eq!(dec, item);
|
||||
|
||||
// Item with Hash.
|
||||
let item = StorageQuery { key: "0x1", queue_type: StorageQueryType::Hash };
|
||||
// Encode
|
||||
let ser = serde_json::to_string(&item).unwrap();
|
||||
let exp = r#"{"key":"0x1","type":"hash"}"#;
|
||||
assert_eq!(ser, exp);
|
||||
// Decode
|
||||
let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
|
||||
assert_eq!(dec, item);
|
||||
|
||||
// Item with DescendantsValues.
|
||||
let item = StorageQuery { key: "0x1", queue_type: StorageQueryType::DescendantsValues };
|
||||
// Encode
|
||||
let ser = serde_json::to_string(&item).unwrap();
|
||||
let exp = r#"{"key":"0x1","type":"descendants-values"}"#;
|
||||
assert_eq!(ser, exp);
|
||||
// Decode
|
||||
let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
|
||||
assert_eq!(dec, item);
|
||||
|
||||
// Item with DescendantsHashes.
|
||||
let item = StorageQuery { key: "0x1", queue_type: StorageQueryType::DescendantsHashes };
|
||||
// Encode
|
||||
let ser = serde_json::to_string(&item).unwrap();
|
||||
let exp = r#"{"key":"0x1","type":"descendants-hashes"}"#;
|
||||
assert_eq!(ser, exp);
|
||||
// Decode
|
||||
let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
|
||||
assert_eq!(dec, item);
|
||||
|
||||
// Item with Merkle.
|
||||
let item =
|
||||
StorageQuery { key: "0x1", queue_type: StorageQueryType::ClosestDescendantMerkleValue };
|
||||
// Encode
|
||||
let ser = serde_json::to_string(&item).unwrap();
|
||||
let exp = r#"{"key":"0x1","type":"closest-descendant-merkle-value"}"#;
|
||||
assert_eq!(ser, exp);
|
||||
// Decode
|
||||
let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap();
|
||||
assert_eq!(dec, item);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chain_head_storage_result() {
|
||||
// Item with Value.
|
||||
let item = StorageResult { key: "0x1".into(), result: StorageResultType::Value("res") };
|
||||
// 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();
|
||||
assert_eq!(dec, item);
|
||||
|
||||
// Item with Hash.
|
||||
let item = StorageResult { key: "0x1".into(), result: StorageResultType::Hash("res") };
|
||||
// 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();
|
||||
assert_eq!(dec, item);
|
||||
|
||||
// Item with DescendantsValues.
|
||||
let item = StorageResult {
|
||||
key: "0x1".into(),
|
||||
result: StorageResultType::ClosestDescendantMerkleValue("res"),
|
||||
};
|
||||
// Encode
|
||||
let ser = serde_json::to_string(&item).unwrap();
|
||||
let exp = r#"{"key":"0x1","closest-descendant-merkle-value":"res"}"#;
|
||||
assert_eq!(ser, exp);
|
||||
// Decode
|
||||
let dec: StorageResult<&str> = serde_json::from_str(exp).unwrap();
|
||||
assert_eq!(dec, item);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chain_head_storage_event() {
|
||||
// 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") },
|
||||
],
|
||||
});
|
||||
// Encode
|
||||
let ser = serde_json::to_string(&event).unwrap();
|
||||
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();
|
||||
assert_eq!(dec, event);
|
||||
|
||||
// Event with WaitForContinue.
|
||||
let event = ChainHeadStorageEvent::WaitForContinue;
|
||||
// Encode
|
||||
let ser = serde_json::to_string(&event).unwrap();
|
||||
let exp = r#"{"event":"wait-for-continue"}"#;
|
||||
assert_eq!(ser, exp);
|
||||
// Decode
|
||||
let dec: ChainHeadStorageEvent<&str> = serde_json::from_str(exp).unwrap();
|
||||
assert_eq!(dec, event);
|
||||
|
||||
// Event with Done.
|
||||
let event = ChainHeadStorageEvent::Done;
|
||||
// Encode
|
||||
let ser = serde_json::to_string(&event).unwrap();
|
||||
let exp = r#"{"event":"done"}"#;
|
||||
assert_eq!(ser, exp);
|
||||
// Decode
|
||||
let dec: ChainHeadStorageEvent<&str> = serde_json::from_str(exp).unwrap();
|
||||
assert_eq!(dec, event);
|
||||
|
||||
// Event with Inaccessible.
|
||||
let event = ChainHeadStorageEvent::Inaccessible;
|
||||
// Encode
|
||||
let ser = serde_json::to_string(&event).unwrap();
|
||||
let exp = r#"{"event":"inaccessible"}"#;
|
||||
assert_eq!(ser, exp);
|
||||
// Decode
|
||||
let dec: ChainHeadStorageEvent<&str> = serde_json::from_str(exp).unwrap();
|
||||
assert_eq!(dec, event);
|
||||
|
||||
// Event with Inaccessible.
|
||||
let event = ChainHeadStorageEvent::Error(ErrorEvent { error: "reason".into() });
|
||||
// Encode
|
||||
let ser = serde_json::to_string(&event).unwrap();
|
||||
let exp = r#"{"event":"error","error":"reason"}"#;
|
||||
assert_eq!(ser, exp);
|
||||
// Decode
|
||||
let dec: ChainHeadStorageEvent<&str> = serde_json::from_str(exp).unwrap();
|
||||
assert_eq!(dec, event);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user