mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 03:21:08 +03:00
Add sync_status in status Node API (#2966)
* Add sync_status in status Node API
This commit is contained in:
parent
28d5ee8242
commit
b209244d17
5 changed files with 75 additions and 5 deletions
|
@ -62,11 +62,13 @@ pub fn start_rest_apis(
|
||||||
chain: Arc<chain::Chain>,
|
chain: Arc<chain::Chain>,
|
||||||
tx_pool: Arc<RwLock<pool::TransactionPool>>,
|
tx_pool: Arc<RwLock<pool::TransactionPool>>,
|
||||||
peers: Arc<p2p::Peers>,
|
peers: Arc<p2p::Peers>,
|
||||||
|
sync_state: Arc<chain::SyncState>,
|
||||||
api_secret: Option<String>,
|
api_secret: Option<String>,
|
||||||
tls_config: Option<TLSConfig>,
|
tls_config: Option<TLSConfig>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut apis = ApiServer::new();
|
let mut apis = ApiServer::new();
|
||||||
let mut router = build_router(chain, tx_pool, peers).expect("unable to build API router");
|
let mut router =
|
||||||
|
build_router(chain, tx_pool, peers, sync_state).expect("unable to build API router");
|
||||||
if let Some(api_secret) = api_secret {
|
if let Some(api_secret) = api_secret {
|
||||||
let api_basic_auth = format!("Basic {}", util::to_base64(&format!("grin:{}", api_secret)));
|
let api_basic_auth = format!("Basic {}", util::to_base64(&format!("grin:{}", api_secret)));
|
||||||
let basic_auth_middleware = Arc::new(BasicAuthMiddleware::new(
|
let basic_auth_middleware = Arc::new(BasicAuthMiddleware::new(
|
||||||
|
@ -93,6 +95,7 @@ pub fn build_router(
|
||||||
chain: Arc<chain::Chain>,
|
chain: Arc<chain::Chain>,
|
||||||
tx_pool: Arc<RwLock<pool::TransactionPool>>,
|
tx_pool: Arc<RwLock<pool::TransactionPool>>,
|
||||||
peers: Arc<p2p::Peers>,
|
peers: Arc<p2p::Peers>,
|
||||||
|
sync_state: Arc<chain::SyncState>,
|
||||||
) -> Result<Router, RouterError> {
|
) -> Result<Router, RouterError> {
|
||||||
let route_list = vec![
|
let route_list = vec![
|
||||||
"get blocks".to_string(),
|
"get blocks".to_string(),
|
||||||
|
@ -144,6 +147,7 @@ pub fn build_router(
|
||||||
let status_handler = StatusHandler {
|
let status_handler = StatusHandler {
|
||||||
chain: Arc::downgrade(&chain),
|
chain: Arc::downgrade(&chain),
|
||||||
peers: Arc::downgrade(&peers),
|
peers: Arc::downgrade(&peers),
|
||||||
|
sync_state: Arc::downgrade(&sync_state),
|
||||||
};
|
};
|
||||||
let kernel_download_handler = KernelDownloadHandler {
|
let kernel_download_handler = KernelDownloadHandler {
|
||||||
peers: Arc::downgrade(&peers),
|
peers: Arc::downgrade(&peers),
|
||||||
|
|
|
@ -13,13 +13,14 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use super::utils::w;
|
use super::utils::w;
|
||||||
use crate::chain;
|
use crate::chain::{Chain, SyncState, SyncStatus};
|
||||||
use crate::p2p;
|
use crate::p2p;
|
||||||
use crate::rest::*;
|
use crate::rest::*;
|
||||||
use crate::router::{Handler, ResponseFuture};
|
use crate::router::{Handler, ResponseFuture};
|
||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
use crate::web::*;
|
use crate::web::*;
|
||||||
use hyper::{Body, Request, StatusCode};
|
use hyper::{Body, Request, StatusCode};
|
||||||
|
use serde_json::json;
|
||||||
use std::sync::Weak;
|
use std::sync::Weak;
|
||||||
|
|
||||||
// RESTful index of available api endpoints
|
// RESTful index of available api endpoints
|
||||||
|
@ -62,8 +63,9 @@ impl Handler for KernelDownloadHandler {
|
||||||
/// Status handler. Post a summary of the server status
|
/// Status handler. Post a summary of the server status
|
||||||
/// GET /v1/status
|
/// GET /v1/status
|
||||||
pub struct StatusHandler {
|
pub struct StatusHandler {
|
||||||
pub chain: Weak<chain::Chain>,
|
pub chain: Weak<Chain>,
|
||||||
pub peers: Weak<p2p::Peers>,
|
pub peers: Weak<p2p::Peers>,
|
||||||
|
pub sync_state: Weak<SyncState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StatusHandler {
|
impl StatusHandler {
|
||||||
|
@ -71,9 +73,13 @@ impl StatusHandler {
|
||||||
let head = w(&self.chain)?
|
let head = w(&self.chain)?
|
||||||
.head()
|
.head()
|
||||||
.map_err(|e| ErrorKind::Internal(format!("can't get head: {}", e)))?;
|
.map_err(|e| ErrorKind::Internal(format!("can't get head: {}", e)))?;
|
||||||
|
let sync_status = w(&self.sync_state)?.status();
|
||||||
|
let (api_sync_status, api_sync_info) = sync_status_to_api(sync_status);
|
||||||
Ok(Status::from_tip_and_peers(
|
Ok(Status::from_tip_and_peers(
|
||||||
head,
|
head,
|
||||||
w(&self.peers)?.peer_count(),
|
w(&self.peers)?.peer_count(),
|
||||||
|
api_sync_status,
|
||||||
|
api_sync_info,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,3 +89,50 @@ impl Handler for StatusHandler {
|
||||||
result_to_response(self.get_status())
|
result_to_response(self.get_status())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert a SyncStatus in a readable API representation
|
||||||
|
fn sync_status_to_api(sync_status: SyncStatus) -> (String, Option<serde_json::Value>) {
|
||||||
|
match sync_status {
|
||||||
|
SyncStatus::NoSync => ("no_sync".to_string(), None),
|
||||||
|
SyncStatus::AwaitingPeers(_) => ("awaiting_peers".to_string(), None),
|
||||||
|
SyncStatus::HeaderSync {
|
||||||
|
current_height,
|
||||||
|
highest_height,
|
||||||
|
} => (
|
||||||
|
"header_sync".to_string(),
|
||||||
|
Some(json!({ "current_height": current_height, "highest_height": highest_height })),
|
||||||
|
),
|
||||||
|
SyncStatus::TxHashsetDownload {
|
||||||
|
start_time: _,
|
||||||
|
prev_update_time: _,
|
||||||
|
update_time: _,
|
||||||
|
prev_downloaded_size: _,
|
||||||
|
downloaded_size,
|
||||||
|
total_size,
|
||||||
|
} => (
|
||||||
|
"txhashset_download".to_string(),
|
||||||
|
Some(json!({ "downloaded_size": downloaded_size, "total_size": total_size })),
|
||||||
|
),
|
||||||
|
SyncStatus::TxHashsetValidation {
|
||||||
|
kernels,
|
||||||
|
kernel_total,
|
||||||
|
rproofs,
|
||||||
|
rproof_total,
|
||||||
|
} => (
|
||||||
|
"txhashset_validation".to_string(),
|
||||||
|
Some(
|
||||||
|
json!({ "kernels": kernels, "kernel_total": kernel_total ,"rproofs": rproofs, "rproof_total": rproof_total }),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SyncStatus::BodySync {
|
||||||
|
current_height,
|
||||||
|
highest_height,
|
||||||
|
} => (
|
||||||
|
"body_sync".to_string(),
|
||||||
|
Some(json!({ "current_height": current_height, "highest_height": highest_height })),
|
||||||
|
),
|
||||||
|
SyncStatus::Shutdown => ("shutdown".to_string(), None),
|
||||||
|
// any other status is considered syncing (should be unreachable)
|
||||||
|
_ => ("syncing".to_string(), None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -79,15 +79,27 @@ pub struct Status {
|
||||||
pub connections: u32,
|
pub connections: u32,
|
||||||
// The state of the current fork Tip
|
// The state of the current fork Tip
|
||||||
pub tip: Tip,
|
pub tip: Tip,
|
||||||
|
// The current sync status
|
||||||
|
pub sync_status: String,
|
||||||
|
// Additional sync information
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub sync_info: Option<serde_json::Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Status {
|
impl Status {
|
||||||
pub fn from_tip_and_peers(current_tip: chain::Tip, connections: u32) -> Status {
|
pub fn from_tip_and_peers(
|
||||||
|
current_tip: chain::Tip,
|
||||||
|
connections: u32,
|
||||||
|
sync_status: String,
|
||||||
|
sync_info: Option<serde_json::Value>,
|
||||||
|
) -> Status {
|
||||||
Status {
|
Status {
|
||||||
protocol_version: ser::ProtocolVersion::local().into(),
|
protocol_version: ser::ProtocolVersion::local().into(),
|
||||||
user_agent: p2p::msg::USER_AGENT.to_string(),
|
user_agent: p2p::msg::USER_AGENT.to_string(),
|
||||||
connections: connections,
|
connections: connections,
|
||||||
tip: Tip::from_tip(current_tip),
|
tip: Tip::from_tip(current_tip),
|
||||||
|
sync_status,
|
||||||
|
sync_info,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ bitflags! {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Various status sync can be in, whether it's fast sync or archival.
|
/// Various status sync can be in, whether it's fast sync or archival.
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Deserialize, Serialize)]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub enum SyncStatus {
|
pub enum SyncStatus {
|
||||||
/// Initial State (we do not yet know if we are/should be syncing)
|
/// Initial State (we do not yet know if we are/should be syncing)
|
||||||
|
|
|
@ -290,6 +290,7 @@ impl Server {
|
||||||
shared_chain.clone(),
|
shared_chain.clone(),
|
||||||
tx_pool.clone(),
|
tx_pool.clone(),
|
||||||
p2p_server.peers.clone(),
|
p2p_server.peers.clone(),
|
||||||
|
sync_state.clone(),
|
||||||
api_secret,
|
api_secret,
|
||||||
tls_conf,
|
tls_conf,
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue