diff --git a/client-network/src/network_ops.rs b/client-network/src/network_ops.rs index ff5d2d189..6132b38c5 100644 --- a/client-network/src/network_ops.rs +++ b/client-network/src/network_ops.rs @@ -2,7 +2,6 @@ mod default_network_ops_client; pub use self::default_network_ops_client::DefaultNetworkOpsClient; - use chain_core::init::coin::Coin; use chain_core::state::account::{ CouncilNode, StakedState, StakedStateAddress, StakedStateOpAttributes, @@ -12,6 +11,7 @@ use chain_core::tx::data::attribute::TxAttributes; use chain_core::tx::data::input::TxoPointer; use chain_core::tx::data::output::TxOut; use chain_core::tx::TxAux; +use client_common::tendermint::types::{Genesis, StatusResponse}; use client_common::{ErrorKind, Result, ResultExt, SecKey}; use client_core::types::TransactionPending; @@ -103,4 +103,10 @@ pub trait NetworkOpsClient: Send + Sync { address: &StakedStateAddress, verify: bool, ) -> Result>; + + /// Return genesis of tendermint + fn get_genesis(&self) -> Result; + + /// Return status response + fn get_status(&self) -> Result; } diff --git a/client-network/src/network_ops/default_network_ops_client.rs b/client-network/src/network_ops/default_network_ops_client.rs index 336fac51a..558f7dce8 100644 --- a/client-network/src/network_ops/default_network_ops_client.rs +++ b/client-network/src/network_ops/default_network_ops_client.rs @@ -16,7 +16,7 @@ use chain_core::tx::fee::FeeAlgorithm; use chain_core::tx::{TxAux, TxPublicAux}; use chain_storage::jellyfish::SparseMerkleProof; use chain_tx_validation::{check_inputs_basic, check_outputs_basic, verify_unjailed}; -use client_common::tendermint::types::AbciQueryExt; +use client_common::tendermint::types::{AbciQueryExt, Genesis, StatusResponse}; use client_common::tendermint::Client; use client_common::{ Error, ErrorKind, Result, ResultExt, SecKey, SignedTransaction, Storage, Transaction, @@ -28,6 +28,7 @@ use client_core::{TransactionObfuscation, UnspentTransactions, WalletClient}; use tendermint::{block::Height, Time}; /// Default implementation of `NetworkOpsClient` +#[derive(Clone)] pub struct DefaultNetworkOpsClient where W: WalletClient, @@ -254,11 +255,15 @@ where ) -> Result<(TxAux, TransactionPending)> { let last_block_time = self.get_last_block_time()?; let staked_state = self.get_staked_state(name, from_address, verify_staking)?; - if staked_state.unbonded_from > last_block_time { + let seconds = staked_state.unbonded_from - last_block_time; + let duration = std::time::Duration::from_secs(seconds); return Err(Error::new( ErrorKind::ValidationError, - "Staking state is not yet unbonded", + format!( + "Staking state is not yet unbonded, time left: {:?}", + duration + ), )); } @@ -514,6 +519,14 @@ where }; Ok(mstaking) } + + fn get_genesis(&self) -> Result { + self.client.genesis() + } + + fn get_status(&self) -> Result { + self.client.status() + } } fn to_timespec(time: Time) -> Timespec { diff --git a/client-rpc/src/handler.rs b/client-rpc/src/handler.rs index 0bad9a275..e73784405 100644 --- a/client-rpc/src/handler.rs +++ b/client-rpc/src/handler.rs @@ -14,6 +14,7 @@ use client_core::wallet::DefaultWalletClient; use client_network::network_ops::DefaultNetworkOpsClient; use crate::rpc::{ + info_rpc::{InfoRpc, InfoRpcImpl}, multisig_rpc::{MultiSigRpc, MultiSigRpcImpl}, staking_rpc::{StakingRpc, StakingRpcImpl}, sync_rpc::{CBindingCore, SyncRpc, SyncRpcImpl}, @@ -75,7 +76,9 @@ impl RpcHandler { let multisig_rpc = MultiSigRpcImpl::new(wallet_client.clone()); let transaction_rpc = TransactionRpcImpl::new(network_id); - let staking_rpc = StakingRpcImpl::new(wallet_client.clone(), ops_client, network_id); + let staking_rpc = + StakingRpcImpl::new(wallet_client.clone(), ops_client.clone(), network_id); + let info_rpc = InfoRpcImpl::new(ops_client); let sync_wallet_client = make_wallet_client(storage, tendermint_client, fee_policy, obfuscator)?; @@ -88,6 +91,7 @@ impl RpcHandler { io.extend_with(staking_rpc.to_delegate()); io.extend_with(sync_rpc.to_delegate()); io.extend_with(wallet_rpc.to_delegate()); + io.extend_with(info_rpc.to_delegate()); Ok(RpcHandler { io }) } diff --git a/client-rpc/src/rpc.rs b/client-rpc/src/rpc.rs index 54ab83541..f101c43dc 100644 --- a/client-rpc/src/rpc.rs +++ b/client-rpc/src/rpc.rs @@ -1,3 +1,4 @@ +pub mod info_rpc; pub mod multisig_rpc; pub mod staking_rpc; pub mod sync_rpc; diff --git a/client-rpc/src/rpc/info_rpc.rs b/client-rpc/src/rpc/info_rpc.rs new file mode 100644 index 000000000..dae0f2b5d --- /dev/null +++ b/client-rpc/src/rpc/info_rpc.rs @@ -0,0 +1,42 @@ +use jsonrpc_core::Result; +use jsonrpc_derive::rpc; + +use crate::to_rpc_error; +use client_common::tendermint::types::{Genesis, StatusResponse}; +use client_network::NetworkOpsClient; + +#[rpc(server)] +pub trait InfoRpc: Send + Sync { + #[rpc(name = "genesis")] + fn genesis(&self) -> Result; + #[rpc(name = "status")] + fn status(&self) -> Result; +} + +pub struct InfoRpcImpl +where + N: NetworkOpsClient, +{ + ops_client: N, +} + +impl InfoRpcImpl +where + N: NetworkOpsClient, +{ + pub fn new(ops_client: N) -> Self { + InfoRpcImpl { ops_client } + } +} + +impl InfoRpc for InfoRpcImpl +where + N: NetworkOpsClient + 'static, +{ + fn genesis(&self) -> Result { + self.ops_client.get_genesis().map_err(to_rpc_error) + } + fn status(&self) -> Result { + self.ops_client.get_status().map_err(to_rpc_error) + } +}