Add sync_status in status Node API (#2966)

* Add sync_status in status Node API
This commit is contained in:
Quentin Le Sceller 2019-09-17 11:12:42 -04:00 committed by GitHub
parent 28d5ee8242
commit b209244d17
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 75 additions and 5 deletions

View file

@ -62,11 +62,13 @@ pub fn start_rest_apis(
chain: Arc<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool>>,
peers: Arc<p2p::Peers>,
sync_state: Arc<chain::SyncState>,
api_secret: Option<String>,
tls_config: Option<TLSConfig>,
) -> bool {
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 {
let api_basic_auth = format!("Basic {}", util::to_base64(&format!("grin:{}", api_secret)));
let basic_auth_middleware = Arc::new(BasicAuthMiddleware::new(
@ -93,6 +95,7 @@ pub fn build_router(
chain: Arc<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool>>,
peers: Arc<p2p::Peers>,
sync_state: Arc<chain::SyncState>,
) -> Result<Router, RouterError> {
let route_list = vec![
"get blocks".to_string(),
@ -144,6 +147,7 @@ pub fn build_router(
let status_handler = StatusHandler {
chain: Arc::downgrade(&chain),
peers: Arc::downgrade(&peers),
sync_state: Arc::downgrade(&sync_state),
};
let kernel_download_handler = KernelDownloadHandler {
peers: Arc::downgrade(&peers),

View file

@ -13,13 +13,14 @@
// limitations under the License.
use super::utils::w;
use crate::chain;
use crate::chain::{Chain, SyncState, SyncStatus};
use crate::p2p;
use crate::rest::*;
use crate::router::{Handler, ResponseFuture};
use crate::types::*;
use crate::web::*;
use hyper::{Body, Request, StatusCode};
use serde_json::json;
use std::sync::Weak;
// RESTful index of available api endpoints
@ -62,8 +63,9 @@ impl Handler for KernelDownloadHandler {
/// Status handler. Post a summary of the server status
/// GET /v1/status
pub struct StatusHandler {
pub chain: Weak<chain::Chain>,
pub chain: Weak<Chain>,
pub peers: Weak<p2p::Peers>,
pub sync_state: Weak<SyncState>,
}
impl StatusHandler {
@ -71,9 +73,13 @@ impl StatusHandler {
let head = w(&self.chain)?
.head()
.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(
head,
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())
}
}
/// 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),
}
}

View file

@ -79,15 +79,27 @@ pub struct Status {
pub connections: u32,
// The state of the current fork 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 {
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 {
protocol_version: ser::ProtocolVersion::local().into(),
user_agent: p2p::msg::USER_AGENT.to_string(),
connections: connections,
tip: Tip::from_tip(current_tip),
sync_status,
sync_info,
}
}
}

View file

@ -39,7 +39,7 @@ bitflags! {
}
/// 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)]
pub enum SyncStatus {
/// Initial State (we do not yet know if we are/should be syncing)

View file

@ -290,6 +290,7 @@ impl Server {
shared_chain.clone(),
tx_pool.clone(),
p2p_server.peers.clone(),
sync_state.clone(),
api_secret,
tls_conf,
);