mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-01 17:01:09 +03:00
config to enable full chain validation per block (#839)
* default to full chain validation on processing each block (except during sync) * add sample config for chain_validation_mode * document chain_validation_mode
This commit is contained in:
parent
fc01a33d15
commit
ff4d68d2be
4 changed files with 63 additions and 1 deletions
|
@ -42,6 +42,12 @@ db_root = ".grin"
|
||||||
#
|
#
|
||||||
chain_type = "Testnet2"
|
chain_type = "Testnet2"
|
||||||
|
|
||||||
|
#The chain validation mode, defines how often (if at all) we
|
||||||
|
#want to run a full chain validation. Can be:
|
||||||
|
#EveryBlock - run full chain validation when processing each block (except during sync)
|
||||||
|
#Disabled - disable full chain validation (just run regular block validation)
|
||||||
|
#chain_validation_mode=EveryBlock
|
||||||
|
|
||||||
#run the node in "full archive" mode (default is fast-sync, pruned node)
|
#run the node in "full archive" mode (default is fast-sync, pruned node)
|
||||||
#archive_mode = false
|
#archive_mode = false
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ use std::net::SocketAddr;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::{Arc, RwLock, Weak};
|
use std::sync::{Arc, RwLock, Weak};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::time::Instant;
|
||||||
use rand;
|
use rand;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@ use p2p;
|
||||||
use pool;
|
use pool;
|
||||||
use util::OneTime;
|
use util::OneTime;
|
||||||
use store;
|
use store;
|
||||||
|
use types::{ChainValidationMode, ServerConfig};
|
||||||
use util::LOGGER;
|
use util::LOGGER;
|
||||||
|
|
||||||
// All adapters use `Weak` references instead of `Arc` to avoid cycles that
|
// All adapters use `Weak` references instead of `Arc` to avoid cycles that
|
||||||
|
@ -51,6 +53,7 @@ pub struct NetToChainAdapter {
|
||||||
chain: Weak<chain::Chain>,
|
chain: Weak<chain::Chain>,
|
||||||
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
|
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
|
||||||
peers: OneTime<Weak<p2p::Peers>>,
|
peers: OneTime<Weak<p2p::Peers>>,
|
||||||
|
config: ServerConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl p2p::ChainAdapter for NetToChainAdapter {
|
impl p2p::ChainAdapter for NetToChainAdapter {
|
||||||
|
@ -334,12 +337,14 @@ impl NetToChainAdapter {
|
||||||
currently_syncing: Arc<AtomicBool>,
|
currently_syncing: Arc<AtomicBool>,
|
||||||
chain_ref: Weak<chain::Chain>,
|
chain_ref: Weak<chain::Chain>,
|
||||||
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
|
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
|
||||||
|
config: ServerConfig,
|
||||||
) -> NetToChainAdapter {
|
) -> NetToChainAdapter {
|
||||||
NetToChainAdapter {
|
NetToChainAdapter {
|
||||||
currently_syncing: currently_syncing,
|
currently_syncing: currently_syncing,
|
||||||
chain: chain_ref,
|
chain: chain_ref,
|
||||||
tx_pool: tx_pool,
|
tx_pool: tx_pool,
|
||||||
peers: OneTime::new(),
|
peers: OneTime::new(),
|
||||||
|
config: config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,7 +393,7 @@ impl NetToChainAdapter {
|
||||||
let prev_hash = b.header.previous;
|
let prev_hash = b.header.previous;
|
||||||
let bhash = b.hash();
|
let bhash = b.hash();
|
||||||
let chain = w(&self.chain);
|
let chain = w(&self.chain);
|
||||||
match chain.process_block(b, self.chain_opts()) {
|
let result = match chain.process_block(b, self.chain_opts()) {
|
||||||
Ok(_) => true,
|
Ok(_) => true,
|
||||||
Err(chain::Error::Orphan) => {
|
Err(chain::Error::Orphan) => {
|
||||||
// make sure we did not miss the parent block
|
// make sure we did not miss the parent block
|
||||||
|
@ -415,7 +420,36 @@ impl NetToChainAdapter {
|
||||||
);
|
);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// If we are running in "validate the full chain every block" then
|
||||||
|
// panic here if validation fails for any reason.
|
||||||
|
// We are out of consensus at this point and want to track the problem
|
||||||
|
// down as soon as possible.
|
||||||
|
// Skip this if we are currently syncing (too slow).
|
||||||
|
if !self.currently_syncing.load(Ordering::Relaxed)
|
||||||
|
&& self.config.chain_validation_mode == ChainValidationMode::EveryBlock
|
||||||
|
{
|
||||||
|
let now = Instant::now();
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
LOGGER,
|
||||||
|
"adapter: process_block: ***** validating full chain state at {}", bhash,
|
||||||
|
);
|
||||||
|
|
||||||
|
let chain = w(&self.chain);
|
||||||
|
chain
|
||||||
|
.validate(true)
|
||||||
|
.expect("chain validation failed, hard stop");
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
LOGGER,
|
||||||
|
"adapter: process_block: ***** done validating full chain state, took {}s",
|
||||||
|
now.elapsed().as_secs(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
// After receiving a compact block if we cannot successfully hydrate
|
// After receiving a compact block if we cannot successfully hydrate
|
||||||
|
|
|
@ -120,6 +120,7 @@ impl Server {
|
||||||
currently_syncing.clone(),
|
currently_syncing.clone(),
|
||||||
Arc::downgrade(&shared_chain),
|
Arc::downgrade(&shared_chain),
|
||||||
tx_pool.clone(),
|
tx_pool.clone(),
|
||||||
|
config.clone(),
|
||||||
));
|
));
|
||||||
|
|
||||||
let p2p_config = config.p2p_config.clone();
|
let p2p_config = config.p2p_config.clone();
|
||||||
|
|
|
@ -86,6 +86,22 @@ impl From<wallet::Error> for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Type of seeding the server will use to find other peers on the network.
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub enum ChainValidationMode {
|
||||||
|
/// Run full chain validation after processing every block.
|
||||||
|
EveryBlock,
|
||||||
|
/// Do not automatically run chain validation during normal block
|
||||||
|
/// processing.
|
||||||
|
Disabled,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ChainValidationMode {
|
||||||
|
fn default() -> ChainValidationMode {
|
||||||
|
ChainValidationMode::EveryBlock
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Type of seeding the server will use to find other peers on the network.
|
/// Type of seeding the server will use to find other peers on the network.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
pub enum Seeding {
|
pub enum Seeding {
|
||||||
|
@ -122,6 +138,10 @@ pub struct ServerConfig {
|
||||||
/// Whether this node is a full archival node or a fast-sync, pruned node
|
/// Whether this node is a full archival node or a fast-sync, pruned node
|
||||||
pub archive_mode: Option<bool>,
|
pub archive_mode: Option<bool>,
|
||||||
|
|
||||||
|
/// Automatically run full chain validation during normal block processing?
|
||||||
|
#[serde(default)]
|
||||||
|
pub chain_validation_mode: ChainValidationMode,
|
||||||
|
|
||||||
/// Method used to get the list of seed nodes for initial bootstrap.
|
/// Method used to get the list of seed nodes for initial bootstrap.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub seeding_type: Seeding,
|
pub seeding_type: Seeding,
|
||||||
|
@ -169,6 +189,7 @@ impl Default for ServerConfig {
|
||||||
mining_config: Some(pow::types::MinerConfig::default()),
|
mining_config: Some(pow::types::MinerConfig::default()),
|
||||||
chain_type: ChainTypes::default(),
|
chain_type: ChainTypes::default(),
|
||||||
archive_mode: None,
|
archive_mode: None,
|
||||||
|
chain_validation_mode: ChainValidationMode::default(),
|
||||||
pool_config: pool::PoolConfig::default(),
|
pool_config: pool::PoolConfig::default(),
|
||||||
skip_sync_wait: None,
|
skip_sync_wait: None,
|
||||||
run_tui: None,
|
run_tui: None,
|
||||||
|
|
Loading…
Reference in a new issue