-
Notifications
You must be signed in to change notification settings - Fork 17
/
rpc.rs
71 lines (60 loc) · 2.64 KB
/
rpc.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//! Strongly typed helper functions for communicating with the Node's
//! RPC endpoint.
use crate::strip_0x_prefix;
use anyhow::anyhow;
use jsonrpsee::{core::client::ClientT, http_client::HttpClient, rpc_params};
use parity_scale_codec::{Decode, Encode};
use sp_core::H256;
use tuxedo_core::{
types::{OpaqueBlock, Output, OutputRef},
TuxedoMetadata, Verifier,
};
/// Get the node's metadata
pub async fn node_get_metadata(client: &HttpClient) -> anyhow::Result<TuxedoMetadata> {
// Don't provide a block height to use the best height.
let params = rpc_params![Option::<u32>::None];
let rpc_response: Option<String> = client.request("state_getMetadata", params).await?;
let metadata = metadata_from_string(&rpc_response.expect("metadata should be available."))?;
Ok(metadata)
}
/// Parse a string into a Tuxedo Metadata
pub(crate) fn metadata_from_string(s: &str) -> anyhow::Result<TuxedoMetadata> {
let s = strip_0x_prefix(s);
let bytes = hex::decode(s)?;
Ok(TuxedoMetadata::decode(&mut &bytes[..])?)
}
/// Typed helper to get the Node's block hash at a particular height
pub async fn node_get_block_hash(height: u32, client: &HttpClient) -> anyhow::Result<Option<H256>> {
let params = rpc_params![Some(height)];
let rpc_response: Option<String> = client.request("chain_getBlockHash", params).await?;
let maybe_hash = rpc_response.map(|s| crate::h256_from_string(&s).unwrap());
Ok(maybe_hash)
}
/// Get the node's full opaque block at a particular hash
pub async fn node_get_block(
hash: H256,
client: &HttpClient,
) -> anyhow::Result<Option<OpaqueBlock>> {
let s = hex::encode(hash.0);
let params = rpc_params![s];
let maybe_rpc_response: Option<serde_json::Value> =
client.request("chain_getBlock", params).await?;
let rpc_response = maybe_rpc_response.unwrap();
let json_opaque_block = rpc_response.get("block").cloned().unwrap();
let opaque_block: OpaqueBlock = serde_json::from_value(json_opaque_block).unwrap();
Ok(Some(opaque_block))
}
/// Fetch an output from chain storage given an OutputRef
pub async fn fetch_storage<V: Verifier>(
output_ref: &OutputRef,
client: &HttpClient,
) -> anyhow::Result<Output<V>> {
let ref_hex = hex::encode(output_ref.encode());
let params = rpc_params![ref_hex];
let rpc_response: Result<Option<String>, _> = client.request("state_getStorage", params).await;
let response_hex = rpc_response?.ok_or(anyhow!("Data cannot be retrieved from storage"))?;
let response_hex = strip_0x_prefix(&response_hex);
let response_bytes = hex::decode(response_hex)?;
let utxo = Output::decode(&mut &response_bytes[..])?;
Ok(utxo)
}