Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[network-rpc & cmd]Add node network call_peer command for debug network rpc problem. #2223

Merged
merged 4 commits into from
Mar 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 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 cmd/starcoin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ starcoin-service-registry = { path = "../../commons/service-registry" }
starcoin-move-explain = { path = "../../vm/move-explain" }
errmapgen = { git = "https://github.com/starcoinorg/diem", rev="b42f4aa6c021eed055b3841da94318559e1e0bbb" }
network-api = {path = "../../network/api", package="network-api"}
starcoin-network-rpc-api = {path = "../../network-rpc/api"}
short-hex-str = { git = "https://github.com/starcoinorg/diem", rev="b42f4aa6c021eed055b3841da94318559e1e0bbb" }


Expand Down
1 change: 1 addition & 0 deletions cmd/starcoin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ pub fn add_command(
.subcommand(node::network::KnownPeersCommand)
.subcommand(node::network::GetAddressCommand)
.subcommand(node::network::AddPeerCommand)
.subcommand(node::network::CallPeerCommand)
),
)
.command(
Expand Down
57 changes: 57 additions & 0 deletions cmd/starcoin/src/node/network/call_peer_cmd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) The Starcoin Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::cli_state::CliState;
use crate::StarcoinOpt;
use anyhow::{bail, Result};
use bcs_ext::BCSCodec;
use scmd::{CommandAction, ExecContext};
use starcoin_network_rpc_api::Ping;
use starcoin_rpc_api::types::StrView;
use starcoin_types::peer_info::PeerId;
use structopt::StructOpt;

/// Call peer method by p2p network, just for diagnose network problem.
#[derive(Debug, StructOpt)]
#[structopt(name = "call_peer")]
pub struct CallPeerOpt {
#[structopt(short = "p", long = "peer-id")]
peer_id: PeerId,
/// rpc path, if absent, use ping method.
#[structopt(short = "r", long = "rpc-method")]
rpc_method: Option<String>,
/// request message serialize by lcs and encode by hex
#[structopt(short = "m", long = "message")]
message: Option<String>,
}

pub struct CallPeerCommand;

impl CommandAction for CallPeerCommand {
type State = CliState;
type GlobalOpt = StarcoinOpt;
type Opt = CallPeerOpt;
type ReturnItem = StrView<Vec<u8>>;

fn run(
&self,
ctx: &ExecContext<Self::State, Self::GlobalOpt, Self::Opt>,
) -> Result<Self::ReturnItem> {
let client = ctx.state().client();
let opt = ctx.opt();
let (rpc_method, message) = match (opt.rpc_method.as_ref(), opt.message.as_ref()) {
(None, _) => {
let ping_msg = Ping {
msg: "ping_by_cmd".to_string(),
err: false,
};
("ping".to_string(), ping_msg.encode()?)
}
(Some(rpc_method), Some(message)) => (rpc_method.clone(), hex::decode(message)?),
(Some(_rpc_method), None) => {
bail!("Please input call message.")
}
};
client.network_call_peer(opt.peer_id.to_string(), rpc_method, StrView(message))
}
}
2 changes: 2 additions & 0 deletions cmd/starcoin/src/node/network/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
// Copyright (c) The Starcoin Core Contributors

mod add_peer_cmd;
mod call_peer_cmd;
mod get_address_cmd;
mod known_peers_cmd;
mod state_cmd;

pub use add_peer_cmd::*;
pub use call_peer_cmd::*;
pub use get_address_cmd::*;
pub use known_peers_cmd::*;
pub use state_cmd::*;
4 changes: 2 additions & 2 deletions network-p2p/types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,15 +181,15 @@ pub enum RequestFailure {
/// The remote replied, but the local node is no longer interested in the response.
Obsolete,
/// Problem on the network.
#[display(fmt = "Problem on the network")]
#[display(fmt = "Problem on the network: {:?}", _0)]
Network(#[error(ignore)] OutboundFailure),
}

/// Error when processing a request sent by a remote.
#[derive(Debug, derive_more::Display, derive_more::Error)]
pub enum ResponseFailure {
/// Problem on the network.
#[display(fmt = "Problem on the network")]
#[display(fmt = "Problem on the network: {:?}", _0)]
Network(#[error(ignore)] InboundFailure),
}

Expand Down
27 changes: 20 additions & 7 deletions network-rpc/derive/src/to_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,34 @@ pub fn generate_client_module(rpc_trait: &ItemTrait) -> anyhow::Result<TokenStre
};

let peer_id = #peer_id_indent;
debug!("Network rpc call method: {:?}, peer_id:{:?} args: {:?} ", stringify!(#name), peer_id, #user_arg_indent);
debug!("[network-rpc] call method: {:?}, peer_id:{:?} args: {:?} ", stringify!(#name), peer_id, #user_arg_indent);
let rpc_path = stringify!(#name).to_string();
match self.request(peer_id, rpc_path, input_arg_serialized).await{
let result = self.request(peer_id, rpc_path, input_arg_serialized).await;
match result {
Ok(result) => {
match from_bytes::<network_rpc_core::Result::<Vec<u8>>>(&result){
let result = from_bytes::<network_rpc_core::Result::<Vec<u8>>>(&result);
match result {
Ok(r) => match r{
Ok(v) => {
from_bytes::<#returns>(&v)
let result = from_bytes::<#returns>(&v);
debug!("[network-rpc] response : {:?} ", result);
result
},
Err(e) => Err(e.into()),
Err(e) => {
debug!("[network-rpc] response error: {:?} ", e);
Err(e.into())
},
},
Err(e) => {
debug!("[network-rpc] response error: {:?} ", e);
Err(e)
},
Err(e) => Err(e),
}
},
Err(e) => Err(e)
Err(e) => {
debug!("[network-rpc] response error: {:?} ", e);
Err(e)
}
}
}.boxed()}
})
Expand Down
1 change: 1 addition & 0 deletions network-rpc/derive/src/to_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub fn generate_to_delegate(method: &TraitItemMethod) -> TokenStream {
Box::pin(async move{
let method = &(Self::#method_ident as #method_sig);
let params = from_bytes::<#param_type>(&params).map_err(|e|NetRpcError::client_err(e))?;
debug!("[network-rpc] from {:?}, method: {:?}, params: {:?}", peer_id, stringify!(method), params);
match method(&base, peer_id, params).await{
Ok(r) => Ok(bcs_ext::to_bytes(&r)?),
Err(e) => Err(e)
Expand Down
10 changes: 10 additions & 0 deletions rpc/api/src/network_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2

pub use self::gen_client::Client as NetworkManagerClient;
use crate::types::StrView;
use crate::FutureResult;
use jsonrpc_derive::rpc;
use network_p2p_types::network_state::NetworkState;
Expand All @@ -20,4 +21,13 @@ pub trait NetworkManagerApi {

#[rpc(name = "network_manager.add_peer")]
fn add_peer(&self, peer: String) -> FutureResult<()>;

/// Call peer's network rpc method.
#[rpc(name = "network_manager.call")]
fn call_peer(
&self,
peer_id: String,
rpc_method: String,
message: StrView<Vec<u8>>,
) -> FutureResult<StrView<Vec<u8>>>;
}
10 changes: 10 additions & 0 deletions rpc/client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,16 @@ impl RpcClient {
.map_err(map_err)
}

pub fn network_call_peer(
&self,
peer_id: String,
rpc_method: String,
message: StrView<Vec<u8>>,
) -> anyhow::Result<StrView<Vec<u8>>> {
self.call_rpc_blocking(|inner| inner.network_client.call_peer(peer_id, rpc_method, message))
.map_err(map_err)
}

pub fn call_raw_api(&self, api: &str, params: Params) -> anyhow::Result<Value> {
self.call_rpc_blocking(|inner| inner.raw_client.call_method(api, params))
.map_err(map_err)
Expand Down
1 change: 1 addition & 0 deletions rpc/server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ network-api = { path = "../../network/api" }
starcoin-node-api = { path = "../../node/api"}
starcoin-sync-api = { path = "../../sync/api"}
network-p2p-types = {path = "../../network-p2p/types"}
network-rpc-core = {path = "../../network-rpc/core"}
api-limiter = {path = "../../commons/api-limiter"}
governor = {version="0.3.1", features=["dashmap"]}

Expand Down
20 changes: 20 additions & 0 deletions rpc/server/src/module/network_manager_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ use crate::module::map_err;
use futures::future::TryFutureExt;
use futures::FutureExt;
use network_p2p_types::network_state::NetworkState;
use network_rpc_core::RawRpcClient;
use starcoin_network::NetworkServiceRef;
use starcoin_rpc_api::network_manager::NetworkManagerApi;
use starcoin_rpc_api::types::StrView;
use starcoin_rpc_api::FutureResult;
use starcoin_types::peer_info::{Multiaddr, PeerId};
use std::str::FromStr;
Expand Down Expand Up @@ -54,4 +56,22 @@ impl NetworkManagerApi for NetworkManagerRpcImpl {
let fut = async move { service.add_peer(peer) }.map_err(map_err);
Box::pin(fut.boxed())
}

fn call_peer(
&self,
peer_id: String,
rpc_method: String,
message: StrView<Vec<u8>>,
) -> FutureResult<StrView<Vec<u8>>> {
let service = self.service.clone();
let fut = async move {
let peer_id = PeerId::from_str(peer_id.as_str())?;
let response = service
.send_raw_request(peer_id, rpc_method, message.0)
.await?;
Ok(StrView(response))
}
.map_err(map_err);
Box::pin(fut.boxed())
}
}