Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/complex structures in url #65

Merged
merged 7 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions scales/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,15 @@ fn sequence_size(data: &[u8]) -> (usize, usize) {
(
match len {
1 => (data[0] >> 2).into(),
2 => u16::from_le_bytes([(data[0] >> 2), data[1]]).into(),
4 => u32::from_le_bytes([(data[0] >> 2), data[1], data[2], data[3]])
.try_into()
.unwrap(),

2 => u16::from(data[0] >> 2 | data[1] << 6).into(),
4 => u32::from(
(data[0] as u32) >> 2
| (data[1] as u32) << 6
| (data[2] as u32) << 14
| (data[3] as u32) << 22,
)
.try_into()
.unwrap(),
_ => todo!(),
},
len,
Expand Down Expand Up @@ -330,6 +334,18 @@ mod tests {
};
use serde_json::to_value;

#[test]
fn test_compact_two_bytes() {
let data: [u8; 2] = [0x99, 0x01];
assert_eq!(sequence_size(&data), (102, 2));

let data: [u8; 2] = [0x15, 0x01];
assert_eq!(sequence_size(&data), (69, 2));

let data: [u8; 4] = [0xfe, 0xff, 0x03, 0x00];
assert_eq!(sequence_size(&data), (65535, 4));
}

fn register<T>(_ty: &T) -> (u32, PortableRegistry)
where
T: TypeInfo + 'static,
Expand Down
26 changes: 26 additions & 0 deletions sube/examples/query_membership.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use core::future::{Future, IntoFuture};
use serde::{Deserialize, Serialize};
use serde_json::{from_value, Value};
use sube::{sube, Response};

#[async_std::main]
async fn main() -> sube::Result<()> {
env_logger::init();

let query = format!(
"ws://127.0.0.1:12281/communityMemberships/account/{}/{}",
"0x12840f0626ac847d41089c4e05cf0719c5698af1e3bb87b66542de70b2de4b2b",
1
);

let r = sube!(&query).await?;

if let Response::ValueSet(ref v) = r {
let json_value = serde_json::to_value(v).expect("to be serializable");
println!("json: {:?}", json_value);
let x = serde_json::to_string_pretty(&json_value).expect("it must return an str");
println!("Account info: {:?}", x);
}

Ok(())
}
26 changes: 26 additions & 0 deletions sube/examples/query_preimage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use core::future::{Future, IntoFuture};
use serde::{Deserialize, Serialize};
use serde_json::{from_value, Value};
use sube::{sube, Response};

#[async_std::main]
async fn main() -> sube::Result<()> {
env_logger::init();

let query = format!(
"ws://127.0.0.1:12281/preimage/preimageFor/{}/{}",
"0x6b172c3695dca229e71c0bca790f5991b68f8eee96334e842312a0a7d4a46c6c",
30
);

let r = sube!(&query).await?;

if let Response::Value(ref v) = r {
let json_value = serde_json::to_value(v).expect("to be serializable");
println!("json: {:?}", json_value);
let x = serde_json::to_string_pretty(&json_value).expect("it must return an str");
println!("Account info: {:?}", x);
}

Ok(())
}
22 changes: 22 additions & 0 deletions sube/examples/query_referendum_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use env_logger;
use serde_json;
use sube::{sube, ExtrinsicBody, Response, Result, SubeBuilder};

#[async_std::main]
async fn main() -> Result<()> {
env_logger::init();

let query = format!(
"https://kreivo.io/communityReferenda/referendumInfoFor/{}",
24
);

let r = sube!(&query).await?;

if let Response::Value(ref v) = r {
let json_value = serde_json::to_value(v).expect("it must to be an valid Value");
println!("Raw JSON value: {:?}", json_value);
println!("Info: {}", serde_json::to_string_pretty(&json_value).expect("it must return an str"));
}
Ok(())
}
1 change: 1 addition & 0 deletions sube/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ impl<'a> SubeBuilder<'a, (), ()> {
let path = url.path();

log::info!("building the backend for {}", url);

let backend = BACKEND
.get_or_try_init(get_backend_by_url(url.clone()))
.await?;
Expand Down
8 changes: 5 additions & 3 deletions sube/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ pub mod http;
#[cfg(feature = "ws")]
pub mod ws;

mod builder;
pub mod builder;
pub use builder::SubeBuilder;
mod hasher;
mod meta_ext;
mod signer;
Expand All @@ -71,11 +72,11 @@ pub fn sube(url: &str) -> builder::SubeBuilder<(), ()> {
pub type Result<T> = core::result::Result<T, Error>;
async fn query<'m>(chain: &impl Backend, meta: &'m Metadata, path: &str) -> Result<Response<'m>> {
let (pallet, item_or_call, mut keys) = parse_uri(path).ok_or(Error::BadInput)?;

log::info!("pallet {}", pallet);
let pallet = meta
.pallet_by_name(&pallet)
.ok_or_else(|| Error::PalletNotFound(pallet))?;

if item_or_call == "_constants" {
let const_name = keys.pop().ok_or_else(|| Error::MissingConstantName)?;
let const_meta = pallet
Expand All @@ -94,6 +95,7 @@ async fn query<'m>(chain: &impl Backend, meta: &'m Metadata, path: &str) -> Resu
if let Ok(key_res) = StorageKey::build_with_registry(&meta.types, pallet, &item_or_call, &keys)
{
if !key_res.is_partial() {
log::info!("is not partial");
let res = chain.query_storage(&key_res).await?;
return Ok(Response::Value(Value::new(res, key_res.ty, &meta.types)));
}
Expand Down
129 changes: 86 additions & 43 deletions sube/src/meta_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl StorageKey {
.as_ref()
.and_then(|s| s.entries.iter().find(|e| e.name == item))
.ok_or(crate::Error::StorageKeyNotFound)?;

log::info!("map_keys={}", map_keys.into_iter().map(|x| x.as_ref()).collect::<Vec<&str>>().join(", "));
entry.ty.key(registry, &meta.name, &entry.name, map_keys)
}
}
Expand Down Expand Up @@ -175,45 +175,85 @@ pub trait EntryTy {
let key_type_info = portable_reg
.resolve(key_ty_id)
.ok_or(crate::Error::BadInput)?;

log::info!("key_type_info={:?}", key_type_info);
extract_touple_type(key_ty_id, key_type_info)
} else {
vec![]
};

if type_call_ids.len() == hashers.len() {
log::info!("type_call_ids={:?}", type_call_ids);
let storage_key = StorageKey::new(
value_ty_id,
hash(&Hasher::Twox128, pallet_item.0),
hash(&Hasher::Twox128, pallet_item.1),
type_call_ids
.into_iter()
.enumerate()
.map(|(i, type_id)| {
log::info!("type_call_ids.i={} type_call_ids.type_id={}", i, type_id);
let k = map_keys.get(i);
let hasher = hashers.get(i).expect("hasher not found");

if k.is_none() {
return KeyValue::Empty(type_id);
}

let k = k.expect("it must exist").as_ref();

let hasher = hasher.borrow();
let mut out = vec![];

if let Some(k) = k.strip_prefix("0x") {
let value = hex::decode(k).expect("str must be encoded");
let _ = to_bytes_with_info(&mut out, &value, Some((portable_reg, type_id)));
} else {
let _ = to_bytes_with_info(&mut out, &k, Some((portable_reg, type_id)));
}

let hash = hash(hasher, &out);
KeyValue::Value((type_id, hash, out, hasher.clone()))
})
.collect(),
);

Ok(storage_key)
} else if hashers.len() == 1 {
log::info!("hello hashers.len() == 1");

let touple_hex: Vec<u8> = type_call_ids
.into_iter()
.enumerate()
.map(|(i, type_id)| {
let k = map_keys.get(i).expect("to exist in map_keys").as_ref();
let mut out = vec![];
if let Some(k) = k.strip_prefix("0x") {
let value = hex::decode(k).expect("str must be encoded");
let _ = to_bytes_with_info(&mut out, &value, Some((portable_reg, type_id)));
} else {
let _ = to_bytes_with_info(&mut out, &k, Some((portable_reg, type_id)));
}
out
})
.flatten()
.collect();

let hasher = hashers.get(0).expect("hasher not found");
let hasher = hasher.borrow();
let hashed_value = hash(hasher, &touple_hex);

let storage_key = StorageKey::new(
value_ty_id,
hash(&Hasher::Twox128, pallet_item.0),
hash(&Hasher::Twox128, pallet_item.1),
type_call_ids
.into_iter()
.enumerate()
.map(|(i, type_id)| {
let k = map_keys.get(i);
let hasher = hashers.get(i).expect("hasher not found");

if k.is_none() {
return KeyValue::Empty(type_id);
}

let k = k.expect("it must exist").as_ref();

let hasher = hasher.borrow();
let mut out = vec![];

if let Some(k) = k.strip_prefix("0x") {
let value = hex::decode(k).expect("str must be encoded");
let _ = to_bytes_with_info(&mut out, &value, Some((portable_reg, type_id)));
} else {
let _ = to_bytes_with_info(&mut out, &k, Some((portable_reg, type_id)));
}

let hash = hash(hasher, &out);
KeyValue::Value((type_id, hash, out, hasher.clone()))
})
.collect(),
);

Ok(storage_key)
let storage_key = StorageKey::new(
value_ty_id,
hash(&Hasher::Twox128, pallet_item.0),
hash(&Hasher::Twox128, pallet_item.1),
vec![KeyValue::Value((key_ty_id.expect("must key id must work"), hashed_value, touple_hex, hasher.clone()))]
);

Ok(storage_key)
} else {
Err(crate::Error::Encode("Wrong number of hashers vs map_keys".into()))
}
}
}

Expand All @@ -233,14 +273,17 @@ impl EntryTy for EntryType {
hashers,
key,
value,
} => self.build_call(
registry,
Some(key.id),
value.id,
(pallet, item),
map_keys,
hashers,
),
} => {
log::info!("key={}, value={}, hasher={:?}", key.id, value.id, hashers);
self.build_call(
registry,
Some(key.id),
value.id,
(pallet, item),
map_keys,
hashers,
)
},
}
}
}
Loading