From fb4ff80955e1a7dc29bbcbabe1e2e4e39cdd9abf Mon Sep 17 00:00:00 2001 From: Dustin Brickwood Date: Fri, 24 Jul 2020 15:24:22 -0500 Subject: [PATCH 01/14] initial implementation done; still need to format cli --- Cargo.lock | 163 ++++++++++++++++++++++++++++- blockchain/blocks/src/tipset.rs | 2 +- forest/Cargo.toml | 1 + forest/src/cli/chain_cmd.rs | 51 +++++++++ forest/src/cli/fetch_params_cmd.rs | 73 +++++++++++++ forest/src/cli/genesis.rs | 2 +- forest/src/cli/mod.rs | 24 +++-- forest/src/cli/wallet_cmd.rs | 11 ++ forest/src/subcommand.rs | 69 ++---------- node/rpc-client/Cargo.toml | 15 +++ node/rpc-client/src/chain_ops.rs | 48 +++++++++ node/rpc-client/src/client.rs | 78 ++++++++++++++ node/rpc-client/src/lib.rs | 10 ++ node/rpc-client/src/wallet_ops.rs | 65 ++++++++++++ vm/message/src/unsigned_message.rs | 2 +- 15 files changed, 538 insertions(+), 76 deletions(-) create mode 100644 forest/src/cli/chain_cmd.rs create mode 100644 forest/src/cli/fetch_params_cmd.rs create mode 100644 forest/src/cli/wallet_cmd.rs create mode 100644 node/rpc-client/Cargo.toml create mode 100644 node/rpc-client/src/chain_ops.rs create mode 100644 node/rpc-client/src/client.rs create mode 100644 node/rpc-client/src/lib.rs create mode 100644 node/rpc-client/src/wallet_ops.rs diff --git a/Cargo.lock b/Cargo.lock index ca58e85efcc0..d7bfd0c27ce8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,15 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + [[package]] name = "actix-codec" version = "0.2.0" @@ -632,6 +642,18 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c17772156ef2829aadc587461c7753af20b7e8db1529bc66855add962a3b35d3" +[[package]] +name = "async-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce6977f57fa68da77ffe5542950d47e9c23d65f5bc7cb0a9f8700996913eec7" +dependencies = [ + "futures 0.3.5", + "rustls 0.16.0", + "webpki", + "webpki-roots 0.17.0", +] + [[package]] name = "async-tls" version = "0.8.0" @@ -731,6 +753,15 @@ dependencies = [ "safemem", ] +[[package]] +name = "base64" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" +dependencies = [ + "byteorder 1.3.4", +] + [[package]] name = "base64" version = "0.11.0" @@ -2327,6 +2358,7 @@ dependencies = [ "pin-project-lite", "pretty_env_logger", "rpc", + "rpc-client", "serde", "serde_json", "state_manager", @@ -2804,6 +2836,19 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +[[package]] +name = "globset" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ad1da430bd7281dde2576f44c84cc3f0f7b475e7202cd503042dff01a8c8120" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + [[package]] name = "gloo-timers" version = "0.2.1" @@ -2928,6 +2973,16 @@ dependencies = [ "autocfg 0.1.7", ] +[[package]] +name = "hashbrown" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96282e96bfcd3da0d3aa9938bedf1e50df3269b6db08b4876d2da0bb1a0841cf" +dependencies = [ + "ahash 0.3.8", + "autocfg 1.0.0", +] + [[package]] name = "heck" version = "0.3.1" @@ -3392,6 +3447,51 @@ dependencies = [ "syn 1.0.34", ] +[[package]] +name = "jsonrpsee" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc8a1da5a54b417cfb7edb9f932024d833dc333de50c21c0e1b28d0e8b4f853" +dependencies = [ + "async-std", + "async-tls 0.6.0", + "bs58", + "bytes 0.5.6", + "fnv", + "futures 0.3.5", + "futures-timer", + "globset", + "hashbrown 0.7.2", + "hyper", + "jsonrpsee-proc-macros", + "lazy_static", + "log", + "parking_lot 0.10.2", + "pin-project", + "rand 0.7.3", + "serde", + "serde_json", + "smallvec 1.4.1", + "soketto 0.3.2", + "thiserror", + "tokio", + "unicase", + "url", + "webpki", +] + +[[package]] +name = "jsonrpsee-proc-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1ed1b5f6937dd2c6c79a9ac6e0e3f41bbc64edb5d443840bdc73e606009ed70" +dependencies = [ + "Inflector", + "proc-macro2 1.0.18", + "quote 1.0.7", + "syn 1.0.34", +] + [[package]] name = "keccak" version = "0.1.0" @@ -3945,7 +4045,7 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046a5201f6e471f22b22b394e4d084269ed1e28cf7300f7b49874385db84c7bd" dependencies = [ - "async-tls", + "async-tls 0.8.0", "either", "futures 0.3.5", "libp2p-core", @@ -3953,7 +4053,7 @@ dependencies = [ "quicksink", "rustls 0.18.0", "rw-stream-sink", - "soketto", + "soketto 0.4.1", "url", "webpki", "webpki-roots 0.18.0", @@ -4060,7 +4160,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0609345ddee5badacf857d4f547e0e5a2e987db77085c24cd887f73573a04237" dependencies = [ - "hashbrown", + "hashbrown 0.6.3", ] [[package]] @@ -4069,7 +4169,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35c456c123957de3a220cd03786e0d86aa542a88b46029973b542f426da6ef34" dependencies = [ - "hashbrown", + "hashbrown 0.6.3", ] [[package]] @@ -5468,6 +5568,20 @@ dependencies = [ "tide", ] +[[package]] +name = "rpc-client" +version = "0.1.0" +dependencies = [ + "forest_blocks", + "forest_crypto", + "forest_message", + "jsonrpc-v2", + "jsonrpsee", + "key_management", + "log", + "serde_json", +] + [[package]] name = "runtime" version = "0.1.0" @@ -5544,6 +5658,19 @@ dependencies = [ "semver 0.9.0", ] +[[package]] +name = "rustls" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e" +dependencies = [ + "base64 0.10.1", + "log", + "ring", + "sct", + "webpki", +] + [[package]] name = "rustls" version = "0.17.0" @@ -6043,6 +6170,25 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "soketto" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c9dab3f95c9ebdf3a88268c19af668f637a3c5039c2c56ff2d40b1b2d64a25b" +dependencies = [ + "base64 0.11.0", + "bytes 0.5.6", + "futures 0.3.5", + "http", + "httparse", + "log", + "rand 0.7.3", + "sha1", + "smallvec 1.4.1", + "static_assertions", + "thiserror", +] + [[package]] name = "soketto" version = "0.4.1" @@ -7157,6 +7303,15 @@ dependencies = [ "untrusted", ] +[[package]] +name = "webpki-roots" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a262ae37dd9d60f60dd473d1158f9fbebf110ba7b6a5051c8160460f6043718b" +dependencies = [ + "webpki", +] + [[package]] name = "webpki-roots" version = "0.18.0" diff --git a/blockchain/blocks/src/tipset.rs b/blockchain/blocks/src/tipset.rs index ed8e2f1ff9b8..9d01dc5eb68e 100644 --- a/blockchain/blocks/src/tipset.rs +++ b/blockchain/blocks/src/tipset.rs @@ -270,7 +270,7 @@ pub mod tipset_json { use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; /// Wrapper for serializing and deserializing a SignedMessage from JSON. - #[derive(Deserialize, Serialize)] + #[derive(Deserialize, Serialize, Debug)] #[serde(transparent)] pub struct TipsetJson(#[serde(with = "self")] pub Tipset); diff --git a/forest/Cargo.toml b/forest/Cargo.toml index 2fd6ffa32fe3..fbf804c7463c 100644 --- a/forest/Cargo.toml +++ b/forest/Cargo.toml @@ -27,6 +27,7 @@ structopt = { version = "0.3" } beacon = { path = "../blockchain/beacon" } hex = "0.4.2" rpc = { path = "../node/rpc" } +rpc_client = {package = "rpc-client", path = "../node/rpc-client" } fil_types = { path = "../types" } serde_json = "1.0" blake2b_simd = "0.5.9" diff --git a/forest/src/cli/chain_cmd.rs b/forest/src/cli/chain_cmd.rs new file mode 100644 index 000000000000..6ac5b584e888 --- /dev/null +++ b/forest/src/cli/chain_cmd.rs @@ -0,0 +1,51 @@ +// Copyright 2020 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0, MIT + +use rpc_client::{get_genesis, get_head}; +use structopt::StructOpt; + +#[allow(missing_docs)] +#[derive(Debug, StructOpt)] +pub struct ChainCommands { + /// Prints out the genesis tipset + #[structopt(long, help = "Prints genesis tipset")] + pub genesis: bool, + + /// Prints out the canonical head of the chain + #[structopt(long, help = "Print chain head")] + pub head: bool, + + #[structopt( + long = "read-obj", + value_name = "CID", + help = "Read the raw bytes of an object" + )] + pub read_obj: String, + + #[structopt( + long = "message", + value_name = "CIDs", + help = "Retrieve and print messages by CIDs" + )] + pub messages: String, + + #[structopt( + long = "block", + value_name = "CID", + help = "Retrieve a block and print its details" + )] + pub block: String, +} + +impl ChainCommands { + pub async fn run(&self) { + if self.genesis { + let gen = get_genesis().await; + println!("{}", serde_json::to_string_pretty(&gen).unwrap()); + } + if self.head { + let head = get_head().await; + println!("{}", serde_json::to_string_pretty(&head).unwrap()); + } + } +} diff --git a/forest/src/cli/fetch_params_cmd.rs b/forest/src/cli/fetch_params_cmd.rs new file mode 100644 index 000000000000..15464e404684 --- /dev/null +++ b/forest/src/cli/fetch_params_cmd.rs @@ -0,0 +1,73 @@ +// Copyright 2020 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0, MIT + +use crate::paramfetch::{get_params_default, SectorSizeOpt}; +use fil_types::SectorSize; +use structopt::StructOpt; + +#[allow(missing_docs)] +#[derive(Debug, StructOpt)] +pub struct FetchCommands { + #[structopt(short, long, help = "Download all proof parameters")] + all: bool, + #[structopt(short, long, help = "Download only verification keys")] + keys: bool, + #[structopt(required_ifs(&[("all", "false"), ("keys", "false")]), help = "Size in bytes")] + params_size: Option, + #[structopt(short, long, help = "Show verbose logging")] + verbose: bool, +} + +impl FetchCommands { + pub async fn run(&self) { + let sizes = if self.all { + SectorSizeOpt::All + } else if let Some(size) = &self.params_size { + let sector_size = ram_to_int(&size).unwrap(); + SectorSizeOpt::Size(sector_size) + } else if self.keys { + SectorSizeOpt::Keys + } else { + panic!("Sector size option must be chosen. Choose between --all, --keys, or "); + }; + + get_params_default(sizes, self.verbose).await.unwrap(); + } +} + +/// Converts a human readable string to a u64 size. +fn ram_to_int(size: &str) -> Result { + // TODO there is no library to do this, but if other sector sizes are supported in future + // this should probably be changed to parse from string to `SectorSize` + let mut trimmed = size.trim_end_matches('B'); + trimmed = trimmed.trim_end_matches('b'); + + match trimmed { + "2048" | "2Ki" | "2ki" => Ok(SectorSize::_2KiB), + "8388608" | "8Mi" | "8mi" => Ok(SectorSize::_8MiB), + "536870912" | "512Mi" | "512mi" => Ok(SectorSize::_512MiB), + "34359738368" | "32Gi" | "32gi" => Ok(SectorSize::_32GiB), + "68719476736" | "64Gi" | "64gi" => Ok(SectorSize::_64GiB), + _ => Err(format!( + "Failed to parse: {}. Must be a valid sector size", + size + )), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn ram_str_conversions() { + assert_eq!(ram_to_int("2048").unwrap(), SectorSize::_2KiB); + assert_eq!(ram_to_int("2048B").unwrap(), SectorSize::_2KiB); + assert_eq!(ram_to_int("2kib").unwrap(), SectorSize::_2KiB); + assert_eq!(ram_to_int("8Mib").unwrap(), SectorSize::_8MiB); + assert_eq!(ram_to_int("512MiB").unwrap(), SectorSize::_512MiB); + assert_eq!(ram_to_int("32Gi").unwrap(), SectorSize::_32GiB); + assert_eq!(ram_to_int("32GiB").unwrap(), SectorSize::_32GiB); + assert_eq!(ram_to_int("64Gib").unwrap(), SectorSize::_64GiB); + } +} diff --git a/forest/src/cli/genesis.rs b/forest/src/cli/genesis.rs index 217d5f1cb291..dc5c92f0f1a1 100644 --- a/forest/src/cli/genesis.rs +++ b/forest/src/cli/genesis.rs @@ -33,7 +33,7 @@ where None => { debug!("No specified genesis in config. Using default genesis."); let bz = include_bytes!("devnet.car"); - let reader = BufReader::new(bz.as_ref()); + let reader = BufReader::<&[u8]>::new(bz.as_ref()); process_car(reader, chain_store)? } }; diff --git a/forest/src/cli/mod.rs b/forest/src/cli/mod.rs index 9e8e7a51aa06..5d442c08e83c 100644 --- a/forest/src/cli/mod.rs +++ b/forest/src/cli/mod.rs @@ -1,11 +1,17 @@ // Copyright 2020 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT +mod chain_cmd; mod config; +mod fetch_params_cmd; mod genesis; +mod wallet_cmd; +pub(super) use self::chain_cmd::ChainCommands; pub use self::config::Config; +pub(super) use self::fetch_params_cmd::FetchCommands; pub(super) use self::genesis::initialize_genesis; +pub(super) use self::wallet_cmd::WalletCommands; use std::cell::RefCell; use std::io; @@ -32,21 +38,19 @@ pub struct CLI { /// Forest binary subcommands available. #[derive(StructOpt)] +#[structopt(setting = structopt::clap::AppSettings::VersionlessSubcommands)] pub enum Subcommand { #[structopt( name = "fetch-params", about = "Download parameters for generating and verifying proofs for given size" )] - FetchParams { - #[structopt(short, long, help = "Download all proof parameters")] - all: bool, - #[structopt(short, long, help = "Download only verification keys")] - keys: bool, - #[structopt(required_ifs(&[("all", "false"), ("keys", "false")]), help = "Size in bytes")] - params_size: Option, - #[structopt(short, long, help = "Show verbose logging")] - verbose: bool, - }, + Fetch(FetchCommands), + + #[structopt(name = "chain", about = "Interact with Filecoin blockchain")] + Chain(ChainCommands), + + #[structopt(name = "wallet", about = "Manage wallet")] + Wallet(WalletCommands), } /// Daemon process command line options. diff --git a/forest/src/cli/wallet_cmd.rs b/forest/src/cli/wallet_cmd.rs new file mode 100644 index 000000000000..8414e47833f2 --- /dev/null +++ b/forest/src/cli/wallet_cmd.rs @@ -0,0 +1,11 @@ +// Copyright 2020 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0, MIT + +use structopt::StructOpt; + +#[allow(missing_docs)] +#[derive(Debug, StructOpt)] +pub struct WalletCommands { + #[structopt(long, help = "Generate a new key of the given typ")] + pub new: bool, +} diff --git a/forest/src/subcommand.rs b/forest/src/subcommand.rs index 87cc1f40f442..b69995a1eff7 100644 --- a/forest/src/subcommand.rs +++ b/forest/src/subcommand.rs @@ -2,69 +2,20 @@ // SPDX-License-Identifier: Apache-2.0, MIT use super::cli::Subcommand; -use super::paramfetch::{get_params_default, SectorSizeOpt}; -use fil_types::SectorSize; - -/// Converts a human readable string to a u64 size. -fn ram_to_int(size: &str) -> Result { - // TODO there is no library to do this, but if other sector sizes are supported in future - // this should probably be changed to parse from string to `SectorSize` - let mut trimmed = size.trim_end_matches('B'); - trimmed = trimmed.trim_end_matches('b'); - - match trimmed { - "2048" | "2Ki" | "2ki" => Ok(SectorSize::_2KiB), - "8388608" | "8Mi" | "8mi" => Ok(SectorSize::_8MiB), - "536870912" | "512Mi" | "512mi" => Ok(SectorSize::_512MiB), - "34359738368" | "32Gi" | "32gi" => Ok(SectorSize::_32GiB), - "68719476736" | "64Gi" | "64gi" => Ok(SectorSize::_64GiB), - _ => Err(format!( - "Failed to parse: {}. Must be a valid sector size", - size - )), - } -} /// Process CLI subcommand pub(super) async fn process(command: Subcommand) { match command { - Subcommand::FetchParams { - params_size, - all, - keys, - verbose, - } => { - let sizes = if all { - SectorSizeOpt::All - } else if let Some(size) = params_size { - let sector_size = ram_to_int(&size).unwrap(); - SectorSizeOpt::Size(sector_size) - } else if keys { - SectorSizeOpt::Keys - } else { - panic!( - "Sector size option must be chosen. Choose between --all, --keys, or " - ); - }; - - get_params_default(sizes, verbose).await.unwrap(); + Subcommand::Fetch(cmd) => { + // TODO should pass in config? + cmd.run().await; + } + Subcommand::Chain(cmd) => { + // TODO should pass in config? + cmd.run().await; + } + Subcommand::Wallet(_cmd) => { + // do something } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn ram_str_conversions() { - assert_eq!(ram_to_int("2048").unwrap(), SectorSize::_2KiB); - assert_eq!(ram_to_int("2048B").unwrap(), SectorSize::_2KiB); - assert_eq!(ram_to_int("2kib").unwrap(), SectorSize::_2KiB); - assert_eq!(ram_to_int("8Mib").unwrap(), SectorSize::_8MiB); - assert_eq!(ram_to_int("512MiB").unwrap(), SectorSize::_512MiB); - assert_eq!(ram_to_int("32Gi").unwrap(), SectorSize::_32GiB); - assert_eq!(ram_to_int("32GiB").unwrap(), SectorSize::_32GiB); - assert_eq!(ram_to_int("64Gib").unwrap(), SectorSize::_64GiB); } } diff --git a/node/rpc-client/Cargo.toml b/node/rpc-client/Cargo.toml new file mode 100644 index 000000000000..8de399f12685 --- /dev/null +++ b/node/rpc-client/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "rpc-client" +version = "0.1.0" +authors = ["ChainSafe Systems "] +edition = "2018" + +[dependencies] +jsonrpsee = "0.1.0" +blocks = { package = "forest_blocks", path = "../../blockchain/blocks", features = ["json"] } +message = { package = "forest_message", path = "../../vm/message", features = ["json"] } +serde_json = "1.0" +jsonrpc-v2 = { version = "0.5.2", features = ["easy-errors", "macros"] } +log = "0.4.8" +crypto = { package = "forest_crypto", path = "../../crypto", features = ["json"] } +wallet = {package = "key_management", path = "../../key_management", features = ["json"] } \ No newline at end of file diff --git a/node/rpc-client/src/chain_ops.rs b/node/rpc-client/src/chain_ops.rs new file mode 100644 index 000000000000..da12bd091ab3 --- /dev/null +++ b/node/rpc-client/src/chain_ops.rs @@ -0,0 +1,48 @@ +// Copyright 2020 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0, MIT + +#![allow(unused_variables)] +#![allow(dead_code)] + +use super::client::Filecoin; +use blocks::{ + tipset_json::TipsetJson, header::json::BlockHeaderJson +}; +use message::{ + unsigned_message::{json::UnsignedMessageJson}, +}; +use jsonrpc_v2::{Error as JsonRpcError}; +use jsonrpsee::raw::RawClient; +use jsonrpsee::transport::http::HttpTransportClient; + +const URL: &str = "http://127.0.0.1:1234/rpc/v0"; + +pub async fn get_genesis() -> Result { + let mut client = RawClient::new(HttpTransportClient::new(URL)); + Ok(Filecoin::chain_get_genesis(&mut client) + .await?) +} + +pub async fn get_messages(cid: String) -> Result { + let mut client = RawClient::new(HttpTransportClient::new(URL)); + Ok(Filecoin::chain_get_messages(&mut client, cid) + .await?) +} + +pub async fn get_head() -> Result { + let mut client = RawClient::new(HttpTransportClient::new(URL)); + Ok(Filecoin::chain_get_head(&mut client) + .await?) +} + +pub async fn get_block(cid: String) -> Result { + let mut client = RawClient::new(HttpTransportClient::new(URL)); + Ok(Filecoin::chain_get_block(&mut client, cid) + .await?) +} + +pub async fn read_obj(cid: String) -> Result, JsonRpcError> { + let mut client = RawClient::new(HttpTransportClient::new(URL)); + Ok(Filecoin::chain_read_obj(&mut client, cid) + .await?) +} \ No newline at end of file diff --git a/node/rpc-client/src/client.rs b/node/rpc-client/src/client.rs new file mode 100644 index 000000000000..c7cb2e9dd569 --- /dev/null +++ b/node/rpc-client/src/client.rs @@ -0,0 +1,78 @@ +// Copyright 2020 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0, MIT + +#![allow(unused_imports)] +#![allow(unused_variables)] +#![allow(dead_code)] + +use jsonrpsee::raw::RawClient; +use jsonrpsee::transport::http::HttpTransportClient; +use jsonrpsee::transport::TransportClient; +use jsonrpc_v2::{Error as JsonRpcError}; +use blocks::{ + tipset_json::TipsetJson, header::json::BlockHeaderJson +}; +use message::{ + unsigned_message::{json::UnsignedMessageJson}, +}; +use wallet::{json::KeyInfoJson}; +use crypto::signature::json::SignatureJson; + +// TODO return result with json err +jsonrpsee::rpc_api! { + pub Filecoin { + /// Chain + #[rpc(method = "Filecoin.ChainGetGenesis")] + fn chain_get_genesis() -> TipsetJson; + + #[rpc(method = "Filecoin.ChainGetMessage")] + fn chain_get_messages(cid: String) -> UnsignedMessageJson; + + #[rpc(method = "Filecoin.ChainHead")] + fn chain_get_head() -> TipsetJson; + + #[rpc(method = "Filecoin.ChainGetBlock")] + fn chain_get_block(cid: String) -> BlockHeaderJson; + + #[rpc(method = "Filecoin.ChainGetObj")] + fn chain_read_obj(cid: String) -> Vec; + + /// Wallet + #[rpc(method = "Filecoin.WalletNew")] + fn wallet_new() -> String; + + #[rpc(method = "Filecoin.WalletList")] + fn wallet_list() -> Vec; + + #[rpc(method = "Filecoin.WalletBalance")] + fn wallet_balance() -> String; + + #[rpc(method = "Filecoin.WalletSetDefault")] + fn wallet_set_default(); + + #[rpc(method = "Filecoin.WalletDefault")] + fn wallet_default() -> String; + + #[rpc(method = "Filecoin.WalletSign")] + fn wallet_sign() -> SignatureJson; + + #[rpc(method = "Filecoin.WalletVerify")] + fn wallet_verify() -> bool; + + #[rpc(method = "Filecoin.WalletImport")] + fn wallet_import() -> String; + + #[rpc(method = "Filecoin.WalletExport")] + fn wallet_export() -> KeyInfoJson; + } +} + +const URL: &str = "http://127.0.0.1:1234/rpc/v0"; + +// TODO pass config for url +// pub fn new_client() -> RawClient +// where +// R: TransportClient +// { +// RawClient::new(HttpTransportClient::new(URL)) +// } \ No newline at end of file diff --git a/node/rpc-client/src/lib.rs b/node/rpc-client/src/lib.rs new file mode 100644 index 000000000000..e166a0779895 --- /dev/null +++ b/node/rpc-client/src/lib.rs @@ -0,0 +1,10 @@ +// Copyright 2020 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0, MIT + +mod chain_ops; +mod wallet_ops; +mod client; + +pub use self::chain_ops::*; +pub use self::wallet_ops::*; +pub use self::client::*; diff --git a/node/rpc-client/src/wallet_ops.rs b/node/rpc-client/src/wallet_ops.rs new file mode 100644 index 000000000000..5e18f0491904 --- /dev/null +++ b/node/rpc-client/src/wallet_ops.rs @@ -0,0 +1,65 @@ +// Copyright 2020 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0, MIT + +use super::client::Filecoin; +use jsonrpc_v2::{Error as JsonRpcError}; +use jsonrpsee::raw::RawClient; +use jsonrpsee::transport::http::HttpTransportClient; +use crypto::signature::json::SignatureJson; +use wallet::{json::KeyInfoJson}; + +const URL: &str = "http://127.0.0.1:1234/rpc/v0"; + +pub async fn new() -> Result { + let mut client = RawClient::new(HttpTransportClient::new(URL)); + Ok(Filecoin::wallet_new(&mut client) + .await?) +} + +pub async fn list() -> Result, JsonRpcError> { + let mut client = RawClient::new(HttpTransportClient::new(URL)); + Ok(Filecoin::wallet_list(&mut client) + .await?) +} + +pub async fn balance() -> Result { + let mut client = RawClient::new(HttpTransportClient::new(URL)); + Ok(Filecoin::wallet_balance(&mut client) + .await?) +} + +pub async fn set_default() -> Result<(), JsonRpcError> { + let mut client = RawClient::new(HttpTransportClient::new(URL)); + Ok(Filecoin::wallet_set_default(&mut client) + .await?) +} + +pub async fn default() -> Result { + let mut client = RawClient::new(HttpTransportClient::new(URL)); + Ok(Filecoin::wallet_default(&mut client) + .await?) +} + +pub async fn sign() -> Result { + let mut client = RawClient::new(HttpTransportClient::new(URL)); + Ok(Filecoin::wallet_sign(&mut client) + .await?) +} + +pub async fn verify() -> Result { + let mut client = RawClient::new(HttpTransportClient::new(URL)); + Ok(Filecoin::wallet_verify(&mut client) + .await?) +} + +pub async fn import() -> Result { + let mut client = RawClient::new(HttpTransportClient::new(URL)); + Ok(Filecoin::wallet_import(&mut client) + .await?) +} + +pub async fn export() -> Result { + let mut client = RawClient::new(HttpTransportClient::new(URL)); + Ok(Filecoin::wallet_export(&mut client) + .await?) +} \ No newline at end of file diff --git a/vm/message/src/unsigned_message.rs b/vm/message/src/unsigned_message.rs index 980b19586d1f..ba71d23d6289 100644 --- a/vm/message/src/unsigned_message.rs +++ b/vm/message/src/unsigned_message.rs @@ -155,7 +155,7 @@ pub mod json { use serde::de; /// Wrapper for serializing and deserializing a UnsignedMessage from JSON. - #[derive(Deserialize, Serialize)] + #[derive(Deserialize, Serialize, Debug)] #[serde(transparent)] pub struct UnsignedMessageJson(#[serde(with = "self")] pub UnsignedMessage); From ef610e5a4add0e8ae80c1d5f4f6a22870df619fc Mon Sep 17 00:00:00 2001 From: Dustin Brickwood Date: Fri, 24 Jul 2020 15:31:32 -0500 Subject: [PATCH 02/14] hot fix --- forest/src/cli/chain_cmd.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/forest/src/cli/chain_cmd.rs b/forest/src/cli/chain_cmd.rs index 6ac5b584e888..50d48b3c98ff 100644 --- a/forest/src/cli/chain_cmd.rs +++ b/forest/src/cli/chain_cmd.rs @@ -20,21 +20,21 @@ pub struct ChainCommands { value_name = "CID", help = "Read the raw bytes of an object" )] - pub read_obj: String, + pub read_obj: Option, #[structopt( long = "message", value_name = "CIDs", help = "Retrieve and print messages by CIDs" )] - pub messages: String, + pub messages: Option, #[structopt( long = "block", value_name = "CID", help = "Retrieve a block and print its details" )] - pub block: String, + pub block: Option, } impl ChainCommands { From 8673926b83301fa0ca4917d327ed65790450c900 Mon Sep 17 00:00:00 2001 From: Dustin Brickwood Date: Tue, 28 Jul 2020 08:57:10 -0500 Subject: [PATCH 03/14] removed wallet commands for separate PR --- Cargo.lock | 1 + forest/Cargo.toml | 2 +- forest/src/cli/chain_cmd.rs | 20 +++++++--- forest/src/cli/mod.rs | 5 --- forest/src/cli/wallet_cmd.rs | 11 ------ forest/src/subcommand.rs | 3 -- ipld/cid/src/json.rs | 2 +- node/rpc-client/Cargo.toml | 1 + node/rpc-client/src/chain_ops.rs | 9 +++-- node/rpc-client/src/client.rs | 33 ++-------------- node/rpc-client/src/lib.rs | 2 - node/rpc-client/src/wallet_ops.rs | 65 ------------------------------- node/rpc/src/chain_api.rs | 2 +- 13 files changed, 28 insertions(+), 128 deletions(-) delete mode 100644 forest/src/cli/wallet_cmd.rs delete mode 100644 node/rpc-client/src/wallet_ops.rs diff --git a/Cargo.lock b/Cargo.lock index d7bfd0c27ce8..37c423c06606 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5573,6 +5573,7 @@ name = "rpc-client" version = "0.1.0" dependencies = [ "forest_blocks", + "forest_cid", "forest_crypto", "forest_message", "jsonrpc-v2", diff --git a/forest/Cargo.toml b/forest/Cargo.toml index fbf804c7463c..aae140e9d59f 100644 --- a/forest/Cargo.toml +++ b/forest/Cargo.toml @@ -18,7 +18,7 @@ pretty_env_logger = "0.4.0" ctrlc = "3.1.4" chain_sync = { path = "../blockchain/chain_sync" } state_manager = { path = "../blockchain/state_manager" } -cid = { package = "forest_cid", path = "../ipld/cid" } +cid = { package = "forest_cid", path = "../ipld/cid", features = ["json"] } forest_car = { path = "../ipld/car" } blocks = { package = "forest_blocks", path = "../blockchain/blocks" } ipld_blockstore = { path = "../ipld/blockstore", features = ["rocksdb"] } diff --git a/forest/src/cli/chain_cmd.rs b/forest/src/cli/chain_cmd.rs index 50d48b3c98ff..b47af03c9d16 100644 --- a/forest/src/cli/chain_cmd.rs +++ b/forest/src/cli/chain_cmd.rs @@ -1,10 +1,10 @@ // Copyright 2020 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -use rpc_client::{get_genesis, get_head}; +use rpc_client::{genesis, head, messages}; +use cid::Cid; use structopt::StructOpt; -#[allow(missing_docs)] #[derive(Debug, StructOpt)] pub struct ChainCommands { /// Prints out the genesis tipset @@ -15,6 +15,8 @@ pub struct ChainCommands { #[structopt(long, help = "Print chain head")] pub head: bool, + /// Reads and prints out ipld nodes referenced by the specified CID from chain + /// blockstore and returns raw bytes #[structopt( long = "read-obj", value_name = "CID", @@ -22,13 +24,16 @@ pub struct ChainCommands { )] pub read_obj: Option, + /// Reads and prints out a message referenced by the specified CID from the + /// chain blockstore. #[structopt( long = "message", value_name = "CIDs", - help = "Retrieve and print messages by CIDs" + help = "Retrieves and prints messages by CIDs" )] pub messages: Option, + /// Retrieves and prints out the block specified by the given CID #[structopt( long = "block", value_name = "CID", @@ -40,12 +45,17 @@ pub struct ChainCommands { impl ChainCommands { pub async fn run(&self) { if self.genesis { - let gen = get_genesis().await; + let gen = genesis().await; println!("{}", serde_json::to_string_pretty(&gen).unwrap()); } if self.head { - let head = get_head().await; + let head = head().await; println!("{}", serde_json::to_string_pretty(&head).unwrap()); } + if let Some(params) = &self.messages { + let cid: Cid = params.parse().unwrap(); + let msg = messages(cid).await; + println!("{}", serde_json::to_string_pretty(&msg).unwrap()); + } } } diff --git a/forest/src/cli/mod.rs b/forest/src/cli/mod.rs index 5d442c08e83c..ff29da445c02 100644 --- a/forest/src/cli/mod.rs +++ b/forest/src/cli/mod.rs @@ -5,13 +5,11 @@ mod chain_cmd; mod config; mod fetch_params_cmd; mod genesis; -mod wallet_cmd; pub(super) use self::chain_cmd::ChainCommands; pub use self::config::Config; pub(super) use self::fetch_params_cmd::FetchCommands; pub(super) use self::genesis::initialize_genesis; -pub(super) use self::wallet_cmd::WalletCommands; use std::cell::RefCell; use std::io; @@ -48,9 +46,6 @@ pub enum Subcommand { #[structopt(name = "chain", about = "Interact with Filecoin blockchain")] Chain(ChainCommands), - - #[structopt(name = "wallet", about = "Manage wallet")] - Wallet(WalletCommands), } /// Daemon process command line options. diff --git a/forest/src/cli/wallet_cmd.rs b/forest/src/cli/wallet_cmd.rs deleted file mode 100644 index 8414e47833f2..000000000000 --- a/forest/src/cli/wallet_cmd.rs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2020 ChainSafe Systems -// SPDX-License-Identifier: Apache-2.0, MIT - -use structopt::StructOpt; - -#[allow(missing_docs)] -#[derive(Debug, StructOpt)] -pub struct WalletCommands { - #[structopt(long, help = "Generate a new key of the given typ")] - pub new: bool, -} diff --git a/forest/src/subcommand.rs b/forest/src/subcommand.rs index b69995a1eff7..a2ac93240ebb 100644 --- a/forest/src/subcommand.rs +++ b/forest/src/subcommand.rs @@ -14,8 +14,5 @@ pub(super) async fn process(command: Subcommand) { // TODO should pass in config? cmd.run().await; } - Subcommand::Wallet(_cmd) => { - // do something - } } } diff --git a/ipld/cid/src/json.rs b/ipld/cid/src/json.rs index bd89c29a8eca..fafee20410ef 100644 --- a/ipld/cid/src/json.rs +++ b/ipld/cid/src/json.rs @@ -5,7 +5,7 @@ use super::Cid; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; /// Wrapper for serializing and deserializing a Cid from JSON. -#[derive(Deserialize, Serialize, Clone)] +#[derive(Deserialize, Serialize, Clone, Debug)] #[serde(transparent)] pub struct CidJson(#[serde(with = "self")] pub Cid); diff --git a/node/rpc-client/Cargo.toml b/node/rpc-client/Cargo.toml index 8de399f12685..538e41af7174 100644 --- a/node/rpc-client/Cargo.toml +++ b/node/rpc-client/Cargo.toml @@ -6,6 +6,7 @@ edition = "2018" [dependencies] jsonrpsee = "0.1.0" +cid = { package = "forest_cid", path = "../../ipld/cid", features = ["json"] } blocks = { package = "forest_blocks", path = "../../blockchain/blocks", features = ["json"] } message = { package = "forest_message", path = "../../vm/message", features = ["json"] } serde_json = "1.0" diff --git a/node/rpc-client/src/chain_ops.rs b/node/rpc-client/src/chain_ops.rs index da12bd091ab3..59b8d3806043 100644 --- a/node/rpc-client/src/chain_ops.rs +++ b/node/rpc-client/src/chain_ops.rs @@ -5,6 +5,7 @@ #![allow(dead_code)] use super::client::Filecoin; +use cid::{json::CidJson, Cid}; use blocks::{ tipset_json::TipsetJson, header::json::BlockHeaderJson }; @@ -17,25 +18,25 @@ use jsonrpsee::transport::http::HttpTransportClient; const URL: &str = "http://127.0.0.1:1234/rpc/v0"; -pub async fn get_genesis() -> Result { +pub async fn genesis() -> Result { let mut client = RawClient::new(HttpTransportClient::new(URL)); Ok(Filecoin::chain_get_genesis(&mut client) .await?) } -pub async fn get_messages(cid: String) -> Result { +pub async fn messages(cid: Cid) -> Result { let mut client = RawClient::new(HttpTransportClient::new(URL)); Ok(Filecoin::chain_get_messages(&mut client, cid) .await?) } -pub async fn get_head() -> Result { +pub async fn head() -> Result { let mut client = RawClient::new(HttpTransportClient::new(URL)); Ok(Filecoin::chain_get_head(&mut client) .await?) } -pub async fn get_block(cid: String) -> Result { +pub async fn block(cid: String) -> Result { let mut client = RawClient::new(HttpTransportClient::new(URL)); Ok(Filecoin::chain_get_block(&mut client, cid) .await?) diff --git a/node/rpc-client/src/client.rs b/node/rpc-client/src/client.rs index c7cb2e9dd569..5a63bdebd5b4 100644 --- a/node/rpc-client/src/client.rs +++ b/node/rpc-client/src/client.rs @@ -9,6 +9,7 @@ use jsonrpsee::raw::RawClient; use jsonrpsee::transport::http::HttpTransportClient; use jsonrpsee::transport::TransportClient; use jsonrpc_v2::{Error as JsonRpcError}; +use cid::{json::CidJson, Cid}; use blocks::{ tipset_json::TipsetJson, header::json::BlockHeaderJson }; @@ -18,7 +19,7 @@ use message::{ use wallet::{json::KeyInfoJson}; use crypto::signature::json::SignatureJson; -// TODO return result with json err +// TODO return result with json err? jsonrpsee::rpc_api! { pub Filecoin { /// Chain @@ -26,7 +27,7 @@ jsonrpsee::rpc_api! { fn chain_get_genesis() -> TipsetJson; #[rpc(method = "Filecoin.ChainGetMessage")] - fn chain_get_messages(cid: String) -> UnsignedMessageJson; + fn chain_get_messages(cid: Cid) -> UnsignedMessageJson; #[rpc(method = "Filecoin.ChainHead")] fn chain_get_head() -> TipsetJson; @@ -36,34 +37,6 @@ jsonrpsee::rpc_api! { #[rpc(method = "Filecoin.ChainGetObj")] fn chain_read_obj(cid: String) -> Vec; - - /// Wallet - #[rpc(method = "Filecoin.WalletNew")] - fn wallet_new() -> String; - - #[rpc(method = "Filecoin.WalletList")] - fn wallet_list() -> Vec; - - #[rpc(method = "Filecoin.WalletBalance")] - fn wallet_balance() -> String; - - #[rpc(method = "Filecoin.WalletSetDefault")] - fn wallet_set_default(); - - #[rpc(method = "Filecoin.WalletDefault")] - fn wallet_default() -> String; - - #[rpc(method = "Filecoin.WalletSign")] - fn wallet_sign() -> SignatureJson; - - #[rpc(method = "Filecoin.WalletVerify")] - fn wallet_verify() -> bool; - - #[rpc(method = "Filecoin.WalletImport")] - fn wallet_import() -> String; - - #[rpc(method = "Filecoin.WalletExport")] - fn wallet_export() -> KeyInfoJson; } } diff --git a/node/rpc-client/src/lib.rs b/node/rpc-client/src/lib.rs index e166a0779895..9cc7ea8b5de5 100644 --- a/node/rpc-client/src/lib.rs +++ b/node/rpc-client/src/lib.rs @@ -2,9 +2,7 @@ // SPDX-License-Identifier: Apache-2.0, MIT mod chain_ops; -mod wallet_ops; mod client; pub use self::chain_ops::*; -pub use self::wallet_ops::*; pub use self::client::*; diff --git a/node/rpc-client/src/wallet_ops.rs b/node/rpc-client/src/wallet_ops.rs deleted file mode 100644 index 5e18f0491904..000000000000 --- a/node/rpc-client/src/wallet_ops.rs +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2020 ChainSafe Systems -// SPDX-License-Identifier: Apache-2.0, MIT - -use super::client::Filecoin; -use jsonrpc_v2::{Error as JsonRpcError}; -use jsonrpsee::raw::RawClient; -use jsonrpsee::transport::http::HttpTransportClient; -use crypto::signature::json::SignatureJson; -use wallet::{json::KeyInfoJson}; - -const URL: &str = "http://127.0.0.1:1234/rpc/v0"; - -pub async fn new() -> Result { - let mut client = RawClient::new(HttpTransportClient::new(URL)); - Ok(Filecoin::wallet_new(&mut client) - .await?) -} - -pub async fn list() -> Result, JsonRpcError> { - let mut client = RawClient::new(HttpTransportClient::new(URL)); - Ok(Filecoin::wallet_list(&mut client) - .await?) -} - -pub async fn balance() -> Result { - let mut client = RawClient::new(HttpTransportClient::new(URL)); - Ok(Filecoin::wallet_balance(&mut client) - .await?) -} - -pub async fn set_default() -> Result<(), JsonRpcError> { - let mut client = RawClient::new(HttpTransportClient::new(URL)); - Ok(Filecoin::wallet_set_default(&mut client) - .await?) -} - -pub async fn default() -> Result { - let mut client = RawClient::new(HttpTransportClient::new(URL)); - Ok(Filecoin::wallet_default(&mut client) - .await?) -} - -pub async fn sign() -> Result { - let mut client = RawClient::new(HttpTransportClient::new(URL)); - Ok(Filecoin::wallet_sign(&mut client) - .await?) -} - -pub async fn verify() -> Result { - let mut client = RawClient::new(HttpTransportClient::new(URL)); - Ok(Filecoin::wallet_verify(&mut client) - .await?) -} - -pub async fn import() -> Result { - let mut client = RawClient::new(HttpTransportClient::new(URL)); - Ok(Filecoin::wallet_import(&mut client) - .await?) -} - -pub async fn export() -> Result { - let mut client = RawClient::new(HttpTransportClient::new(URL)); - Ok(Filecoin::wallet_export(&mut client) - .await?) -} \ No newline at end of file diff --git a/node/rpc/src/chain_api.rs b/node/rpc/src/chain_api.rs index 35756e83ae75..e2d836b5aaea 100644 --- a/node/rpc/src/chain_api.rs +++ b/node/rpc/src/chain_api.rs @@ -145,7 +145,7 @@ pub(crate) async fn chain_head( where DB: BlockStore + Send + Sync + 'static, KS: KeyStore + Send + Sync + 'static, -{ +{ let heaviest = chain::get_heaviest_tipset(data.store.as_ref())?.ok_or("can't find heaviest tipset")?; Ok(TipsetJson(heaviest)) From 3b301fd894ec97f400573d0bd145853b77cbe15d Mon Sep 17 00:00:00 2001 From: Dustin Brickwood Date: Tue, 28 Jul 2020 16:34:15 -0500 Subject: [PATCH 04/14] Improved subcommands --- forest/src/cli/chain_cmd.rs | 102 ++++++++++++++++++------------- forest/src/subcommand.rs | 2 - node/rpc-client/src/chain_ops.rs | 57 +++++++---------- node/rpc-client/src/client.rs | 42 +++++-------- node/rpc/src/chain_api.rs | 2 +- 5 files changed, 101 insertions(+), 104 deletions(-) diff --git a/forest/src/cli/chain_cmd.rs b/forest/src/cli/chain_cmd.rs index b47af03c9d16..488f2328ab36 100644 --- a/forest/src/cli/chain_cmd.rs +++ b/forest/src/cli/chain_cmd.rs @@ -1,61 +1,81 @@ // Copyright 2020 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -use rpc_client::{genesis, head, messages}; use cid::Cid; +use rpc_client::{block, genesis, head, messages, new_client, read_obj}; use structopt::StructOpt; #[derive(Debug, StructOpt)] -pub struct ChainCommands { +pub enum ChainCommands { + /// Retrieves and prints out the block specified by the given CID + #[structopt(about = " Retrieve a block and print its details")] + Block { + #[structopt(help = "Input a valid CID")] + cid: String, + }, + /// Prints out the genesis tipset - #[structopt(long, help = "Prints genesis tipset")] - pub genesis: bool, + #[structopt(about = "Prints genesis tipset", help = "Prints genesis tipset")] + Genesis, /// Prints out the canonical head of the chain - #[structopt(long, help = "Print chain head")] - pub head: bool, - - /// Reads and prints out ipld nodes referenced by the specified CID from chain - /// blockstore and returns raw bytes - #[structopt( - long = "read-obj", - value_name = "CID", - help = "Read the raw bytes of an object" - )] - pub read_obj: Option, + #[structopt(about = "Print chain head", help = "Print chain head")] + Head, /// Reads and prints out a message referenced by the specified CID from the - /// chain blockstore. - #[structopt( - long = "message", - value_name = "CIDs", - help = "Retrieves and prints messages by CIDs" - )] - pub messages: Option, + /// chain blockstore + #[structopt(about = " Retrieves and prints messages by CIDs")] + Message { + #[structopt(help = "Input a valid CID")] + cid: String, + }, - /// Retrieves and prints out the block specified by the given CID - #[structopt( - long = "block", - value_name = "CID", - help = "Retrieve a block and print its details" - )] - pub block: Option, + /// Reads and prints out ipld nodes referenced by the specified CID from chain + /// blockstore and returns raw bytes + #[structopt(about = " Read the raw bytes of an object")] + ReadObj { + #[structopt(help = "Input a valid CID")] + cid: String, + }, } impl ChainCommands { pub async fn run(&self) { - if self.genesis { - let gen = genesis().await; - println!("{}", serde_json::to_string_pretty(&gen).unwrap()); - } - if self.head { - let head = head().await; - println!("{}", serde_json::to_string_pretty(&head).unwrap()); - } - if let Some(params) = &self.messages { - let cid: Cid = params.parse().unwrap(); - let msg = messages(cid).await; - println!("{}", serde_json::to_string_pretty(&msg).unwrap()); + // TODO handle cli config + match self { + Self::Block { cid } => { + let cid: Cid = cid.parse().unwrap(); + let mut client = new_client(); + + let blk = block(client, cid).await; + println!("{}", serde_json::to_string_pretty(&blk).unwrap()); + } + Self::Genesis => { + let mut client = new_client(); + + let gen = genesis(client).await; + println!("{}", serde_json::to_string_pretty(&gen).unwrap()); + } + Self::Head => { + let mut client = new_client(); + + let head = head(client).await; + println!("{}", serde_json::to_string_pretty(&head).unwrap()); + } + Self::Message { cid } => { + let cid: Cid = cid.parse().unwrap(); + let mut client = new_client(); + + let msg = messages(client, cid).await; + println!("{}", serde_json::to_string_pretty(&msg).unwrap()); + } + Self::ReadObj { cid } => { + let cid: Cid = cid.parse().unwrap(); + let mut client = new_client(); + + let obj = read_obj(client, cid).await; + println!("{}", serde_json::to_string_pretty(&obj).unwrap()); + } } } } diff --git a/forest/src/subcommand.rs b/forest/src/subcommand.rs index a2ac93240ebb..e894847ce581 100644 --- a/forest/src/subcommand.rs +++ b/forest/src/subcommand.rs @@ -7,11 +7,9 @@ use super::cli::Subcommand; pub(super) async fn process(command: Subcommand) { match command { Subcommand::Fetch(cmd) => { - // TODO should pass in config? cmd.run().await; } Subcommand::Chain(cmd) => { - // TODO should pass in config? cmd.run().await; } } diff --git a/node/rpc-client/src/chain_ops.rs b/node/rpc-client/src/chain_ops.rs index 59b8d3806043..5111155fb44e 100644 --- a/node/rpc-client/src/chain_ops.rs +++ b/node/rpc-client/src/chain_ops.rs @@ -1,49 +1,38 @@ // Copyright 2020 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -#![allow(unused_variables)] -#![allow(dead_code)] - use super::client::Filecoin; +use blocks::{header::json::BlockHeaderJson, tipset_json::TipsetJson}; use cid::{json::CidJson, Cid}; -use blocks::{ - tipset_json::TipsetJson, header::json::BlockHeaderJson -}; -use message::{ - unsigned_message::{json::UnsignedMessageJson}, -}; -use jsonrpc_v2::{Error as JsonRpcError}; +use jsonrpc_v2::Error as JsonRpcError; use jsonrpsee::raw::RawClient; -use jsonrpsee::transport::http::HttpTransportClient; - -const URL: &str = "http://127.0.0.1:1234/rpc/v0"; +use jsonrpsee::transport::http::HttpTransportClient as HTC; +use message::unsigned_message::json::UnsignedMessageJson; -pub async fn genesis() -> Result { - let mut client = RawClient::new(HttpTransportClient::new(URL)); - Ok(Filecoin::chain_get_genesis(&mut client) - .await?) +/// Returns a block with specified CID fom chain via RPC +pub async fn block(mut client: RawClient, cid: Cid) -> Result { + Ok(Filecoin::chain_get_block(&mut client, CidJson(cid)).await?) } -pub async fn messages(cid: Cid) -> Result { - let mut client = RawClient::new(HttpTransportClient::new(URL)); - Ok(Filecoin::chain_get_messages(&mut client, cid) - .await?) +/// Returns genesis tipset from chain via RPC +pub async fn genesis(mut client: RawClient) -> Result { + Ok(Filecoin::chain_get_genesis(&mut client).await?) } -pub async fn head() -> Result { - let mut client = RawClient::new(HttpTransportClient::new(URL)); - Ok(Filecoin::chain_get_head(&mut client) - .await?) +/// Returns canonical head of the chain via RPC +pub async fn head(mut client: RawClient) -> Result { + Ok(Filecoin::chain_get_head(&mut client).await?) } -pub async fn block(cid: String) -> Result { - let mut client = RawClient::new(HttpTransportClient::new(URL)); - Ok(Filecoin::chain_get_block(&mut client, cid) - .await?) +/// Returns messages with specified CID from chain via RPC +pub async fn messages( + mut client: RawClient, + cid: Cid, +) -> Result { + Ok(Filecoin::chain_get_messages(&mut client, CidJson(cid)).await?) } -pub async fn read_obj(cid: String) -> Result, JsonRpcError> { - let mut client = RawClient::new(HttpTransportClient::new(URL)); - Ok(Filecoin::chain_read_obj(&mut client, cid) - .await?) -} \ No newline at end of file +/// Returns IPLD node with specified CID from chain via RPC +pub async fn read_obj(mut client: RawClient, cid: Cid) -> Result, JsonRpcError> { + Ok(Filecoin::chain_read_obj(&mut client, CidJson(cid)).await?) +} diff --git a/node/rpc-client/src/client.rs b/node/rpc-client/src/client.rs index 5a63bdebd5b4..82c7de636638 100644 --- a/node/rpc-client/src/client.rs +++ b/node/rpc-client/src/client.rs @@ -5,47 +5,37 @@ #![allow(unused_variables)] #![allow(dead_code)] +use blocks::{header::json::BlockHeaderJson, tipset_json::TipsetJson}; +use cid::json::CidJson; use jsonrpsee::raw::RawClient; use jsonrpsee::transport::http::HttpTransportClient; use jsonrpsee::transport::TransportClient; -use jsonrpc_v2::{Error as JsonRpcError}; -use cid::{json::CidJson, Cid}; -use blocks::{ - tipset_json::TipsetJson, header::json::BlockHeaderJson -}; -use message::{ - unsigned_message::{json::UnsignedMessageJson}, -}; -use wallet::{json::KeyInfoJson}; -use crypto::signature::json::SignatureJson; - -// TODO return result with json err? +use message::unsigned_message::json::UnsignedMessageJson; + jsonrpsee::rpc_api! { pub Filecoin { /// Chain + #[rpc(method = "Filecoin.ChainGetBlock", positional_params)] + fn chain_get_block(cid: CidJson) -> BlockHeaderJson; + #[rpc(method = "Filecoin.ChainGetGenesis")] fn chain_get_genesis() -> TipsetJson; - #[rpc(method = "Filecoin.ChainGetMessage")] - fn chain_get_messages(cid: Cid) -> UnsignedMessageJson; - #[rpc(method = "Filecoin.ChainHead")] fn chain_get_head() -> TipsetJson; - #[rpc(method = "Filecoin.ChainGetBlock")] - fn chain_get_block(cid: String) -> BlockHeaderJson; + #[rpc(method = "Filecoin.ChainGetMessage", positional_params)] + fn chain_get_messages(cid: CidJson) -> UnsignedMessageJson; - #[rpc(method = "Filecoin.ChainGetObj")] - fn chain_read_obj(cid: String) -> Vec; + #[rpc(method = "Filecoin.ChainGetObj", positional_params)] + fn chain_read_obj(cid: CidJson) -> Vec; } } +// TODO need to handle dynamic port const URL: &str = "http://127.0.0.1:1234/rpc/v0"; -// TODO pass config for url -// pub fn new_client() -> RawClient -// where -// R: TransportClient -// { -// RawClient::new(HttpTransportClient::new(URL)) -// } \ No newline at end of file +// TODO pass config for URL +pub fn new_client() -> RawClient { + RawClient::new(HttpTransportClient::new(URL)) +} diff --git a/node/rpc/src/chain_api.rs b/node/rpc/src/chain_api.rs index e2d836b5aaea..35756e83ae75 100644 --- a/node/rpc/src/chain_api.rs +++ b/node/rpc/src/chain_api.rs @@ -145,7 +145,7 @@ pub(crate) async fn chain_head( where DB: BlockStore + Send + Sync + 'static, KS: KeyStore + Send + Sync + 'static, -{ +{ let heaviest = chain::get_heaviest_tipset(data.store.as_ref())?.ok_or("can't find heaviest tipset")?; Ok(TipsetJson(heaviest)) From af6df3241d1b4d1905a1f8064e089858e901a267 Mon Sep 17 00:00:00 2001 From: Dustin Brickwood Date: Tue, 28 Jul 2020 17:08:20 -0500 Subject: [PATCH 05/14] ignore clippy warning from lib macro --- forest/src/cli/wallet_cmd.rs | 81 +++++++++++++++++++++++++++++++ node/rpc-client/src/client.rs | 4 +- node/rpc-client/src/wallet_ops.rs | 64 ++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 forest/src/cli/wallet_cmd.rs create mode 100644 node/rpc-client/src/wallet_ops.rs diff --git a/forest/src/cli/wallet_cmd.rs b/forest/src/cli/wallet_cmd.rs new file mode 100644 index 000000000000..e2614108eaf7 --- /dev/null +++ b/forest/src/cli/wallet_cmd.rs @@ -0,0 +1,81 @@ +// Copyright 2020 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0, MIT + +use cid::Cid; +use rpc_client::{block, genesis, head, messages, new_client, read_obj}; +use structopt::StructOpt; + +#[derive(Debug, StructOpt)] +pub enum WalletCommands { + /// Retrieves and prints out the block specified by the given CID + #[structopt(about = "Get account balance")] + Balance { + #[structopt(help = "Input a valid address")] + address: String, + }, + + /// Prints out the genesis tipset + #[structopt(about = "Generate a new key of the given type", help = "Generate a new key of the given type")] + New, + + /// Prints out the canonical head of the chain + #[structopt(about = "Print chain head", help = "Print chain head")] + Head, + + /// Reads and prints out a message referenced by the specified CID from the + /// chain blockstore + #[structopt(about = " Retrieves and prints messages by CIDs")] + Message { + #[structopt(help = "Input a valid CID")] + cid: String, + }, + + /// Reads and prints out ipld nodes referenced by the specified CID from chain + /// blockstore and returns raw bytes + #[structopt(about = " Read the raw bytes of an object")] + ReadObj { + #[structopt(help = "Input a valid CID")] + cid: String, + }, +} + +impl WalletCommands { + pub async fn run(&self) { + // TODO handle cli config + match self { + Self::Block { cid } => { + let cid: Cid = cid.parse().unwrap(); + let mut client = new_client(); + + let blk = block(client, cid).await; + println!("{}", serde_json::to_string_pretty(&blk).unwrap()); + } + Self::Genesis => { + let mut client = new_client(); + + let gen = genesis(client).await; + println!("{}", serde_json::to_string_pretty(&gen).unwrap()); + } + Self::Head => { + let mut client = new_client(); + + let head = head(client).await; + println!("{}", serde_json::to_string_pretty(&head).unwrap()); + } + Self::Message { cid } => { + let cid: Cid = cid.parse().unwrap(); + let mut client = new_client(); + + let msg = messages(client, cid).await; + println!("{}", serde_json::to_string_pretty(&msg).unwrap()); + } + Self::ReadObj { cid } => { + let cid: Cid = cid.parse().unwrap(); + let mut client = new_client(); + + let obj = read_obj(client, cid).await; + println!("{}", serde_json::to_string_pretty(&obj).unwrap()); + } + } + } +} diff --git a/node/rpc-client/src/client.rs b/node/rpc-client/src/client.rs index 82c7de636638..fd2a17cfba1e 100644 --- a/node/rpc-client/src/client.rs +++ b/node/rpc-client/src/client.rs @@ -1,9 +1,7 @@ // Copyright 2020 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(dead_code)] +#![allow(clippy::all)] use blocks::{header::json::BlockHeaderJson, tipset_json::TipsetJson}; use cid::json::CidJson; diff --git a/node/rpc-client/src/wallet_ops.rs b/node/rpc-client/src/wallet_ops.rs new file mode 100644 index 000000000000..87a2ca737393 --- /dev/null +++ b/node/rpc-client/src/wallet_ops.rs @@ -0,0 +1,64 @@ +// Copyright 2020 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0, MIT + +use super::client::Filecoin; +use jsonrpc_v2::{Error as JsonRpcError}; +use jsonrpsee::raw::RawClient; +use jsonrpsee::transport::http::HttpTransportClient as HTC; +use crypto::signature::json::SignatureJson; +use wallet::{json::KeyInfoJson}; + +/// Creates a new address in the wallet with the given signature type +pub async fn new(mut client: RawClient) -> Result { + Ok(Filecoin::wallet_new(&mut client) + .await?) +} + +/// Lists all the addresses in the wallet +pub async fn list(mut client: RawClient) -> Result, JsonRpcError> { + Ok(Filecoin::wallet_list(&mut client) + .await?) +} + +/// Returns the balance of the given address at the current head of the chain +pub async fn balance(mut client: RawClient) -> Result { + Ok(Filecoin::wallet_balance(&mut client) + .await?) +} + +/// Marks the given address as as the default one +pub async fn set_default(mut client: RawClient) -> Result<(), JsonRpcError> { + Ok(Filecoin::wallet_set_default(&mut client) + .await?) +} + +/// Returns the address marked as default in the wallet +pub async fn default(mut client: RawClient) -> Result { + Ok(Filecoin::wallet_default(&mut client) + .await?) +} + +/// Signs the given bytes using the given address +pub async fn sign(mut client: RawClient) -> Result { + Ok(Filecoin::wallet_sign(&mut client) + .await?) +} + +/// Takes an address, a signature, and some bytes, and indicates whether the signature is valid. +/// The address does not have to be in the wallet +pub async fn verify(mut client: RawClient) -> Result { + Ok(Filecoin::wallet_verify(&mut client) + .await?) +} + +/// Receives a KeyInfo, which includes a private key, and imports it into the wallet +pub async fn import(mut client: RawClient) -> Result { + Ok(Filecoin::wallet_import(&mut client) + .await?) +} + +/// Returns the private key of an address in the wallet +pub async fn export(mut client: RawClient) -> Result { + Ok(Filecoin::wallet_export(&mut client) + .await?) +} \ No newline at end of file From 21af07467f73452cbd643466a23003f708af8365 Mon Sep 17 00:00:00 2001 From: Dustin Brickwood Date: Wed, 29 Jul 2020 08:11:11 -0500 Subject: [PATCH 06/14] Add clippy all and remove unneeded import --- node/rpc-client/src/client.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/node/rpc-client/src/client.rs b/node/rpc-client/src/client.rs index fd2a17cfba1e..1e66d363d8b3 100644 --- a/node/rpc-client/src/client.rs +++ b/node/rpc-client/src/client.rs @@ -7,7 +7,6 @@ use blocks::{header::json::BlockHeaderJson, tipset_json::TipsetJson}; use cid::json::CidJson; use jsonrpsee::raw::RawClient; use jsonrpsee::transport::http::HttpTransportClient; -use jsonrpsee::transport::TransportClient; use message::unsigned_message::json::UnsignedMessageJson; jsonrpsee::rpc_api! { From c1a70532fb81172d54f9e5deddad1c5c6b6d1d6b Mon Sep 17 00:00:00 2001 From: Dustin Brickwood Date: Wed, 29 Jul 2020 09:11:18 -0500 Subject: [PATCH 07/14] Uwrapping response and mapping json err --- forest/src/cli/chain_cmd.rs | 45 ++++++++++++----- forest/src/cli/wallet_cmd.rs | 81 ------------------------------- node/rpc-client/src/wallet_ops.rs | 64 ------------------------ 3 files changed, 34 insertions(+), 156 deletions(-) delete mode 100644 forest/src/cli/wallet_cmd.rs delete mode 100644 node/rpc-client/src/wallet_ops.rs diff --git a/forest/src/cli/chain_cmd.rs b/forest/src/cli/chain_cmd.rs index 488f2328ab36..ba0f46447f18 100644 --- a/forest/src/cli/chain_cmd.rs +++ b/forest/src/cli/chain_cmd.rs @@ -4,6 +4,8 @@ use cid::Cid; use rpc_client::{block, genesis, head, messages, new_client, read_obj}; use structopt::StructOpt; +use jsonrpc_v2::Error as JsonRpcError; +use log::warn; #[derive(Debug, StructOpt)] pub enum ChainCommands { @@ -45,37 +47,58 @@ impl ChainCommands { match self { Self::Block { cid } => { let cid: Cid = cid.parse().unwrap(); - let mut client = new_client(); + let client = new_client(); - let blk = block(client, cid).await; + let blk = block(client, cid).await.map_err(|e| { + stringify_rpc_err(e); + }).unwrap(); println!("{}", serde_json::to_string_pretty(&blk).unwrap()); } Self::Genesis => { - let mut client = new_client(); + let client = new_client(); - let gen = genesis(client).await; + let gen = genesis(client).await.map_err(|e| { + stringify_rpc_err(e); + }).unwrap(); println!("{}", serde_json::to_string_pretty(&gen).unwrap()); } Self::Head => { - let mut client = new_client(); + let client = new_client(); - let head = head(client).await; - println!("{}", serde_json::to_string_pretty(&head).unwrap()); + let canonical = head(client).await.map_err(|e| { + stringify_rpc_err(e); + }).unwrap(); + println!("{}", serde_json::to_string_pretty(&canonical.0.cids()).unwrap()); } Self::Message { cid } => { let cid: Cid = cid.parse().unwrap(); - let mut client = new_client(); + let client = new_client(); - let msg = messages(client, cid).await; + let msg = messages(client, cid).await.map_err(|e| { + stringify_rpc_err(e); + }).unwrap(); println!("{}", serde_json::to_string_pretty(&msg).unwrap()); } Self::ReadObj { cid } => { let cid: Cid = cid.parse().unwrap(); - let mut client = new_client(); + let client = new_client(); - let obj = read_obj(client, cid).await; + let obj = read_obj(client, cid).await.map_err(|e| { + stringify_rpc_err(e); + }).unwrap(); println!("{}", serde_json::to_string_pretty(&obj).unwrap()); } } } } + +fn stringify_rpc_err(e: JsonRpcError) -> String { + match e { + JsonRpcError::Full { code, message, data } => { + warn!("JSON RPC Error: Code: {} Message: {}", code, message) + }, + JsonRpcError::Provided { code, message, data } => { + warn!("JSON RPC Error: Code: {} Message: {}", code, message) + } + } +} diff --git a/forest/src/cli/wallet_cmd.rs b/forest/src/cli/wallet_cmd.rs deleted file mode 100644 index e2614108eaf7..000000000000 --- a/forest/src/cli/wallet_cmd.rs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2020 ChainSafe Systems -// SPDX-License-Identifier: Apache-2.0, MIT - -use cid::Cid; -use rpc_client::{block, genesis, head, messages, new_client, read_obj}; -use structopt::StructOpt; - -#[derive(Debug, StructOpt)] -pub enum WalletCommands { - /// Retrieves and prints out the block specified by the given CID - #[structopt(about = "Get account balance")] - Balance { - #[structopt(help = "Input a valid address")] - address: String, - }, - - /// Prints out the genesis tipset - #[structopt(about = "Generate a new key of the given type", help = "Generate a new key of the given type")] - New, - - /// Prints out the canonical head of the chain - #[structopt(about = "Print chain head", help = "Print chain head")] - Head, - - /// Reads and prints out a message referenced by the specified CID from the - /// chain blockstore - #[structopt(about = " Retrieves and prints messages by CIDs")] - Message { - #[structopt(help = "Input a valid CID")] - cid: String, - }, - - /// Reads and prints out ipld nodes referenced by the specified CID from chain - /// blockstore and returns raw bytes - #[structopt(about = " Read the raw bytes of an object")] - ReadObj { - #[structopt(help = "Input a valid CID")] - cid: String, - }, -} - -impl WalletCommands { - pub async fn run(&self) { - // TODO handle cli config - match self { - Self::Block { cid } => { - let cid: Cid = cid.parse().unwrap(); - let mut client = new_client(); - - let blk = block(client, cid).await; - println!("{}", serde_json::to_string_pretty(&blk).unwrap()); - } - Self::Genesis => { - let mut client = new_client(); - - let gen = genesis(client).await; - println!("{}", serde_json::to_string_pretty(&gen).unwrap()); - } - Self::Head => { - let mut client = new_client(); - - let head = head(client).await; - println!("{}", serde_json::to_string_pretty(&head).unwrap()); - } - Self::Message { cid } => { - let cid: Cid = cid.parse().unwrap(); - let mut client = new_client(); - - let msg = messages(client, cid).await; - println!("{}", serde_json::to_string_pretty(&msg).unwrap()); - } - Self::ReadObj { cid } => { - let cid: Cid = cid.parse().unwrap(); - let mut client = new_client(); - - let obj = read_obj(client, cid).await; - println!("{}", serde_json::to_string_pretty(&obj).unwrap()); - } - } - } -} diff --git a/node/rpc-client/src/wallet_ops.rs b/node/rpc-client/src/wallet_ops.rs deleted file mode 100644 index 87a2ca737393..000000000000 --- a/node/rpc-client/src/wallet_ops.rs +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2020 ChainSafe Systems -// SPDX-License-Identifier: Apache-2.0, MIT - -use super::client::Filecoin; -use jsonrpc_v2::{Error as JsonRpcError}; -use jsonrpsee::raw::RawClient; -use jsonrpsee::transport::http::HttpTransportClient as HTC; -use crypto::signature::json::SignatureJson; -use wallet::{json::KeyInfoJson}; - -/// Creates a new address in the wallet with the given signature type -pub async fn new(mut client: RawClient) -> Result { - Ok(Filecoin::wallet_new(&mut client) - .await?) -} - -/// Lists all the addresses in the wallet -pub async fn list(mut client: RawClient) -> Result, JsonRpcError> { - Ok(Filecoin::wallet_list(&mut client) - .await?) -} - -/// Returns the balance of the given address at the current head of the chain -pub async fn balance(mut client: RawClient) -> Result { - Ok(Filecoin::wallet_balance(&mut client) - .await?) -} - -/// Marks the given address as as the default one -pub async fn set_default(mut client: RawClient) -> Result<(), JsonRpcError> { - Ok(Filecoin::wallet_set_default(&mut client) - .await?) -} - -/// Returns the address marked as default in the wallet -pub async fn default(mut client: RawClient) -> Result { - Ok(Filecoin::wallet_default(&mut client) - .await?) -} - -/// Signs the given bytes using the given address -pub async fn sign(mut client: RawClient) -> Result { - Ok(Filecoin::wallet_sign(&mut client) - .await?) -} - -/// Takes an address, a signature, and some bytes, and indicates whether the signature is valid. -/// The address does not have to be in the wallet -pub async fn verify(mut client: RawClient) -> Result { - Ok(Filecoin::wallet_verify(&mut client) - .await?) -} - -/// Receives a KeyInfo, which includes a private key, and imports it into the wallet -pub async fn import(mut client: RawClient) -> Result { - Ok(Filecoin::wallet_import(&mut client) - .await?) -} - -/// Returns the private key of an address in the wallet -pub async fn export(mut client: RawClient) -> Result { - Ok(Filecoin::wallet_export(&mut client) - .await?) -} \ No newline at end of file From c2cb9449139dcb64f282f8d3b83c70f6a7d1bf5f Mon Sep 17 00:00:00 2001 From: Dustin Brickwood Date: Wed, 29 Jul 2020 09:13:28 -0500 Subject: [PATCH 08/14] added import path --- Cargo.lock | 1 + forest/Cargo.toml | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 2d68ce517b51..9fb4203a9b4e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2355,6 +2355,7 @@ dependencies = [ "futures 0.3.5", "hex", "ipld_blockstore", + "jsonrpc-v2", "key_management", "libp2p 0.21.1", "log", diff --git a/forest/Cargo.toml b/forest/Cargo.toml index 5fe2b3b3a35d..8b1700956bb4 100644 --- a/forest/Cargo.toml +++ b/forest/Cargo.toml @@ -35,4 +35,5 @@ surf = "2.0.0-alpha.4" pbr = "1.0.3" pin-project-lite = "0.1" message_pool = { package = "message_pool", path = "../blockchain/message_pool" } -wallet = {package = "key_management", path = "../key_management"} \ No newline at end of file +wallet = {package = "key_management", path = "../key_management"} +jsonrpc-v2 = { version = "0.5.2", features = ["easy-errors", "macros"] } \ No newline at end of file From 9a8f7bf65764cc23e88b994fc8b24159b79c0bbd Mon Sep 17 00:00:00 2001 From: Dustin Brickwood Date: Wed, 29 Jul 2020 09:31:30 -0500 Subject: [PATCH 09/14] Hot fix --- forest/src/cli/chain_cmd.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/forest/src/cli/chain_cmd.rs b/forest/src/cli/chain_cmd.rs index ba0f46447f18..a57c315f1437 100644 --- a/forest/src/cli/chain_cmd.rs +++ b/forest/src/cli/chain_cmd.rs @@ -92,13 +92,13 @@ impl ChainCommands { } } -fn stringify_rpc_err(e: JsonRpcError) -> String { +fn stringify_rpc_err(e: JsonRpcError) { match e { - JsonRpcError::Full { code, message, data } => { - warn!("JSON RPC Error: Code: {} Message: {}", code, message) + JsonRpcError::Full { code, message, data: _ } => { + return warn!("JSON RPC Error: Code: {} Message: {}", code, message); }, - JsonRpcError::Provided { code, message, data } => { - warn!("JSON RPC Error: Code: {} Message: {}", code, message) + JsonRpcError::Provided { code, message } => { + return warn!("JSON RPC Error: Code: {} Message: {}", code, message); } } } From 9dfb38f39687c42ca19dd028e2edcf71ce9d8e84 Mon Sep 17 00:00:00 2001 From: Dustin Brickwood Date: Wed, 29 Jul 2020 09:36:42 -0500 Subject: [PATCH 10/14] linted --- forest/src/cli/chain_cmd.rs | 62 +++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/forest/src/cli/chain_cmd.rs b/forest/src/cli/chain_cmd.rs index a57c315f1437..3071765b2614 100644 --- a/forest/src/cli/chain_cmd.rs +++ b/forest/src/cli/chain_cmd.rs @@ -2,10 +2,10 @@ // SPDX-License-Identifier: Apache-2.0, MIT use cid::Cid; -use rpc_client::{block, genesis, head, messages, new_client, read_obj}; -use structopt::StructOpt; use jsonrpc_v2::Error as JsonRpcError; use log::warn; +use rpc_client::{block, genesis, head, messages, new_client, read_obj}; +use structopt::StructOpt; #[derive(Debug, StructOpt)] pub enum ChainCommands { @@ -49,43 +49,61 @@ impl ChainCommands { let cid: Cid = cid.parse().unwrap(); let client = new_client(); - let blk = block(client, cid).await.map_err(|e| { - stringify_rpc_err(e); - }).unwrap(); + let blk = block(client, cid) + .await + .map_err(|e| { + stringify_rpc_err(e); + }) + .unwrap(); println!("{}", serde_json::to_string_pretty(&blk).unwrap()); } Self::Genesis => { let client = new_client(); - let gen = genesis(client).await.map_err(|e| { - stringify_rpc_err(e); - }).unwrap(); + let gen = genesis(client) + .await + .map_err(|e| { + stringify_rpc_err(e); + }) + .unwrap(); println!("{}", serde_json::to_string_pretty(&gen).unwrap()); } Self::Head => { let client = new_client(); - let canonical = head(client).await.map_err(|e| { - stringify_rpc_err(e); - }).unwrap(); - println!("{}", serde_json::to_string_pretty(&canonical.0.cids()).unwrap()); + let canonical = head(client) + .await + .map_err(|e| { + stringify_rpc_err(e); + }) + .unwrap(); + println!( + "{}", + serde_json::to_string_pretty(&canonical.0.cids()).unwrap() + ); } Self::Message { cid } => { let cid: Cid = cid.parse().unwrap(); let client = new_client(); - let msg = messages(client, cid).await.map_err(|e| { - stringify_rpc_err(e); - }).unwrap(); + let msg = messages(client, cid) + .await + .map_err(|e| { + stringify_rpc_err(e); + }) + .unwrap(); println!("{}", serde_json::to_string_pretty(&msg).unwrap()); } Self::ReadObj { cid } => { let cid: Cid = cid.parse().unwrap(); let client = new_client(); - let obj = read_obj(client, cid).await.map_err(|e| { - stringify_rpc_err(e); - }).unwrap(); + let obj = read_obj(client, cid) + .await + .map_err(|e| { + stringify_rpc_err(e); + }) + .unwrap(); println!("{}", serde_json::to_string_pretty(&obj).unwrap()); } } @@ -94,9 +112,13 @@ impl ChainCommands { fn stringify_rpc_err(e: JsonRpcError) { match e { - JsonRpcError::Full { code, message, data: _ } => { + JsonRpcError::Full { + code, + message, + data: _, + } => { return warn!("JSON RPC Error: Code: {} Message: {}", code, message); - }, + } JsonRpcError::Provided { code, message } => { return warn!("JSON RPC Error: Code: {} Message: {}", code, message); } From 3f718256c4eb362a69c8c1ac7182021f2a588c60 Mon Sep 17 00:00:00 2001 From: Dustin Brickwood Date: Thu, 30 Jul 2020 00:29:29 -0500 Subject: [PATCH 11/14] Made requested changes --- forest/src/cli/chain_cmd.rs | 33 ++++++++++++++++---------------- node/rpc-client/src/chain_ops.rs | 20 +++++++++---------- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/forest/src/cli/chain_cmd.rs b/forest/src/cli/chain_cmd.rs index 3071765b2614..fbe0215b98d0 100644 --- a/forest/src/cli/chain_cmd.rs +++ b/forest/src/cli/chain_cmd.rs @@ -3,7 +3,6 @@ use cid::Cid; use jsonrpc_v2::Error as JsonRpcError; -use log::warn; use rpc_client::{block, genesis, head, messages, new_client, read_obj}; use structopt::StructOpt; @@ -12,7 +11,7 @@ pub enum ChainCommands { /// Retrieves and prints out the block specified by the given CID #[structopt(about = " Retrieve a block and print its details")] Block { - #[structopt(help = "Input a valid CID")] + #[structopt(short, help = "Input a valid CID")] cid: String, }, @@ -28,7 +27,7 @@ pub enum ChainCommands { /// chain blockstore #[structopt(about = " Retrieves and prints messages by CIDs")] Message { - #[structopt(help = "Input a valid CID")] + #[structopt(short, help = "Input a valid CID")] cid: String, }, @@ -36,7 +35,7 @@ pub enum ChainCommands { /// blockstore and returns raw bytes #[structopt(about = " Read the raw bytes of an object")] ReadObj { - #[structopt(help = "Input a valid CID")] + #[structopt(short, help = "Input a valid CID")] cid: String, }, } @@ -47,9 +46,9 @@ impl ChainCommands { match self { Self::Block { cid } => { let cid: Cid = cid.parse().unwrap(); - let client = new_client(); + let mut client = new_client(); - let blk = block(client, cid) + let blk = block(&mut client, cid) .await .map_err(|e| { stringify_rpc_err(e); @@ -58,9 +57,9 @@ impl ChainCommands { println!("{}", serde_json::to_string_pretty(&blk).unwrap()); } Self::Genesis => { - let client = new_client(); + let mut client = new_client(); - let gen = genesis(client) + let gen = genesis(&mut client) .await .map_err(|e| { stringify_rpc_err(e); @@ -69,9 +68,9 @@ impl ChainCommands { println!("{}", serde_json::to_string_pretty(&gen).unwrap()); } Self::Head => { - let client = new_client(); + let mut client = new_client(); - let canonical = head(client) + let canonical = head(&mut client) .await .map_err(|e| { stringify_rpc_err(e); @@ -84,9 +83,9 @@ impl ChainCommands { } Self::Message { cid } => { let cid: Cid = cid.parse().unwrap(); - let client = new_client(); + let mut client = new_client(); - let msg = messages(client, cid) + let msg = messages(&mut client, cid) .await .map_err(|e| { stringify_rpc_err(e); @@ -96,9 +95,9 @@ impl ChainCommands { } Self::ReadObj { cid } => { let cid: Cid = cid.parse().unwrap(); - let client = new_client(); + let mut client = new_client(); - let obj = read_obj(client, cid) + let obj = read_obj(&mut client, cid) .await .map_err(|e| { stringify_rpc_err(e); @@ -110,17 +109,17 @@ impl ChainCommands { } } -fn stringify_rpc_err(e: JsonRpcError) { +fn stringify_rpc_err(e: JsonRpcError) -> String { match e { JsonRpcError::Full { code, message, data: _, } => { - return warn!("JSON RPC Error: Code: {} Message: {}", code, message); + return format!("JSON RPC Error: Code: {} Message: {}", code, message); } JsonRpcError::Provided { code, message } => { - return warn!("JSON RPC Error: Code: {} Message: {}", code, message); + return format!("JSON RPC Error: Code: {} Message: {}", code, message); } } } diff --git a/node/rpc-client/src/chain_ops.rs b/node/rpc-client/src/chain_ops.rs index 5111155fb44e..0cb64c7ab516 100644 --- a/node/rpc-client/src/chain_ops.rs +++ b/node/rpc-client/src/chain_ops.rs @@ -10,29 +10,29 @@ use jsonrpsee::transport::http::HttpTransportClient as HTC; use message::unsigned_message::json::UnsignedMessageJson; /// Returns a block with specified CID fom chain via RPC -pub async fn block(mut client: RawClient, cid: Cid) -> Result { - Ok(Filecoin::chain_get_block(&mut client, CidJson(cid)).await?) +pub async fn block(client: &mut RawClient, cid: Cid) -> Result { + Ok(Filecoin::chain_get_block(client, CidJson(cid)).await?) } /// Returns genesis tipset from chain via RPC -pub async fn genesis(mut client: RawClient) -> Result { - Ok(Filecoin::chain_get_genesis(&mut client).await?) +pub async fn genesis(client: &mut RawClient) -> Result { + Ok(Filecoin::chain_get_genesis(client).await?) } /// Returns canonical head of the chain via RPC -pub async fn head(mut client: RawClient) -> Result { - Ok(Filecoin::chain_get_head(&mut client).await?) +pub async fn head(client: &mut RawClient) -> Result { + Ok(Filecoin::chain_get_head(client).await?) } /// Returns messages with specified CID from chain via RPC pub async fn messages( - mut client: RawClient, + client: &mut RawClient, cid: Cid, ) -> Result { - Ok(Filecoin::chain_get_messages(&mut client, CidJson(cid)).await?) + Ok(Filecoin::chain_get_messages(client, CidJson(cid)).await?) } /// Returns IPLD node with specified CID from chain via RPC -pub async fn read_obj(mut client: RawClient, cid: Cid) -> Result, JsonRpcError> { - Ok(Filecoin::chain_read_obj(&mut client, CidJson(cid)).await?) +pub async fn read_obj(client: &mut RawClient, cid: Cid) -> Result, JsonRpcError> { + Ok(Filecoin::chain_read_obj(client, CidJson(cid)).await?) } From df2e1c53d74951208f2f9a94acdc044265f53f88 Mon Sep 17 00:00:00 2001 From: Dustin Brickwood Date: Thu, 30 Jul 2020 09:45:00 -0500 Subject: [PATCH 12/14] Made requested changes --- forest/src/cli/chain_cmd.rs | 17 +---------------- forest/src/cli/mod.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/forest/src/cli/chain_cmd.rs b/forest/src/cli/chain_cmd.rs index fbe0215b98d0..7cdec1540897 100644 --- a/forest/src/cli/chain_cmd.rs +++ b/forest/src/cli/chain_cmd.rs @@ -1,8 +1,8 @@ // Copyright 2020 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT +use super::stringify_rpc_err; use cid::Cid; -use jsonrpc_v2::Error as JsonRpcError; use rpc_client::{block, genesis, head, messages, new_client, read_obj}; use structopt::StructOpt; @@ -108,18 +108,3 @@ impl ChainCommands { } } } - -fn stringify_rpc_err(e: JsonRpcError) -> String { - match e { - JsonRpcError::Full { - code, - message, - data: _, - } => { - return format!("JSON RPC Error: Code: {} Message: {}", code, message); - } - JsonRpcError::Provided { code, message } => { - return format!("JSON RPC Error: Code: {} Message: {}", code, message); - } - } -} diff --git a/forest/src/cli/mod.rs b/forest/src/cli/mod.rs index ff29da445c02..f37ad621bdf0 100644 --- a/forest/src/cli/mod.rs +++ b/forest/src/cli/mod.rs @@ -11,6 +11,7 @@ pub use self::config::Config; pub(super) use self::fetch_params_cmd::FetchCommands; pub(super) use self::genesis::initialize_genesis; +use jsonrpc_v2::Error as JsonRpcError; use std::cell::RefCell; use std::io; use std::process; @@ -109,3 +110,19 @@ pub(super) async fn block_until_sigint() { ctrlc_oneshot.await.unwrap(); } + +/// Returns a stringified JSON-RPC error +pub(super) fn stringify_rpc_err(e: JsonRpcError) -> String { + match e { + JsonRpcError::Full { + code, + message, + data: _, + } => { + return format!("JSON RPC Error: Code: {} Message: {}", code, message); + } + JsonRpcError::Provided { code, message } => { + return format!("JSON RPC Error: Code: {} Message: {}", code, message); + } + } +} From be891f240b125a724f08d4784919149fcd15dacc Mon Sep 17 00:00:00 2001 From: Dustin Brickwood Date: Thu, 30 Jul 2020 09:55:19 -0500 Subject: [PATCH 13/14] ignore clippy warnings from jsonrpsee crate --- node/rpc-client/src/client.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/node/rpc-client/src/client.rs b/node/rpc-client/src/client.rs index 1e66d363d8b3..5c523a9949e8 100644 --- a/node/rpc-client/src/client.rs +++ b/node/rpc-client/src/client.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0, MIT #![allow(clippy::all)] +#![allow(unused_variables, dead_code)] use blocks::{header::json::BlockHeaderJson, tipset_json::TipsetJson}; use cid::json::CidJson; From c27b63834839162f8a935ef886691a3d8a52b5e1 Mon Sep 17 00:00:00 2001 From: Dustin Brickwood Date: Thu, 30 Jul 2020 12:03:43 -0500 Subject: [PATCH 14/14] update err handling --- forest/src/cli/chain_cmd.rs | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/forest/src/cli/chain_cmd.rs b/forest/src/cli/chain_cmd.rs index 7cdec1540897..14da8df31fee 100644 --- a/forest/src/cli/chain_cmd.rs +++ b/forest/src/cli/chain_cmd.rs @@ -50,9 +50,7 @@ impl ChainCommands { let blk = block(&mut client, cid) .await - .map_err(|e| { - stringify_rpc_err(e); - }) + .map_err(stringify_rpc_err) .unwrap(); println!("{}", serde_json::to_string_pretty(&blk).unwrap()); } @@ -61,21 +59,14 @@ impl ChainCommands { let gen = genesis(&mut client) .await - .map_err(|e| { - stringify_rpc_err(e); - }) + .map_err(stringify_rpc_err) .unwrap(); println!("{}", serde_json::to_string_pretty(&gen).unwrap()); } Self::Head => { let mut client = new_client(); - let canonical = head(&mut client) - .await - .map_err(|e| { - stringify_rpc_err(e); - }) - .unwrap(); + let canonical = head(&mut client).await.map_err(stringify_rpc_err).unwrap(); println!( "{}", serde_json::to_string_pretty(&canonical.0.cids()).unwrap() @@ -87,9 +78,7 @@ impl ChainCommands { let msg = messages(&mut client, cid) .await - .map_err(|e| { - stringify_rpc_err(e); - }) + .map_err(stringify_rpc_err) .unwrap(); println!("{}", serde_json::to_string_pretty(&msg).unwrap()); } @@ -99,9 +88,7 @@ impl ChainCommands { let obj = read_obj(&mut client, cid) .await - .map_err(|e| { - stringify_rpc_err(e); - }) + .map_err(stringify_rpc_err) .unwrap(); println!("{}", serde_json::to_string_pretty(&obj).unwrap()); }