Skip to content

Commit

Permalink
feat: add at to block
Browse files Browse the repository at this point in the history
  • Loading branch information
S0c5 committed Aug 17, 2024
1 parent a53acea commit 82dc159
Show file tree
Hide file tree
Showing 12 changed files with 141 additions and 64 deletions.
1 change: 0 additions & 1 deletion libwallet/examples/persisted_in_keyring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
let vault = vault::OSKeyring::<String>::new(TEST_USER, Language::default());

let mut wallet = Wallet::new(vault);


wallet.unlock(None, pin).await?;

Expand Down
8 changes: 4 additions & 4 deletions libwallet/src/vault/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use core::marker::PhantomData;
use crate::{
mnemonic::{Language, Mnemonic},
util::{seed_from_entropy, Pin},
vault::utils::{AccountSigner, RootAccount},
Vault,
vault::utils::{ RootAccount, AccountSigner }
};
use arrayvec::ArrayVec;
use keyring;
Expand All @@ -16,7 +16,7 @@ pub struct OSKeyring<S> {
entry: keyring::Entry,
root: Option<RootAccount>,
auto_generate: Option<Language>,
_phantom: PhantomData<S>
_phantom: PhantomData<S>,
}

impl<S> OSKeyring<S> {
Expand All @@ -28,7 +28,7 @@ impl<S> OSKeyring<S> {
entry: keyring::Entry::new(SERVICE, &uname),
root: None,
auto_generate: lang.into(),
_phantom: PhantomData::default()
_phantom: PhantomData::default(),
}
}

Expand Down Expand Up @@ -119,7 +119,7 @@ impl<S: AsRef<str>> Vault for OSKeyring<S> {
.and_then(|l| self.generate(pin, l))
})
.map(|r| {
let acc = AccountSigner::new(account.as_ref().map(|x| x.as_ref())).unlock(&r);
let acc = AccountSigner::new(account.as_ref().map(|x| x.as_ref())).unlock(&r);
self.root = Some(r);
acc
})
Expand Down
10 changes: 8 additions & 2 deletions sube/examples/pallet_communities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,20 @@ async fn main() -> Result<()> {

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

let result = sube!("https://kreivo.io/system/account/0x12840f0626ac847d41089c4e05cf0719c5698af1e3bb87b66542de70b2de4b2b").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"));
println!(
"Account info: {}",
serde_json::to_string_pretty(&data).expect("it must return an str")
);
}

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

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

let result = sube!("ws://127.0.0.1:12281/system/account/0x12840f0626ac847d41089c4e05cf0719c5698af1e3bb87b66542de70b2de4b2b?at=0xd26390715322be085596da3d21a9f357e7477ea48e68438430ed9fbea6235845").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")
);
}

Ok(())
}
7 changes: 3 additions & 4 deletions sube/examples/query_membership.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ async fn main() -> sube::Result<()> {

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

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

if let Response::ValueSet(ref v) = r {
Expand All @@ -23,4 +22,4 @@ async fn main() -> sube::Result<()> {
}

Ok(())
}
}
7 changes: 3 additions & 4 deletions sube/examples/query_preimage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ async fn main() -> sube::Result<()> {

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

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

if let Response::Value(ref v) = r {
Expand All @@ -23,4 +22,4 @@ async fn main() -> sube::Result<()> {
}

Ok(())
}
}
5 changes: 4 additions & 1 deletion sube/examples/query_referendum_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ async fn main() -> Result<()> {
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"));
println!(
"Info: {}",
serde_json::to_string_pretty(&json_value).expect("it must return an str")
);
}
Ok(())
}
15 changes: 10 additions & 5 deletions sube/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ impl<'a> SubeBuilder<'a, (), ()> {
let Self { url, metadata, .. } = self;

let url = chain_string_to_url(url.ok_or(Error::BadInput)?)?;

let block = url
.query_pairs()
.find(|(k, _)| k == "at")
.map(|(_, v)| v.to_string());
let path = url.path();

log::trace!("building the backend for {}", url);
Expand All @@ -71,7 +76,7 @@ impl<'a> SubeBuilder<'a, (), ()> {
Ok(match path {
"_meta" => Response::Meta(meta),
"_meta/registry" => Response::Registry(&meta.types),
_ => crate::query(&backend, meta, path).await?,
_ => crate::query(&backend, meta, path, block).await?,
})
}
}
Expand Down Expand Up @@ -329,13 +334,13 @@ impl Backend for &AnyBackend {
}
}

async fn query_storage(&self, key: &StorageKey) -> SubeResult<Vec<u8>> {
async fn query_storage(&self, key: &StorageKey, block: Option<String>) -> SubeResult<Vec<u8>> {
match self {
#[cfg(any(feature = "http", feature = "http-web"))]
AnyBackend::Http(b) => b.query_storage(key).await,
AnyBackend::Http(b) => b.query_storage(key, block).await,
#[cfg(feature = "ws")]
AnyBackend::Ws(b) => b.query_storage(key).await,
AnyBackend::_Offline(b) => b.query_storage(key).await,
AnyBackend::Ws(b) => b.query_storage(key, block).await,
AnyBackend::_Offline(b) => b.query_storage(key, block).await,
}
}
}
Expand Down
25 changes: 16 additions & 9 deletions sube/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,19 @@ 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>> {
async fn query<'m>(
chain: &impl Backend,
meta: &'m Metadata,
path: &str,
block: Option<String>,
) -> Result<Response<'m>> {
log::info!("path {}", path);
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 @@ -96,12 +102,12 @@ async fn query<'m>(chain: &impl Backend, meta: &'m Metadata, path: &str) -> Resu
{
if !key_res.is_partial() {
log::info!("is not partial");
let res = chain.query_storage(&key_res).await?;
let res = chain.query_storage(&key_res, 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 result = chain.query_storage_at(res, None).await?;
let result = chain.query_storage_at(res, block).await?;

if let [storage_change, ..] = &result[..] {
let value = storage_change
Expand All @@ -110,19 +116,19 @@ async fn query<'m>(chain: &impl Backend, meta: &'m Metadata, path: &str) -> Resu
.map(|[key, data]| {
let key = key.replace(&hex::encode(&key_res.pallet), "");
let key = key.replace(&hex::encode(&key_res.call), "");
let mut pointer = 2 + 32; // + 0x
let mut offset = 2 + 32; // + 0x
let keys = key_res
.args
.iter()
.map(|arg| match arg {
KeyValue::Empty(type_id) | KeyValue::Value((type_id, _, _, _)) => {
let hashed = &key[pointer..];
let hashed = &key[offset..];
let value = Value::new(
hex::decode(hashed).expect("hello world"),
*type_id,
&meta.types,
);
pointer += (value.size() * 2) + 32;
offset += (value.size() * 2) + 32;
value
}
})
Expand Down Expand Up @@ -215,6 +221,7 @@ where
&chain,
meta,
&format!("system/account/0x{}", hex::encode(from_account.as_ref())),
None,
)
.await?;

Expand Down Expand Up @@ -419,7 +426,7 @@ pub trait Backend {
) -> crate::Result<Vec<String>>;

/// Get raw storage items form the blockchain
async fn query_storage(&self, key: &StorageKey) -> Result<Vec<u8>>;
async fn query_storage(&self, key: &StorageKey, block: Option<String>) -> Result<Vec<u8>>;

/// Send a signed extrinsic to the blockchain
async fn submit(&self, ext: impl AsRef<[u8]>) -> Result<()>;
Expand Down Expand Up @@ -450,7 +457,7 @@ impl Backend for Offline {
Err(Error::ChainUnavailable)
}

async fn query_storage(&self, _key: &StorageKey) -> Result<Vec<u8>> {
async fn query_storage(&self, _key: &StorageKey, _block: Option<String>) -> Result<Vec<u8>> {
Err(Error::ChainUnavailable)
}

Expand Down
69 changes: 42 additions & 27 deletions sube/src/meta_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,14 @@ impl StorageKey {
.as_ref()
.and_then(|s| s.entries.iter().find(|e| e.name == item))
.ok_or(crate::Error::CantFindMethodInPallet)?;
log::trace!("map_keys={}", map_keys.iter().map(|x| x.as_ref()).collect::<Vec<&str>>().join(", "));
log::trace!(
"map_keys={}",
map_keys
.iter()
.map(|x| x.as_ref())
.collect::<Vec<&str>>()
.join(", ")
);
entry.ty.key(registry, &meta.name, &entry.name, map_keys)
}
}
Expand Down Expand Up @@ -181,7 +188,7 @@ pub trait EntryTy {
} else {
vec![]
};

if type_call_ids.len() == hashers.len() {
log::trace!("type_call_ids={:?}", type_call_ids);
let storage_key = StorageKey::new(
Expand All @@ -195,48 +202,49 @@ pub trait EntryTy {
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)));
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::trace!("treating touple as argument for hasher");

let touple_hex: Vec<u8> = type_call_ids
.into_iter()
.enumerate()
.flat_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 hex 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
})
.collect();
.into_iter()
.enumerate()
.flat_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 hex 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
})
.collect();

let hasher = hashers.first().expect("hasher not found");
let hasher = hasher.borrow();
Expand All @@ -246,12 +254,19 @@ pub trait EntryTy {
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()))]
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()))
Err(crate::Error::Encode(
"Wrong number of hashers vs map_keys".into(),
))
}
}
}
Expand Down Expand Up @@ -282,7 +297,7 @@ impl EntryTy for EntryType {
map_keys,
hashers,
)
},
}
}
}
}
Loading

0 comments on commit 82dc159

Please sign in to comment.