Skip to content

Commit

Permalink
add sp-client for resource-viewer (#163)
Browse files Browse the repository at this point in the history
* add sp-client for resource-viewer

* make json-schema optional as feature

* update deps

* support ss58 addrs in param & query

* support output block height

* partially support input block height

* fix query parsing error formatting

* bump version minor

* improve documentation for resource viewer
  • Loading branch information
boozook authored Feb 25, 2021
1 parent feab160 commit 0e17a96
Show file tree
Hide file tree
Showing 8 changed files with 3,293 additions and 344 deletions.
3,280 changes: 2,965 additions & 315 deletions Cargo.lock

Large diffs are not rendered by default.

31 changes: 26 additions & 5 deletions resource-viewer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "move-resource-viewer"
version = "0.1.2"
version = "0.1.3"
authors = ["Alex Koz. <[email protected]>"]
edition = "2018"

Expand All @@ -13,7 +13,7 @@ http = "0.2"

serde = { version = "=1.0.118", features = ["derive", "rc"] }
serde_json = "1.0"
schemars = { version = "0.8", features = ["default", "derive", "preserve_order"] }
schemars = { version = "0.8", features = ["default", "derive", "preserve_order"], optional = true }
hex = "0.4.2"

# move-lang deps:
Expand All @@ -22,7 +22,20 @@ libra = { package = "dfibra", git = "https://github.com/dfinance/libra.git", bra
lang = { path = "../lang" }
git-hash = { path = "../common/git-hash" }
compat = { path = "../lang/compat", package = "move-compat" }
dnclient = { path = "../common/dnode-rest-client", package = "dnode-rest-client" }
dnclient = { path = "../common/dnode-rest-client", package = "dnode-rest-client", optional = true }

# ps:
[dependencies.substrate-api-client]
git = "https://github.com/scs/substrate-api-client.git"
rev = "62afbac0be1928681d8c70565fa0cc39a92cf4c8"
optional = true
[dependencies.keyring]
version = '2.0.0'
package = "sp-keyring"
optional = true
[dependencies.sp-core]
version = '2.0.0'
optional = true

# cli:
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
Expand All @@ -32,21 +45,29 @@ env_logger = "0.8.2"

[features]
default = [
"dfinance_address"
"json-schema",
"dfinance_address",
]

libra_address = [
"lang/libra_address",
"libra/libra_address",
"compat/libra_address",
"dnclient",
]
dfinance_address = [
"lang/dfinance_address",
"libra/dfinance_address",
"compat/dfinance_address",
"dnclient",
]
ps_address = [
"lang/ps_address",
"libra/ps_address",
"compat/ps_address",
]
"substrate-api-client",
"keyring",
"sp-core",
]

json-schema = [ "schemars", ]
32 changes: 32 additions & 0 deletions resource-viewer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,31 @@ cargo install --git https://github.com/dfinance/move-tools.git move-resource-vie
[Rust]: https://www.rust-lang.org
[Rustup]: https://rustup.rs


### Build with optional features

- `json-schema` - adds option to export json schema for output format
- `dfinance_address` - support [DFinance][] node & address format
- `libra_address` - support [Libra/Diem][] address format
- `ps_address` - support Substrate node & [ss58][] address format

[DFinance]: https://github.com/dfinance
[Libra/Diem]: https://github.com/diem
[ss58]: "https://github.com/paritytech/substrate/wiki/External-Address-Format-(SS58)"

Add shousen features as list to the command line:
```bash
cargo install --git https://github.com/dfinance/move-tools.git move-resource-viewer \
--no-default-features \
--features="feature, feature, feature"
```

For example To build Resource Viewer for Polkadot/Substrate use:
```bash
--no-default-features --features="ps_address"
```


## Usage example

Query the user's ETH balance:
Expand Down Expand Up @@ -59,6 +84,13 @@ For more info check out `--help`.
[dnode]: https://github.com/dfinance/dnode
[bech32]: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki


### Substrate

Additionally if Resource Viewer was built with `ps_address` feature,
[ss58][]-addresses are acceptable for `--account` and `--query` parameters.


### Output

Two output formats supported:
Expand Down
11 changes: 10 additions & 1 deletion resource-viewer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
#[macro_use]
extern crate anyhow;

pub mod ser;
pub mod tte;

#[cfg(feature = "ps_address")]
mod sp_client;

pub mod net {
#[cfg(any(feature = "dfinance_address", feature = "libra_address"))]
pub use dnclient::blocking::{get_resource, client::DnodeRestClient as NodeClient};
#[cfg(feature = "ps_address")]
pub use super::sp_client::*;
}
35 changes: 29 additions & 6 deletions resource-viewer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ use http::Uri;
use clap::Clap;
use libra::prelude::*;
use lang::compiler::bech32::{bech32_into_libra, HRP};
use dnclient::blocking as net;
use libra::rv;
use move_resource_viewer::{tte, ser};
use move_resource_viewer::{tte, ser, net::*};

const VERSION: &str = git_hash::crate_version_with_git_hash_short!();
#[cfg(feature = "json-schema")]
const JSON_SCHEMA_STDOUT: &str = "-";
const VERSION: &str = git_hash::crate_version_with_git_hash_short!();

#[derive(Clap, Debug)]
#[clap(name = "Move resource viewer", version = VERSION)]
Expand All @@ -40,7 +40,10 @@ struct Cfg {

/// Time: maximum block number
#[clap(long, short)]
#[cfg(not(feature = "ps_address"))]
height: Option<u128>,
#[cfg(feature = "ps_address")]
height: Option<sp_core::H256>,

/// Output file path
#[clap(long, short)]
Expand All @@ -61,6 +64,7 @@ struct Cfg {

/// Export JSON schema for output format.
/// Special value for write to stdout: "-"
#[cfg(feature = "json-schema")]
#[clap(long = "json-schema")]
json_schema: Option<PathBuf>,
}
Expand Down Expand Up @@ -100,18 +104,24 @@ fn run() -> Result<(), Error> {
let (tte, index) = cfg.query.into_inner();
let addr = if cfg.address.starts_with(HRP) {
AccountAddress::from_hex_literal(&bech32_into_libra(&cfg.address)?)
} else if cfg.address.starts_with("0x") {
AccountAddress::from_hex_literal(&cfg.address)
} else if let Ok(addr) = lang::compiler::ss58::ss58_to_libra(&cfg.address) {
debug!("address decoded: {:}", addr);
AccountAddress::from_hex_literal(&addr)
} else {
// fail with from:
AccountAddress::from_hex_literal(&cfg.address)
}?;

match tte {
TypeTag::Struct(st) => {
let key = ResourceKey::new(addr, st.clone());
let res = net::get_resource(&key, &host, height);
let res = get_resource(&key, &host, height);
res.map(|resp| {
let bytes = resp.as_bytes();
if !bytes.is_empty() {
let client = net::client::DnodeRestClient::new(host, height);
let client = NodeClient::new(host, height);

// Internally produce FatStructType (with layout) for StructTag by
// resolving & de-.. entire deps-chain.
Expand All @@ -120,7 +130,18 @@ fn run() -> Result<(), Error> {
annotator
.view_resource(&st, &bytes)
.and_then(|result| {
let height = resp.block();
let height = {
let height;
#[cfg(feature = "ps_address")]
{
height = format!("{:#x}", resp.block());
}
#[cfg(not(feature = "ps_address"))]
{
height = resp.block();
}
height
};
if json {
serde_json::ser::to_string_pretty(
&ser::AnnotatedMoveStructWrapper { height, result },
Expand Down Expand Up @@ -148,7 +169,9 @@ fn run() -> Result<(), Error> {
}
}

#[allow(unused_variables)]
fn produce_json_schema(cfg: &Cfg) {
#[cfg(feature = "json-schema")]
if let Some(path) = cfg.json_schema.as_ref() {
let schema = ser::produce_json_schema();
let render = serde_json::to_string_pretty(&schema).unwrap();
Expand Down
48 changes: 34 additions & 14 deletions resource-viewer/src/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,48 @@ use libra::rv;
use libra::prelude::*;
use libra::move_core_types::language_storage::StructTag;
use libra::account::Identifier;
use rv::{AnnotatedMoveStruct, AnnotatedMoveValue};
use serde::Serialize;
use schemars::{JsonSchema, schema_for};
use schemars::schema::RootSchema;
use rv::{AnnotatedMoveStruct, AnnotatedMoveValue};

#[cfg(feature = "json-schema")]
use schemars::{JsonSchema, schema_for, schema::RootSchema};

#[cfg(feature = "json-schema")]
pub fn produce_json_schema() -> RootSchema {
schema_for!(AnnotatedMoveStructExt)
}

#[derive(Serialize, JsonSchema)]
#[derive(Serialize)]
#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
pub struct AnnotatedMoveStructWrapper {
/// Block number, current for the state
#[cfg(not(feature = "ps_address"))]
pub height: u128,
#[cfg(feature = "ps_address")]
pub height: String,

#[serde(with = "AnnotatedMoveStructExt")]
pub result: AnnotatedMoveStruct,
}

#[derive(Serialize, JsonSchema)]
#[derive(Serialize)]
#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
#[serde(remote = "rv::AnnotatedMoveStruct")]
struct AnnotatedMoveStructExt {
is_resource: bool,
#[serde(rename = "type")]
#[serde(with = "schema_support::StructTagExt")]
#[cfg_attr(feature = "json-schema", serde(with = "schema_support::StructTagExt"))]
type_: StructTag,
#[schemars(schema_with = "schema_support::vec_identifier_annotated_move_value")]
#[cfg_attr(
feature = "json-schema",
schemars(schema_with = "schema_support::vec_identifier_annotated_move_value")
)]
#[serde(serialize_with = "vec_annotated_move_value_mapped::serialize")]
value: Vec<(Identifier, AnnotatedMoveValue)>,
}

#[derive(Serialize, JsonSchema)]
#[derive(Serialize)]
#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
#[serde(remote = "rv::AnnotatedMoveValue")]
enum AnnotatedMoveValueExt {
U8(u8),
Expand All @@ -43,16 +54,19 @@ enum AnnotatedMoveValueExt {
Bool(bool),
Address(#[serde(with = "AccountAddressExt")] AccountAddress),
Vector(
// #[serde(with = "AnnotatedMoveValueExt")]
#[schemars(schema_with = "schema_support::vec_annotated_move_value")]
#[cfg_attr(
feature = "json-schema",
schemars(schema_with = "schema_support::vec_annotated_move_value")
)]
#[serde(serialize_with = "vec_annotated_move_value::serialize")]
Vec<AnnotatedMoveValue>,
),
Bytes(Vec<u8>),
Struct(#[serde(with = "AnnotatedMoveStructExt")] AnnotatedMoveStruct),
}

#[derive(Serialize, JsonSchema)]
#[derive(Serialize)]
#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
#[serde(remote = "AccountAddress")]
struct AccountAddressExt(
#[serde(getter = "AccountAddressExt::ext_to_u8")] pub [u8; AccountAddress::LENGTH],
Expand All @@ -63,20 +77,23 @@ impl AccountAddressExt {
}
}

#[derive(Serialize, JsonSchema)]
#[derive(Serialize)]
#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
#[serde(remote = "Identifier")]
struct IdentifierExt(#[serde(getter = "Identifier::to_string")] pub String);

mod vec_annotated_move_value {
use super::{AnnotatedMoveValue, AnnotatedMoveValueExt};
use serde::{Serialize, Serializer};
#[cfg(feature = "json-schema")]
use schemars::JsonSchema;

pub fn serialize<S>(vec: &[AnnotatedMoveValue], serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
#[derive(Serialize, JsonSchema)]
#[derive(Serialize)]
#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
struct Helper<'a>(#[serde(with = "AnnotatedMoveValueExt")] &'a AnnotatedMoveValue);

vec.iter()
Expand All @@ -90,6 +107,7 @@ mod vec_annotated_move_value_mapped {
use super::{AnnotatedMoveValue, AnnotatedMoveValueExt};
use super::{Identifier, IdentifierExt};
use serde::{Serialize, Serializer};
#[cfg(feature = "json-schema")]
use schemars::JsonSchema;

pub fn serialize<S>(
Expand All @@ -99,7 +117,8 @@ mod vec_annotated_move_value_mapped {
where
S: Serializer,
{
#[derive(Serialize, JsonSchema)]
#[derive(Serialize)]
#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
struct Helper<'a> {
#[serde(with = "IdentifierExt")]
id: &'a Identifier,
Expand All @@ -114,6 +133,7 @@ mod vec_annotated_move_value_mapped {
}
}

#[cfg(feature = "json-schema")]
mod schema_support {
use super::*;
use schemars::{
Expand Down
Loading

0 comments on commit 0e17a96

Please sign in to comment.