Skip to content

Commit

Permalink
node info
Browse files Browse the repository at this point in the history
  • Loading branch information
cgilliard committed Jun 18, 2019
1 parent 6e77fd9 commit ceb6c66
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 2 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,4 @@ grin_core = { git = "https://github.com/cgilliard/mwc-node" }
grin_keychain = { git = "https://github.com/cgilliard/mwc-node" }
grin_util = { git = "https://github.com/cgilliard/mwc-node" }
grin_store = { git = "https://github.com/cgilliard/mwc-node" }
grin_p2p = { git = "https://github.com/cgilliard/mwc-node" }
4 changes: 4 additions & 0 deletions src/cli/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,10 @@ impl<'a, 'b> Parser {
Arg::from_usage("-f, --file=<file> 'the file to read from'")
)
)
.subcommand(
SubCommand::with_name("nodeinfo")
.about("prints information about the node")
)
.subcommand(
SubCommand::with_name("set-recv")
.about("sets which account is the recipient of an incoming transaction")
Expand Down
6 changes: 5 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ extern crate grin_core;
extern crate grin_keychain;
extern crate grin_store;
extern crate grin_util;
extern crate grin_p2p;

use std::borrow::Cow::{self, Borrowed, Owned};
use std::fs::File;
Expand Down Expand Up @@ -1152,6 +1153,9 @@ fn do_command(
wallet.lock().finalize_slate(&mut slate, None)?;
cli_message!("{} finalized.", input);
}
Some("nodeinfo") => {
wallet.lock().node_info()?;
}
Some("send") => {
let args = matches.subcommand_matches("send").unwrap();
let to = args.value_of("to");
Expand Down Expand Up @@ -1572,4 +1576,4 @@ pub fn enable_ansi_support() {

#[cfg(not(windows))]
pub fn enable_ansi_support() {
}
}
56 changes: 56 additions & 0 deletions src/wallet/api/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use grin_core::ser;
use grin_util::secp::key::PublicKey;
use grin_util::secp::pedersen;
use grin_util::secp::{ContextFlag, Secp256k1};
use grin_p2p::types::PeerInfoDisplay;

use crate::contacts::GrinboxAddress;

Expand Down Expand Up @@ -40,6 +41,14 @@ where
phantom_c: PhantomData<C>,
}

// struct for sending back node information
pub struct NodeInfo
{
pub height: u64,
pub total_difficulty: u64,
pub peers: Vec<PeerInfoDisplay>,
}

impl<W: ?Sized, C, K> Wallet713OwnerAPI<W, C, K>
where
W: WalletBackend<C, K>,
Expand Down Expand Up @@ -344,6 +353,53 @@ where
w.get_stored_tx(uuid)
}

pub fn node_info(&self) -> Result<(NodeInfo), Error> {
// first get height
let height = {
let mut w = self.wallet.lock();
w.open_with_credentials()?;
w.w2n_client().get_chain_height()
};

// next total_difficulty
let total_difficulty = {
let mut w = self.wallet.lock();
w.open_with_credentials()?;
w.w2n_client().get_total_difficulty()
};

// peer info
let peers = {
let mut w = self.wallet.lock();
w.open_with_credentials()?;
w.w2n_client().get_connected_peer_info()
};

// handle any errors that occurred
match height {
Ok(height) => {
match total_difficulty {
Ok(total_difficulty) => {
match peers {
Ok(peers) => {
Ok(NodeInfo{height:height,total_difficulty:total_difficulty,peers:peers})
},
Err(_) => {
Ok(NodeInfo{height:0,total_difficulty:0,peers:Vec::new()})
}
}
},
Err(_) => {
Ok(NodeInfo{height:0,total_difficulty:0,peers:Vec::new()})
}
}
},
Err(_) => {
Ok(NodeInfo{height:0,total_difficulty:0,peers:Vec::new()})
}
}
}

pub fn post_tx(&self, tx: &Transaction, fluff: bool) -> Result<(), Error> {
let tx_hex = grin_util::to_hex(ser::ser_vec(tx).unwrap());
let client = {
Expand Down
32 changes: 31 additions & 1 deletion src/wallet/types/node_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use futures::Stream;
use futures::stream;
use grin_api::{Output, OutputType, OutputListing, Tip};
use grin_api::client;
use grin_p2p::types::PeerInfoDisplay;
use grin_util::secp::pedersen::{Commitment, RangeProof};
use grin_util::to_hex;
use std::collections::HashMap;
Expand Down Expand Up @@ -45,6 +46,12 @@ pub trait NodeClient: Sync + Send + Clone {
/// retrieves the current tip from the specified grin node
fn get_chain_height(&self) -> Result<u64, Error>;

/// retreives total difficulty
fn get_total_difficulty(&self) -> Result<u64, Error>;

/// retreives the connected peer info of the node
fn get_connected_peer_info(&self) -> Result<Vec<PeerInfoDisplay>, grin_api::Error>;

/// retrieve a list of outputs from the specified grin node
/// need "by_height" and "by_id" variants
fn get_outputs_from_node(
Expand Down Expand Up @@ -121,6 +128,29 @@ impl NodeClient for HTTPNodeClient {
Ok(())
}

/// Return Connected peers
fn get_connected_peer_info(&self) -> Result<Vec<PeerInfoDisplay>, grin_api::Error> {
let addr = self.node_url();
let url = format!("{}/v1/peers/connected", addr);
let peers = client::get::<Vec<PeerInfoDisplay>>(url.as_str(), self.node_api_secret());
peers
}

/// Return total_difficulty of the chain
fn get_total_difficulty(&self) -> Result<u64, Error> {
let addr = self.node_url();
let url = format!("{}/v1/chain", addr);
let res = client::get::<Tip>(url.as_str(), self.node_api_secret());
match res {
Err(e) => {
let report = format!("Getting chain difficulty from node: {}", e);
error!("Get diffulty error: {}", e);
Err(ErrorKind::ClientCallback(report).into())
}
Ok(r) => Ok(r.total_difficulty),
}
}

/// Return the chain tip from a given node
fn get_chain_height(&self) -> Result<u64, Error> {
let addr = self.node_url();
Expand Down Expand Up @@ -233,4 +263,4 @@ impl NodeClient for HTTPNodeClient {
}
}
}
}
}
25 changes: 25 additions & 0 deletions src/wallet/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,31 @@ impl Wallet {
Ok(())
}

pub fn node_info(
&mut self) -> Result<()> {
// get wallet instance
let wallet = self.get_wallet_instance()?;

// create a single use wallet api
controller::owner_single_use(wallet.clone(), |api| {
let ni = api.node_info().unwrap();
// this is an error condition
if ni.height == 0 && ni.total_difficulty == 0 {
cli_message!("Error occured trying to contact node!");
}
else
{
// otherwise it worked, print it out here.
cli_message!("Node Info:");
cli_message!("Height: {}", ni.height);
cli_message!("Total_Difficulty: {}", ni.total_difficulty);
cli_message!("PeerInfo: {:?}", ni.peers);
}
Ok(())
})?;
Ok(())
}

pub fn account_exists(
&mut self,
account: &str) -> Result<(bool)> {
Expand Down

1 comment on commit ceb6c66

@bayk
Copy link
Collaborator

@bayk bayk commented on ceb6c66 Jun 18, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, just what we need.

Please sign in to comment.