mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 18:41:05 +00:00
Refactor (#7)
* Increment nonce when submitting transaction. * Refactor. * use default values from metadata * use functions from metadata * Nonce fixup * Add docs. * Add contracts module. * Add set_code. * Add events to metadata. * Support pretty printing metadata. * Add subscriptions. * Add submit_and_watch to XtBuilder. * nits from review
This commit is contained in:
+105
-33
@@ -1,4 +1,8 @@
|
||||
use parity_scale_codec::Encode;
|
||||
use crate::codec::Encoded;
|
||||
use parity_scale_codec::{
|
||||
Decode,
|
||||
Encode,
|
||||
};
|
||||
use runtime_metadata::{
|
||||
DecodeDifferent,
|
||||
RuntimeMetadata,
|
||||
@@ -11,15 +15,17 @@ use runtime_metadata::{
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
convert::TryFrom,
|
||||
marker::PhantomData,
|
||||
};
|
||||
use substrate_primitives::storage::StorageKey;
|
||||
|
||||
pub struct Encoded(pub Vec<u8>);
|
||||
|
||||
impl Encode for Encoded {
|
||||
fn encode(&self) -> Vec<u8> {
|
||||
self.0.to_owned()
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub enum MetadataError {
|
||||
ModuleNotFound(&'static str),
|
||||
CallNotFound(&'static str),
|
||||
StorageNotFound(&'static str),
|
||||
StorageTypeError,
|
||||
MapValueTypeError,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -28,27 +34,66 @@ pub struct Metadata {
|
||||
}
|
||||
|
||||
impl Metadata {
|
||||
pub fn module(&self, name: &str) -> Option<&ModuleMetadata> {
|
||||
self.modules.get(name)
|
||||
pub fn module(&self, name: &'static str) -> Result<&ModuleMetadata, MetadataError> {
|
||||
self.modules
|
||||
.get(name)
|
||||
.ok_or(MetadataError::ModuleNotFound(name))
|
||||
}
|
||||
|
||||
pub fn pretty(&self) -> String {
|
||||
let mut string = String::new();
|
||||
for (name, module) in &self.modules {
|
||||
string.push_str(name.as_str());
|
||||
string.push('\n');
|
||||
for (storage, _) in &module.storage {
|
||||
string.push_str(" s ");
|
||||
string.push_str(storage.as_str());
|
||||
string.push('\n');
|
||||
}
|
||||
for (call, _) in &module.calls {
|
||||
string.push_str(" c ");
|
||||
string.push_str(call.as_str());
|
||||
string.push('\n');
|
||||
}
|
||||
for (event, _) in &module.events {
|
||||
string.push_str(" e ");
|
||||
string.push_str(event.as_str());
|
||||
string.push('\n');
|
||||
}
|
||||
}
|
||||
string
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ModuleMetadata {
|
||||
index: u8,
|
||||
index: Vec<u8>,
|
||||
storage: HashMap<String, StorageMetadata>,
|
||||
// calls, event, constants
|
||||
calls: HashMap<String, Vec<u8>>,
|
||||
events: HashMap<String, Vec<u8>>,
|
||||
// constants
|
||||
}
|
||||
|
||||
impl ModuleMetadata {
|
||||
pub fn call<T: Encode>(&self, call: T) -> Encoded {
|
||||
let mut bytes = vec![self.index];
|
||||
bytes.extend(call.encode());
|
||||
Encoded(bytes)
|
||||
pub fn call<T: Encode>(
|
||||
&self,
|
||||
function: &'static str,
|
||||
params: T,
|
||||
) -> Result<Encoded, MetadataError> {
|
||||
let fn_bytes = self
|
||||
.calls
|
||||
.get(function)
|
||||
.ok_or(MetadataError::CallNotFound(function))?;
|
||||
let mut bytes = self.index.clone();
|
||||
bytes.extend(fn_bytes);
|
||||
bytes.extend(params.encode());
|
||||
Ok(Encoded(bytes))
|
||||
}
|
||||
|
||||
pub fn storage(&self, key: &str) -> Option<&StorageMetadata> {
|
||||
self.storage.get(key)
|
||||
pub fn storage(&self, key: &'static str) -> Result<&StorageMetadata, MetadataError> {
|
||||
self.storage
|
||||
.get(key)
|
||||
.ok_or(MetadataError::StorageNotFound(key))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,26 +106,37 @@ pub struct StorageMetadata {
|
||||
}
|
||||
|
||||
impl StorageMetadata {
|
||||
pub fn map(&self) -> Option<StorageMap> {
|
||||
pub fn get_map<K: Encode, V: Decode + Clone>(
|
||||
&self,
|
||||
) -> Result<StorageMap<K, V>, MetadataError> {
|
||||
match &self.ty {
|
||||
StorageEntryType::Map { hasher, .. } => {
|
||||
let prefix = self.prefix.as_bytes().to_vec();
|
||||
let hasher = hasher.to_owned();
|
||||
Some(StorageMap { prefix, hasher })
|
||||
let default = Decode::decode(&mut &self.default[..])
|
||||
.map_err(|_| MetadataError::MapValueTypeError)?;
|
||||
Ok(StorageMap {
|
||||
_marker: PhantomData,
|
||||
prefix,
|
||||
hasher,
|
||||
default,
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
_ => Err(MetadataError::StorageTypeError),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct StorageMap {
|
||||
pub struct StorageMap<K, V> {
|
||||
_marker: PhantomData<K>,
|
||||
prefix: Vec<u8>,
|
||||
hasher: StorageHasher,
|
||||
default: V,
|
||||
}
|
||||
|
||||
impl StorageMap {
|
||||
pub fn key<K: Encode>(&self, key: K) -> StorageKey {
|
||||
impl<K: Encode, V: Decode + Clone> StorageMap<K, V> {
|
||||
pub fn key(&self, key: K) -> StorageKey {
|
||||
let mut bytes = self.prefix.clone();
|
||||
bytes.extend(key.encode());
|
||||
let hash = match self.hasher {
|
||||
@@ -96,6 +152,10 @@ impl StorageMap {
|
||||
};
|
||||
StorageKey(hash)
|
||||
}
|
||||
|
||||
pub fn default(&self) -> V {
|
||||
self.default.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -118,10 +178,7 @@ impl TryFrom<RuntimeMetadataPrefixed> for Metadata {
|
||||
};
|
||||
let mut modules = HashMap::new();
|
||||
for (i, module) in convert(meta.modules)?.into_iter().enumerate() {
|
||||
modules.insert(
|
||||
convert(module.name.clone())?,
|
||||
convert_module(i as u8, module)?,
|
||||
);
|
||||
modules.insert(convert(module.name.clone())?, convert_module(i, module)?);
|
||||
}
|
||||
Ok(Metadata { modules })
|
||||
}
|
||||
@@ -135,10 +192,10 @@ fn convert<B: 'static, O: 'static>(dd: DecodeDifferent<B, O>) -> Result<O, Error
|
||||
}
|
||||
|
||||
fn convert_module(
|
||||
index: u8,
|
||||
index: usize,
|
||||
module: runtime_metadata::ModuleMetadata,
|
||||
) -> Result<ModuleMetadata, Error> {
|
||||
let mut entries = HashMap::new();
|
||||
let mut storage_map = HashMap::new();
|
||||
if let Some(storage) = module.storage {
|
||||
let storage = convert(storage)?;
|
||||
let prefix = convert(storage.prefix)?;
|
||||
@@ -146,13 +203,28 @@ fn convert_module(
|
||||
let entry_name = convert(entry.name.clone())?;
|
||||
let entry_prefix = format!("{} {}", prefix, entry_name);
|
||||
let entry = convert_entry(entry_prefix, entry)?;
|
||||
entries.insert(entry_name, entry);
|
||||
storage_map.insert(entry_name, entry);
|
||||
}
|
||||
}
|
||||
let mut call_map = HashMap::new();
|
||||
if let Some(calls) = module.calls {
|
||||
for (index, call) in convert(calls)?.into_iter().enumerate() {
|
||||
let name = convert(call.name)?;
|
||||
call_map.insert(name, vec![index as u8]);
|
||||
}
|
||||
}
|
||||
let mut event_map = HashMap::new();
|
||||
if let Some(events) = module.event {
|
||||
for (index, event) in convert(events)?.into_iter().enumerate() {
|
||||
let name = convert(event.name)?;
|
||||
event_map.insert(name, vec![index as u8]);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ModuleMetadata {
|
||||
index,
|
||||
storage: entries,
|
||||
index: vec![index as u8],
|
||||
storage: storage_map,
|
||||
calls: call_map,
|
||||
events: event_map,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user