Skip to content

Commit

Permalink
refactor: Update method signatures and logic for better type handling
Browse files Browse the repository at this point in the history
  • Loading branch information
S0c5 committed Aug 19, 2024
1 parent c87bf6b commit e75fc24
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 84 deletions.
12 changes: 1 addition & 11 deletions sube/examples/query_at_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,7 @@ use sube::{sube, ExtrinsicBody, Response, Result, SubeBuilder};
async fn main() -> Result<()> {
env_logger::init();

let result = sube!("ws://127.0.0.1:12281/system/account/0x12840f0626ac847d41089c4e05cf0719c5698af1e3bb87b66542de70b2de4b2b?at=0x8c0eb4368ffcc1fca8226b1653a4b3ba50d22fe494dab1dac3df206d438c7e70").await?;

if let Response::Value(value) = result {
let data = serde_json::to_value(&value).expect("to be serializable");
println!(
"Account info: {}",
serde_json::to_string_pretty(&data).expect("it must return an str")
);
}

let result = sube!("ws://127.0.0.1:12281/system/account/0x12840f0626ac847d41089c4e05cf0719c5698af1e3bb87b66542de70b2de4b2b?at=2062650").await?;
let result = sube!("ws://127.0.0.1:12281/system/account/0x12840f0626ac847d41089c4e05cf0719c5698af1e3bb87b66542de70b2de4b2b?at=2067321").await?;

if let Response::Value(value) = result {
let data = serde_json::to_value(&value).expect("to be serializable");
Expand Down
23 changes: 13 additions & 10 deletions sube/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
meta::BlockInfo, Backend, Error, ExtrinsicBody, Metadata, Response, Result as SubeResult,
Signer, StorageKey,
};
use crate::{prelude::*, Offline};
use crate::{prelude::*, Offline, RawKey, RawValue};

use core::future::{Future, IntoFuture};
use url::Url;
Expand Down Expand Up @@ -66,7 +66,10 @@ impl<'a> SubeBuilder<'a, (), ()> {
let block = url
.query_pairs()
.find(|(k, _)| k == "at")
.map(|(_, v)| v.to_string());
.map(|(_, v)| {
log::info!("hello world{:?}", v);
v.parse::<u32>().expect("at to be a number")
});

let path = url.path();

Expand Down Expand Up @@ -278,10 +281,10 @@ enum AnyBackend {
impl Backend for &AnyBackend {
async fn get_storage_items(
&self,
keys: Vec<String>,
block: Option<String>,
) -> crate::Result<impl Iterator<Item = (Vec<u8>, Vec<u8>)>> {
let result: Box<dyn Iterator<Item = (Vec<u8>, Vec<u8>)>> = match self {
keys: Vec<RawKey>,
block: Option<u32>,
) -> crate::Result<impl Iterator<Item = (RawKey, RawValue)>> {
let result: Box<dyn Iterator<Item = (RawKey, RawValue)>> = match self {
#[cfg(any(feature = "http", feature = "http-web"))]
AnyBackend::Http(b) => Box::new(b.get_storage_items(keys, block).await?),
#[cfg(feature = "ws")]
Expand All @@ -292,7 +295,7 @@ impl Backend for &AnyBackend {
Ok(result)
}

async fn get_storage_item(&self, key: String, block: Option<String>) -> crate::Result<Vec<u8>> {
async fn get_storage_item(&self, key: RawKey, block: Option<u32>) -> crate::Result<Vec<u8>> {
match self {
#[cfg(any(feature = "http", feature = "http-web"))]
AnyBackend::Http(b) => b.get_storage_item(key, block).await,
Expand All @@ -304,10 +307,10 @@ impl Backend for &AnyBackend {

async fn get_keys_paged(
&self,
from: &StorageKey,
from: RawKey,
size: u16,
to: Option<&StorageKey>,
) -> crate::Result<Vec<String>> {
to: Option<RawKey>,
) -> crate::Result<Vec<RawKey>> {
match self {
#[cfg(any(feature = "http", feature = "http-web"))]
AnyBackend::Http(b) => b.get_keys_paged(from, size, to).await,
Expand Down
2 changes: 1 addition & 1 deletion sube/src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl Rpc for Backend {
})
.send()
.await
.map_err(|err| rpc::Error::Transport(Box::new(err)))?;
.map_err(|err| rpc::error::Error::Transport(Box::new(err)))?;

let status = res.status();
let res = if status.is_success() {
Expand Down
66 changes: 20 additions & 46 deletions sube/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ async fn query<'m>(
chain: &impl Backend,
meta: &'m Metadata,
path: &str,
block: Option<String>,
block: Option<u32>,
) -> Result<Response<'m>> {
log::info!("path {}", path);
let (pallet, item_or_call, mut keys) = parse_uri(path).ok_or(Error::BadInput)?;
Expand All @@ -100,26 +100,14 @@ async fn query<'m>(
)));
}

let block = match block {
Some(block) if block.starts_with("0x") => Some(block),
Some(block) => {
let block_number = block
.parse::<u32>()
.expect("blockhash to be a number or either a hash");
let info = chain.block_info(Some(block_number)).await?;
Some(format!("0x{}", hex::encode(info.hash)))
}
_ => None,
};

if let Ok(key_res) = StorageKey::build_with_registry(&meta.types, pallet, &item_or_call, &keys)
{
if !key_res.is_partial() {
let res = chain.get_storage_item(key_res.to_string(), block).await?;
let res = chain.get_storage_item(key_res.key(), block).await?;
return Ok(Response::Value(Value::new(res, key_res.ty, &meta.types)));
}

let res = chain.get_keys_paged(&key_res, 1000, None).await?;
let res = chain.get_keys_paged(key_res.key(), 1000, None).await?;
let result = chain.get_storage_items(res, block).await?;

let value = result
Expand Down Expand Up @@ -372,31 +360,16 @@ fn parse_uri(uri: &str) -> Option<(String, String, Vec<String>)> {
Some((pallet, item, map_keys))
}

// struct PalletCall {
// pallet_idx: u8,
// ty: u32,
// }

// impl PalletCall {
// fn new(pallet: &PalletMeta, reg: &PortableRegistry, _call: &str) -> Result<Self> {
// let calls = &pallet
// .calls
// .as_ref()
// .and_then(|c| reg.resolve(c.ty.id))
// .ok_or_else(|| Error::CallNotFound)?
// .type_def;
// log::debug!("{:?}", calls);
// let pallet_idx = pallet.index;
// Ok(PalletCall { pallet_idx, ty: 0 })
// }
// }

#[derive(Deserialize, Serialize, Debug)]
pub struct StorageChangeSet {
block: String,
changes: Vec<[String; 2]>,
}

pub type RawKey = Vec<u8>;
pub type RawValue = Vec<u8>;

/// Generic definition of a blockchain backend
///
/// ```rust,ignore
Expand All @@ -413,11 +386,11 @@ pub struct StorageChangeSet {
pub trait Backend {
async fn get_storage_items(
&self,
keys: Vec<String>,
block: Option<String>,
) -> crate::Result<impl Iterator<Item = (Vec<u8>, Vec<u8>)>>;
keys: Vec<RawKey>,
block: Option<u32>,
) -> crate::Result<impl Iterator<Item = (RawKey, RawValue)>>;

async fn get_storage_item(&self, key: String, block: Option<String>) -> crate::Result<Vec<u8>> {
async fn get_storage_item(&self, key: RawKey, block: Option<u32>) -> crate::Result<RawValue> {
let res = self.get_storage_items(vec![key], block).await?;
res.into_iter()
.next()
Expand All @@ -427,10 +400,10 @@ pub trait Backend {

async fn get_keys_paged(
&self,
from: &StorageKey,
from: RawKey,
size: u16,
to: Option<&StorageKey>,
) -> crate::Result<Vec<String>>;
to: Option<RawKey>,
) -> crate::Result<Vec<RawValue>>;

/// Send a signed extrinsic to the blockchain
async fn submit(&self, ext: impl AsRef<[u8]>) -> Result<()>;
Expand All @@ -446,18 +419,18 @@ pub struct Offline(pub Metadata);
impl Backend for Offline {
async fn get_storage_items(
&self,
_keys: Vec<String>,
_block: Option<String>,
_keys: Vec<RawKey>,
_block: Option<u32>,
) -> crate::Result<impl Iterator<Item = (Vec<u8>, Vec<u8>)>> {
Err::<Empty<(Vec<u8>, Vec<u8>)>, _>(Error::ChainUnavailable)
Err::<Empty<(RawKey, RawValue)>, _>(Error::ChainUnavailable)
}

async fn get_keys_paged(
&self,
_from: &StorageKey,
_from: RawKey,
_size: u16,
_to: Option<&StorageKey>,
) -> crate::Result<Vec<String>> {
_to: Option<RawKey>,
) -> crate::Result<Vec<RawKey>> {
Err(Error::ChainUnavailable)
}

Expand Down Expand Up @@ -499,6 +472,7 @@ pub enum Error {
CantDecodeReponseForMeta,
CantDecodeRawQueryResponse,
CantFindMethodInPallet,
BadBlockNumber
}

impl fmt::Display for Error {
Expand Down
50 changes: 34 additions & 16 deletions sube/src/rpc.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use core::convert::TryInto;
use jsonrpc::serde_json::value::RawValue;
pub use jsonrpc::{error, Error, Request, Response};
pub use jsonrpc::{error, Request, Response};
use serde::Deserialize;

use crate::meta::{self, Metadata};
use crate::{prelude::*, StorageChangeSet};
use crate::{Backend, StorageKey};
use crate::Backend;
use crate::Error;
use crate::{prelude::*, RawKey, StorageChangeSet};
use meta::from_bytes;

pub type RpcResult<T> = Result<T, error::Error>;
Expand All @@ -31,14 +32,26 @@ pub struct RpcClient<R>(pub R);
impl<R: Rpc> Backend for RpcClient<R> {
async fn get_storage_items(
&self,
keys: Vec<String>,
block: Option<String>,
keys: Vec<RawKey>,
block: Option<u32>,
) -> crate::Result<impl Iterator<Item = (Vec<u8>, Vec<u8>)>> {
let keys = serde_json::to_string(&keys).expect("it to be a valid json");
let keys = serde_json::to_string(
&keys
.iter()
.map(|v| format!("0x{}", hex::encode(v)))
.collect::<Vec<String>>(),
)
.expect("it to be a valid json");

log::info!("query_storage_at encoded: {}", keys);
let params: Vec<String> = if let Some(block_hash) = block {
vec![keys, format!("\"{}\"", block_hash)]

let params: Vec<String> = if let Some(block_number) = block {
let info = self
.block_info(Some(block_number))
.await
.map_err(|_| Error::BadBlockNumber)?;

vec![keys, format!("\"0x{}\"", hex::encode(&info.hash))]
} else {
vec![keys]
};
Expand Down Expand Up @@ -79,27 +92,32 @@ impl<R: Rpc> Backend for RpcClient<R> {

async fn get_keys_paged(
&self,
from: &StorageKey,
from: RawKey,
size: u16,
to: Option<&StorageKey>,
) -> crate::Result<Vec<String>> {
let r: Vec<String> = self
to: Option<RawKey>,
) -> crate::Result<Vec<RawKey>> {
let result: Vec<String> = self
.0
.rpc(
"state_getKeysPaged",
&[
&format!("\"{}\"", &from),
&format!("\"0x{}\"", hex::encode(&from)),
&size.to_string(),
&to.or(Some(from)).map(|f| format!("\"{}\"", &f)).unwrap(),
&to.or(Some(from))
.map(|f| format!("\"0x{}\"", hex::encode(f)))
.unwrap(),
],
)
.await
.map_err(|err| {
log::error!("error paged {:?}", err);
crate::Error::StorageKeyNotFound
})?;
log::info!("rpc call {:?}", r);
Ok(r)
log::info!("rpc call {:?}", result);
Ok(result
.into_iter()
.map(|k| hex::decode(&k[2..]).expect("to be an hex"))
.collect())
}

async fn submit(&self, ext: impl AsRef<[u8]>) -> crate::Result<()> {
Expand Down

0 comments on commit e75fc24

Please sign in to comment.