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

Move SyncStatus and SyncState to chain crate #2964

Merged
merged 3 commits into from
Jul 23, 2019
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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ failure_derive = "0.1"

grin_api = { path = "./api", version = "2.0.1-beta.1" }
grin_config = { path = "./config", version = "2.0.1-beta.1" }
grin_chain = { path = "./chain", version = "2.0.1-beta.1" }
grin_core = { path = "./core", version = "2.0.1-beta.1" }
grin_keychain = { path = "./keychain", version = "2.0.1-beta.1" }
grin_p2p = { path = "./p2p", version = "2.0.1-beta.1" }
Expand Down
3 changes: 3 additions & 0 deletions chain/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ pub enum ErrorKind {
/// Internal Roaring Bitmap error
#[fail(display = "Roaring Bitmap error")]
Bitmap,
/// Error during chain sync
#[fail(display = "Sync error")]
SyncError(String),
}

impl Display for Error {
Expand Down
4 changes: 3 additions & 1 deletion chain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,6 @@ pub mod types;
pub use crate::chain::{Chain, MAX_ORPHAN_SIZE};
pub use crate::error::{Error, ErrorKind};
pub use crate::store::ChainStore;
pub use crate::types::{BlockStatus, ChainAdapter, Options, Tip, TxHashsetWriteStatus};
pub use crate::types::{
BlockStatus, ChainAdapter, Options, SyncState, SyncStatus, Tip, TxHashsetWriteStatus,
};
170 changes: 170 additions & 0 deletions chain/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@

//! Base types that the block chain pipeline requires.

use chrono::prelude::{DateTime, Utc};
use std::sync::Arc;

use crate::core::core::hash::{Hash, Hashed, ZERO_HASH};
use crate::core::core::{Block, BlockHeader};
use crate::core::pow::Difficulty;
use crate::core::ser;
use crate::error::Error;
use crate::util::RwLock;

bitflags! {
/// Options for block validation
Expand All @@ -33,6 +38,171 @@ bitflags! {
}
}

/// Various status sync can be in, whether it's fast sync or archival.
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[allow(missing_docs)]
pub enum SyncStatus {
/// Initial State (we do not yet know if we are/should be syncing)
Initial,
/// Not syncing
NoSync,
/// Not enough peers to do anything yet, boolean indicates whether
/// we should wait at all or ignore and start ASAP
AwaitingPeers(bool),
/// Downloading block headers
HeaderSync {
current_height: u64,
highest_height: u64,
},
/// Downloading the various txhashsets
TxHashsetDownload {
start_time: DateTime<Utc>,
prev_update_time: DateTime<Utc>,
update_time: DateTime<Utc>,
prev_downloaded_size: u64,
downloaded_size: u64,
total_size: u64,
},
/// Setting up before validation
TxHashsetSetup,
/// Validating the full state
TxHashsetValidation {
kernels: u64,
kernel_total: u64,
rproofs: u64,
rproof_total: u64,
},
/// Finalizing the new state
TxHashsetSave,
/// State sync finalized
TxHashsetDone,
/// Downloading blocks
BodySync {
current_height: u64,
highest_height: u64,
},
Shutdown,
}

/// Current sync state. Encapsulates the current SyncStatus.
pub struct SyncState {
current: RwLock<SyncStatus>,
sync_error: Arc<RwLock<Option<Error>>>,
}

impl SyncState {
/// Return a new SyncState initialize to NoSync
pub fn new() -> SyncState {
SyncState {
current: RwLock::new(SyncStatus::Initial),
sync_error: Arc::new(RwLock::new(None)),
}
}

/// Whether the current state matches any active syncing operation.
/// Note: This includes our "initial" state.
pub fn is_syncing(&self) -> bool {
*self.current.read() != SyncStatus::NoSync
}

/// Current syncing status
pub fn status(&self) -> SyncStatus {
*self.current.read()
}

/// Update the syncing status
pub fn update(&self, new_status: SyncStatus) {
if self.status() == new_status {
return;
}

let mut status = self.current.write();

debug!("sync_state: sync_status: {:?} -> {:?}", *status, new_status,);

*status = new_status;
}

/// Update txhashset downloading progress
pub fn update_txhashset_download(&self, new_status: SyncStatus) -> bool {
if let SyncStatus::TxHashsetDownload { .. } = new_status {
let mut status = self.current.write();
*status = new_status;
true
} else {
false
}
}

/// Communicate sync error
pub fn set_sync_error(&self, error: Error) {
*self.sync_error.write() = Some(error);
}

/// Get sync error
pub fn sync_error(&self) -> Arc<RwLock<Option<Error>>> {
Arc::clone(&self.sync_error)
}

/// Clear sync error
pub fn clear_sync_error(&self) {
*self.sync_error.write() = None;
}
}

impl TxHashsetWriteStatus for SyncState {
fn on_setup(&self) {
self.update(SyncStatus::TxHashsetSetup);
}

fn on_validation(&self, vkernels: u64, vkernel_total: u64, vrproofs: u64, vrproof_total: u64) {
let mut status = self.current.write();
match *status {
SyncStatus::TxHashsetValidation {
kernels,
kernel_total,
rproofs,
rproof_total,
} => {
let ks = if vkernels > 0 { vkernels } else { kernels };
let kt = if vkernel_total > 0 {
vkernel_total
} else {
kernel_total
};
let rps = if vrproofs > 0 { vrproofs } else { rproofs };
let rpt = if vrproof_total > 0 {
vrproof_total
} else {
rproof_total
};
*status = SyncStatus::TxHashsetValidation {
kernels: ks,
kernel_total: kt,
rproofs: rps,
rproof_total: rpt,
};
}
_ => {
*status = SyncStatus::TxHashsetValidation {
kernels: 0,
kernel_total: 0,
rproofs: 0,
rproof_total: 0,
}
}
}
}

fn on_save(&self) {
self.update(SyncStatus::TxHashsetSave);
}

fn on_done(&self) {
self.update(SyncStatus::TxHashsetDone);
}
}

/// A helper to hold the roots of the txhashset in order to keep them
/// readable.
#[derive(Debug)]
Expand Down
14 changes: 8 additions & 6 deletions servers/src/common/adapters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ use std::sync::{Arc, Weak};
use std::thread;
use std::time::Instant;

use crate::chain::{self, BlockStatus, ChainAdapter, Options};
use crate::chain::{self, BlockStatus, ChainAdapter, Options, SyncState, SyncStatus};
use crate::common::hooks::{ChainEvents, NetEvents};
use crate::common::types::{
self, ChainValidationMode, DandelionEpoch, ServerConfig, SyncState, SyncStatus,
};
use crate::common::types::{ChainValidationMode, DandelionEpoch, ServerConfig};
use crate::core::core::hash::{Hash, Hashed};
use crate::core::core::transaction::Transaction;
use crate::core::core::verifier_cache::VerifierCache;
Expand Down Expand Up @@ -251,7 +249,11 @@ impl p2p::ChainAdapter for NetToChainAdapter {
.process_block_header(&bh, self.chain_opts(false));

if let Err(e) = res {
debug!("Block header {} refused by chain: {:?}", bh.hash(), e.kind());
debug!(
"Block header {} refused by chain: {:?}",
bh.hash(),
e.kind()
);
if e.is_bad_data() {
return Ok(false);
} else {
Expand Down Expand Up @@ -428,7 +430,7 @@ impl p2p::ChainAdapter for NetToChainAdapter {
error!("Failed to save txhashset archive: {}", e);

let is_good_data = !e.is_bad_data();
self.sync_state.set_sync_error(types::Error::Chain(e));
self.sync_state.set_sync_error(e);
Ok(is_good_data)
} else {
info!("Received valid txhashset data for {}.", h);
Expand Down
2 changes: 1 addition & 1 deletion servers/src/common/stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::core::ser::ProtocolVersion;
use chrono::prelude::*;

use crate::chain;
use crate::common::types::SyncStatus;
use crate::chain::SyncStatus;
use crate::p2p;

/// Server state info collection struct, to be passed around into internals
Expand Down
Loading