Prometheus, heavy memory calls removed (#27)
This commit is contained in:
@@ -47,7 +47,7 @@ log = "0.4"
|
||||
lru-cache = "0.1"
|
||||
macros = { path = "../util/macros" }
|
||||
memory-cache = { path = "../util/memory-cache" }
|
||||
memory-db = "0.11"
|
||||
memory-db = { path = "../util/memory-db" }
|
||||
num_cpus = "1.2"
|
||||
parity-bytes = "0.1"
|
||||
parity-snappy = "0.1"
|
||||
|
||||
@@ -171,7 +171,7 @@ impl IoHandler<ClientIoMessage> for ClientIoHandler {
|
||||
CLIENT_TICK_TIMER => {
|
||||
use ethcore::snapshot::SnapshotService;
|
||||
let snapshot_restoration =
|
||||
if let RestorationStatus::Ongoing { .. } = self.snapshot.status() {
|
||||
if let RestorationStatus::Ongoing { .. } = self.snapshot.restoration_status() {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
||||
@@ -85,6 +85,7 @@ use snapshot::{self, io as snapshot_io, SnapshotClient};
|
||||
use spec::Spec;
|
||||
use state::{self, State};
|
||||
use state_db::StateDB;
|
||||
use stats::{prometheus, prometheus_counter, prometheus_gauge, PrometheusMetrics};
|
||||
use trace::{
|
||||
self, Database as TraceDatabase, ImportRequest as TraceImportRequest, LocalizedTrace, TraceDB,
|
||||
};
|
||||
@@ -118,8 +119,8 @@ pub struct ClientReport {
|
||||
pub transactions_applied: usize,
|
||||
/// How much gas has been processed so far.
|
||||
pub gas_processed: U256,
|
||||
/// Memory used by state DB
|
||||
pub state_db_mem: usize,
|
||||
/// Internal structure item sizes
|
||||
pub item_sizes: BTreeMap<String, usize>,
|
||||
}
|
||||
|
||||
impl ClientReport {
|
||||
@@ -135,13 +136,9 @@ impl<'a> ::std::ops::Sub<&'a ClientReport> for ClientReport {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(mut self, other: &'a ClientReport) -> Self {
|
||||
let higher_mem = ::std::cmp::max(self.state_db_mem, other.state_db_mem);
|
||||
let lower_mem = ::std::cmp::min(self.state_db_mem, other.state_db_mem);
|
||||
|
||||
self.blocks_imported -= other.blocks_imported;
|
||||
self.transactions_applied -= other.transactions_applied;
|
||||
self.gas_processed = self.gas_processed - other.gas_processed;
|
||||
self.state_db_mem = higher_mem - lower_mem;
|
||||
|
||||
self
|
||||
}
|
||||
@@ -1245,7 +1242,7 @@ impl Client {
|
||||
/// Get the report.
|
||||
pub fn report(&self) -> ClientReport {
|
||||
let mut report = self.report.read().clone();
|
||||
report.state_db_mem = self.state_db.read().mem_used();
|
||||
self.state_db.read().get_sizes(&mut report.item_sizes);
|
||||
report
|
||||
}
|
||||
|
||||
@@ -3183,6 +3180,163 @@ impl IoChannelQueue {
|
||||
}
|
||||
}
|
||||
|
||||
impl PrometheusMetrics for Client {
|
||||
fn prometheus_metrics(&self, r: &mut prometheus::Registry) {
|
||||
// gas, tx & blocks
|
||||
let report = self.report();
|
||||
|
||||
for (key, value) in report.item_sizes.iter() {
|
||||
prometheus_gauge(
|
||||
r,
|
||||
&key,
|
||||
format!("Total item number of {}", key).as_str(),
|
||||
*value as i64,
|
||||
);
|
||||
}
|
||||
|
||||
prometheus_counter(
|
||||
r,
|
||||
"import_gas",
|
||||
"Gas processed",
|
||||
report.gas_processed.as_u64() as i64,
|
||||
);
|
||||
prometheus_counter(
|
||||
r,
|
||||
"import_blocks",
|
||||
"Blocks imported",
|
||||
report.blocks_imported as i64,
|
||||
);
|
||||
prometheus_counter(
|
||||
r,
|
||||
"import_txs",
|
||||
"Transactions applied",
|
||||
report.transactions_applied as i64,
|
||||
);
|
||||
|
||||
let state_db = self.state_db.read();
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"statedb_cache_size",
|
||||
"State DB cache size",
|
||||
state_db.cache_size() as i64,
|
||||
);
|
||||
|
||||
// blockchain cache
|
||||
let blockchain_cache_info = self.blockchain_cache_info();
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"blockchaincache_block_details",
|
||||
"BlockDetails cache size",
|
||||
blockchain_cache_info.block_details as i64,
|
||||
);
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"blockchaincache_block_recipts",
|
||||
"Block receipts size",
|
||||
blockchain_cache_info.block_receipts as i64,
|
||||
);
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"blockchaincache_blocks",
|
||||
"Blocks cache size",
|
||||
blockchain_cache_info.blocks as i64,
|
||||
);
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"blockchaincache_txaddrs",
|
||||
"Transaction addresses cache size",
|
||||
blockchain_cache_info.transaction_addresses as i64,
|
||||
);
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"blockchaincache_size",
|
||||
"Total blockchain cache size",
|
||||
blockchain_cache_info.total() as i64,
|
||||
);
|
||||
|
||||
// chain info
|
||||
let chain = self.chain_info();
|
||||
|
||||
let gap = chain
|
||||
.ancient_block_number
|
||||
.map(|x| U256::from(x + 1))
|
||||
.and_then(|first| {
|
||||
chain
|
||||
.first_block_number
|
||||
.map(|last| (first, U256::from(last)))
|
||||
});
|
||||
if let Some((first, last)) = gap {
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"chain_warpsync_gap_first",
|
||||
"Warp sync gap, first block",
|
||||
first.as_u64() as i64,
|
||||
);
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"chain_warpsync_gap_last",
|
||||
"Warp sync gap, last block",
|
||||
last.as_u64() as i64,
|
||||
);
|
||||
}
|
||||
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"chain_block",
|
||||
"Best block number",
|
||||
chain.best_block_number as i64,
|
||||
);
|
||||
|
||||
// prunning info
|
||||
let prunning = self.pruning_info();
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"prunning_earliest_chain",
|
||||
"The first block which everything can be served after",
|
||||
prunning.earliest_chain as i64,
|
||||
);
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"prunning_earliest_state",
|
||||
"The first block where state requests may be served",
|
||||
prunning.earliest_state as i64,
|
||||
);
|
||||
|
||||
// queue info
|
||||
let queue = self.queue_info();
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"queue_mem_used",
|
||||
"Queue heap memory used in bytes",
|
||||
queue.mem_used as i64,
|
||||
);
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"queue_size_total",
|
||||
"The total size of the queues",
|
||||
queue.total_queue_size() as i64,
|
||||
);
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"queue_size_unverified",
|
||||
"Number of queued items pending verification",
|
||||
queue.unverified_queue_size as i64,
|
||||
);
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"queue_size_verified",
|
||||
"Number of verified queued items pending import",
|
||||
queue.verified_queue_size as i64,
|
||||
);
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"queue_size_verifying",
|
||||
"Number of items being verified",
|
||||
queue.verifying_queue_size as i64,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use blockchain::{BlockProvider, ExtrasInsert};
|
||||
|
||||
@@ -72,6 +72,7 @@ use miner::{self, Miner, MinerService};
|
||||
use spec::Spec;
|
||||
use state::StateInfo;
|
||||
use state_db::StateDB;
|
||||
use stats::{prometheus, PrometheusMetrics};
|
||||
use trace::LocalizedTrace;
|
||||
use verification::queue::{kind::blocks::Unverified, QueueInfo};
|
||||
|
||||
@@ -1114,3 +1115,7 @@ impl super::traits::EngineClient for TestBlockChainClient {
|
||||
BlockChainClient::block_header(self, id)
|
||||
}
|
||||
}
|
||||
|
||||
impl PrometheusMetrics for TestBlockChainClient {
|
||||
fn prometheus_metrics(&self, _r: &mut prometheus::Registry) {}
|
||||
}
|
||||
|
||||
@@ -64,8 +64,8 @@ pub use self::{
|
||||
watcher::Watcher,
|
||||
};
|
||||
pub use types::{
|
||||
basic_account::BasicAccount, restoration_status::RestorationStatus,
|
||||
snapshot_manifest::ManifestData,
|
||||
basic_account::BasicAccount, creation_status::CreationStatus,
|
||||
restoration_status::RestorationStatus, snapshot_manifest::ManifestData,
|
||||
};
|
||||
|
||||
pub mod io;
|
||||
|
||||
@@ -30,7 +30,8 @@ use std::{
|
||||
|
||||
use super::{
|
||||
io::{LooseReader, LooseWriter, SnapshotReader, SnapshotWriter},
|
||||
ManifestData, Rebuilder, RestorationStatus, SnapshotService, StateRebuilder, MAX_CHUNK_SIZE,
|
||||
CreationStatus, ManifestData, Rebuilder, RestorationStatus, SnapshotService, StateRebuilder,
|
||||
MAX_CHUNK_SIZE,
|
||||
};
|
||||
|
||||
use blockchain::{BlockChain, BlockChainDB, BlockChainDBHandler};
|
||||
@@ -271,6 +272,7 @@ pub struct Service {
|
||||
client: Arc<dyn SnapshotClient>,
|
||||
progress: super::Progress,
|
||||
taking_snapshot: AtomicBool,
|
||||
taking_snapshot_at: AtomicUsize,
|
||||
restoring_snapshot: AtomicBool,
|
||||
}
|
||||
|
||||
@@ -292,6 +294,7 @@ impl Service {
|
||||
client: params.client,
|
||||
progress: Default::default(),
|
||||
taking_snapshot: AtomicBool::new(false),
|
||||
taking_snapshot_at: AtomicUsize::new(0),
|
||||
restoring_snapshot: AtomicBool::new(false),
|
||||
};
|
||||
|
||||
@@ -522,6 +525,9 @@ impl Service {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
self.taking_snapshot_at
|
||||
.store(num as usize, Ordering::SeqCst);
|
||||
|
||||
info!("Taking snapshot at #{}", num);
|
||||
self.progress.reset();
|
||||
|
||||
@@ -629,6 +635,7 @@ impl Service {
|
||||
|
||||
self.restoring_snapshot.store(true, Ordering::SeqCst);
|
||||
|
||||
let block_number = manifest.block_number;
|
||||
// Import previous chunks, continue if it fails
|
||||
self.import_prev_chunks(&mut res, manifest).ok();
|
||||
|
||||
@@ -636,6 +643,7 @@ impl Service {
|
||||
let mut restoration_status = self.status.lock();
|
||||
if let RestorationStatus::Initializing { .. } = *restoration_status {
|
||||
*restoration_status = RestorationStatus::Ongoing {
|
||||
block_number,
|
||||
state_chunks: state_chunks as u32,
|
||||
block_chunks: block_chunks as u32,
|
||||
state_chunks_done: self.state_chunks.load(Ordering::SeqCst) as u32,
|
||||
@@ -774,7 +782,7 @@ impl Service {
|
||||
is_state: bool,
|
||||
) -> Result<(), Error> {
|
||||
let (result, db) = {
|
||||
match self.status() {
|
||||
match self.restoration_status() {
|
||||
RestorationStatus::Inactive | RestorationStatus::Failed => {
|
||||
trace!(target: "snapshot", "Tried to restore chunk {:x} while inactive or failed", hash);
|
||||
return Ok(());
|
||||
@@ -881,7 +889,17 @@ impl SnapshotService for Service {
|
||||
}
|
||||
}
|
||||
|
||||
fn status(&self) -> RestorationStatus {
|
||||
fn creation_status(&self) -> CreationStatus {
|
||||
if self.taking_snapshot.load(Ordering::SeqCst) {
|
||||
CreationStatus::Ongoing {
|
||||
block_number: self.taking_snapshot_at.load(Ordering::SeqCst) as u32,
|
||||
}
|
||||
} else {
|
||||
CreationStatus::Inactive
|
||||
}
|
||||
}
|
||||
|
||||
fn restoration_status(&self) -> RestorationStatus {
|
||||
let mut cur_status = self.status.lock();
|
||||
|
||||
match *cur_status {
|
||||
@@ -1003,7 +1021,7 @@ mod tests {
|
||||
|
||||
assert!(service.manifest().is_none());
|
||||
assert!(service.chunk(Default::default()).is_none());
|
||||
assert_eq!(service.status(), RestorationStatus::Inactive);
|
||||
assert_eq!(service.restoration_status(), RestorationStatus::Inactive);
|
||||
|
||||
let manifest = ManifestData {
|
||||
version: 2,
|
||||
|
||||
@@ -95,7 +95,7 @@ fn restored_is_equivalent() {
|
||||
service.feed_block_chunk(hash, &chunk);
|
||||
}
|
||||
|
||||
assert_eq!(service.status(), RestorationStatus::Inactive);
|
||||
assert_eq!(service.restoration_status(), RestorationStatus::Inactive);
|
||||
|
||||
for x in 0..NUM_BLOCKS {
|
||||
let block1 = client.block(BlockId::Number(x as u64)).unwrap();
|
||||
@@ -265,7 +265,7 @@ fn keep_ancient_blocks() {
|
||||
service.feed_state_chunk(*hash, &chunk);
|
||||
}
|
||||
|
||||
match service.status() {
|
||||
match service.restoration_status() {
|
||||
RestorationStatus::Inactive => (),
|
||||
RestorationStatus::Failed => panic!("Snapshot Restoration has failed."),
|
||||
RestorationStatus::Ongoing { .. } => panic!("Snapshot Restoration should be done."),
|
||||
@@ -334,7 +334,7 @@ fn recover_aborted_recovery() {
|
||||
service.feed_state_chunk(*hash, &chunk);
|
||||
}
|
||||
|
||||
match service.status() {
|
||||
match service.restoration_status() {
|
||||
RestorationStatus::Ongoing {
|
||||
block_chunks_done,
|
||||
state_chunks_done,
|
||||
@@ -352,7 +352,7 @@ fn recover_aborted_recovery() {
|
||||
// And try again!
|
||||
service.init_restore(manifest.clone(), true).unwrap();
|
||||
|
||||
match service.status() {
|
||||
match service.restoration_status() {
|
||||
RestorationStatus::Ongoing {
|
||||
block_chunks_done,
|
||||
state_chunks_done,
|
||||
@@ -371,7 +371,7 @@ fn recover_aborted_recovery() {
|
||||
// And try again!
|
||||
service.init_restore(manifest.clone(), true).unwrap();
|
||||
|
||||
match service.status() {
|
||||
match service.restoration_status() {
|
||||
RestorationStatus::Ongoing {
|
||||
block_chunks_done,
|
||||
state_chunks_done,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use super::{ManifestData, RestorationStatus};
|
||||
use super::{CreationStatus, ManifestData, RestorationStatus};
|
||||
use bytes::Bytes;
|
||||
use ethereum_types::H256;
|
||||
|
||||
@@ -37,7 +37,10 @@ pub trait SnapshotService: Sync + Send {
|
||||
fn chunk(&self, hash: H256) -> Option<Bytes>;
|
||||
|
||||
/// Ask the snapshot service for the restoration status.
|
||||
fn status(&self) -> RestorationStatus;
|
||||
fn restoration_status(&self) -> RestorationStatus;
|
||||
|
||||
/// Ask the snapshot service for the creation status.
|
||||
fn creation_status(&self) -> CreationStatus;
|
||||
|
||||
/// Begin snapshot restoration.
|
||||
/// If restoration in-progress, this will reset it.
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
//! State database abstraction. For more info, see the doc for `StateDB`
|
||||
|
||||
use std::{
|
||||
collections::{HashSet, VecDeque},
|
||||
collections::{BTreeMap, HashSet, VecDeque},
|
||||
io,
|
||||
sync::Arc,
|
||||
};
|
||||
@@ -394,13 +394,17 @@ impl StateDB {
|
||||
}
|
||||
|
||||
/// Heap size used.
|
||||
pub fn mem_used(&self) -> usize {
|
||||
// TODO: account for LRU-cache overhead; this is a close approximation.
|
||||
self.db.mem_used() + {
|
||||
let accounts = self.account_cache.lock().accounts.len();
|
||||
let code_size = self.code_cache.lock().current_size();
|
||||
code_size + accounts * ::std::mem::size_of::<Option<Account>>()
|
||||
}
|
||||
pub fn get_sizes(&self, sizes: &mut BTreeMap<String, usize>) {
|
||||
self.db.get_sizes(sizes);
|
||||
|
||||
sizes.insert(
|
||||
String::from("account_cache_len"),
|
||||
self.account_cache.lock().accounts.len(),
|
||||
);
|
||||
sizes.insert(
|
||||
String::from("code_cache_size"),
|
||||
self.code_cache.lock().current_size(),
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns underlying `JournalDB`.
|
||||
|
||||
@@ -32,6 +32,8 @@ rand = "0.4"
|
||||
rlp = { version = "0.3.0", features = ["ethereum"] }
|
||||
trace-time = "0.1"
|
||||
triehash-ethereum = {version = "0.2", path = "../../util/triehash-ethereum" }
|
||||
stats = { path = "../../util/stats" }
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
env_logger = "0.5"
|
||||
|
||||
@@ -30,8 +30,8 @@ use std::{
|
||||
};
|
||||
|
||||
use chain::{
|
||||
ChainSyncApi, SyncStatus as EthSyncStatus, ETH_PROTOCOL_VERSION_62, ETH_PROTOCOL_VERSION_63,
|
||||
PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_2,
|
||||
ChainSyncApi, SyncState, SyncStatus as EthSyncStatus, ETH_PROTOCOL_VERSION_62,
|
||||
ETH_PROTOCOL_VERSION_63, PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_2,
|
||||
};
|
||||
use ethcore::{
|
||||
client::{BlockChainClient, ChainMessageType, ChainNotify, NewBlocks},
|
||||
@@ -42,12 +42,17 @@ use ethkey::Secret;
|
||||
use io::TimerToken;
|
||||
use network::IpFilter;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use stats::{prometheus, prometheus_counter, prometheus_gauge, PrometheusMetrics};
|
||||
|
||||
use std::{
|
||||
net::{AddrParseError, SocketAddr},
|
||||
str::FromStr,
|
||||
};
|
||||
use sync_io::NetSyncIo;
|
||||
use types::{transaction::UnverifiedTransaction, BlockNumber};
|
||||
use types::{
|
||||
creation_status::CreationStatus, restoration_status::RestorationStatus,
|
||||
transaction::UnverifiedTransaction, BlockNumber,
|
||||
};
|
||||
|
||||
/// Parity sync protocol
|
||||
pub const PAR_PROTOCOL: ProtocolId = *b"par";
|
||||
@@ -120,7 +125,7 @@ impl Default for SyncConfig {
|
||||
}
|
||||
|
||||
/// Current sync status
|
||||
pub trait SyncProvider: Send + Sync {
|
||||
pub trait SyncProvider: Send + Sync + PrometheusMetrics {
|
||||
/// Get sync status
|
||||
fn status(&self) -> EthSyncStatus;
|
||||
|
||||
@@ -311,6 +316,110 @@ impl SyncProvider for EthSync {
|
||||
}
|
||||
}
|
||||
|
||||
impl PrometheusMetrics for EthSync {
|
||||
fn prometheus_metrics(&self, r: &mut prometheus::Registry) {
|
||||
let scalar = |b| if b { 1i64 } else { 0i64 };
|
||||
let sync_status = self.status();
|
||||
|
||||
prometheus_gauge(r,
|
||||
"sync_status",
|
||||
"WaitingPeers(0), SnapshotManifest(1), SnapshotData(2), SnapshotWaiting(3), Blocks(4), Idle(5), Waiting(6), NewBlocks(7)",
|
||||
match self.eth_handler.sync.status().state {
|
||||
SyncState::WaitingPeers => 0,
|
||||
SyncState::SnapshotManifest => 1,
|
||||
SyncState::SnapshotData => 2,
|
||||
SyncState::SnapshotWaiting => 3,
|
||||
SyncState::Blocks => 4,
|
||||
SyncState::Idle => 5,
|
||||
SyncState::Waiting => 6,
|
||||
SyncState::NewBlocks => 7,
|
||||
});
|
||||
|
||||
for (key, value) in sync_status.item_sizes.iter() {
|
||||
prometheus_gauge(
|
||||
r,
|
||||
&key,
|
||||
format!("Total item number of {}", key).as_str(),
|
||||
*value as i64,
|
||||
);
|
||||
}
|
||||
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"net_peers",
|
||||
"Total number of connected peers",
|
||||
sync_status.num_peers as i64,
|
||||
);
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"net_active_peers",
|
||||
"Total number of active peers",
|
||||
sync_status.num_active_peers as i64,
|
||||
);
|
||||
prometheus_counter(
|
||||
r,
|
||||
"sync_blocks_recieved",
|
||||
"Number of blocks downloaded so far",
|
||||
sync_status.blocks_received as i64,
|
||||
);
|
||||
prometheus_counter(
|
||||
r,
|
||||
"sync_blocks_total",
|
||||
"Total number of blocks for the sync process",
|
||||
sync_status.blocks_total as i64,
|
||||
);
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"sync_blocks_highest",
|
||||
"Highest block number in the download queue",
|
||||
sync_status.highest_block_number.unwrap_or(0) as i64,
|
||||
);
|
||||
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"snapshot_download_active",
|
||||
"1 if downloading snapshots",
|
||||
scalar(sync_status.is_snapshot_syncing()),
|
||||
);
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"snapshot_download_chunks",
|
||||
"Snapshot chunks",
|
||||
sync_status.num_snapshot_chunks as i64,
|
||||
);
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"snapshot_download_chunks_done",
|
||||
"Snapshot chunks downloaded",
|
||||
sync_status.snapshot_chunks_done as i64,
|
||||
);
|
||||
|
||||
let restoration = self.eth_handler.snapshot_service.restoration_status();
|
||||
let creation = self.eth_handler.snapshot_service.creation_status();
|
||||
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"snapshot_create_block",
|
||||
"First block of the current snapshot creation",
|
||||
if let CreationStatus::Ongoing { block_number } = creation {
|
||||
block_number as i64
|
||||
} else {
|
||||
0
|
||||
},
|
||||
);
|
||||
prometheus_gauge(
|
||||
r,
|
||||
"snapshot_restore_block",
|
||||
"First block of the current snapshot restoration",
|
||||
if let RestorationStatus::Ongoing { block_number, .. } = restoration {
|
||||
block_number as i64
|
||||
} else {
|
||||
0
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const PEERS_TIMER: TimerToken = 0;
|
||||
const MAINTAIN_SYNC_TIMER: TimerToken = 1;
|
||||
const CONTINUE_SYNC_TIMER: TimerToken = 2;
|
||||
|
||||
@@ -24,14 +24,13 @@ use ethcore::{
|
||||
},
|
||||
};
|
||||
use ethereum_types::H256;
|
||||
use heapsize::HeapSizeOf;
|
||||
use network::{client_version::ClientCapabilities, PeerId};
|
||||
use rlp::{self, Rlp};
|
||||
use std::cmp;
|
||||
///
|
||||
/// Blockchain downloader
|
||||
///
|
||||
use std::collections::{HashSet, VecDeque};
|
||||
use std::collections::{BTreeMap, HashSet, VecDeque};
|
||||
use sync_io::SyncIo;
|
||||
use types::BlockNumber;
|
||||
|
||||
@@ -218,9 +217,14 @@ impl BlockDownloader {
|
||||
self.state = State::Blocks;
|
||||
}
|
||||
|
||||
/// Returns used heap memory size.
|
||||
pub fn heap_size(&self) -> usize {
|
||||
self.blocks.heap_size() + self.round_parents.heap_size_of_children()
|
||||
/// Returns number if items in structures
|
||||
pub fn get_sizes(&self, sizes: &mut BTreeMap<String, usize>) {
|
||||
let prefix = format!("{}_", self.block_set.to_string());
|
||||
self.blocks.get_sizes(sizes, &prefix);
|
||||
sizes.insert(
|
||||
format!("{}{}", prefix, "round_parents"),
|
||||
self.round_parents.len(),
|
||||
);
|
||||
}
|
||||
|
||||
fn reset_to_block(&mut self, start_hash: &H256, start_number: BlockNumber) {
|
||||
|
||||
@@ -21,7 +21,7 @@ use hash::{keccak, KECCAK_EMPTY_LIST_RLP, KECCAK_NULL_RLP};
|
||||
use heapsize::HeapSizeOf;
|
||||
use network;
|
||||
use rlp::{DecoderError, Rlp, RlpStream};
|
||||
use std::collections::{hash_map, HashMap, HashSet};
|
||||
use std::collections::{hash_map, BTreeMap, HashMap, HashSet};
|
||||
use triehash_ethereum::ordered_trie_root;
|
||||
use types::{header::Header as BlockHeader, transaction::UnverifiedTransaction};
|
||||
|
||||
@@ -414,14 +414,37 @@ impl BlockCollection {
|
||||
self.heads.len()
|
||||
}
|
||||
|
||||
/// Return used heap size.
|
||||
pub fn heap_size(&self) -> usize {
|
||||
self.heads.heap_size_of_children()
|
||||
+ self.blocks.heap_size_of_children()
|
||||
+ self.parents.heap_size_of_children()
|
||||
+ self.header_ids.heap_size_of_children()
|
||||
+ self.downloading_headers.heap_size_of_children()
|
||||
+ self.downloading_bodies.heap_size_of_children()
|
||||
/// Return number of items size.
|
||||
pub fn get_sizes(&self, sizes: &mut BTreeMap<String, usize>, insert_prefix: &str) {
|
||||
sizes.insert(format!("{}{}", insert_prefix, "heads"), self.heads.len());
|
||||
sizes.insert(format!("{}{}", insert_prefix, "blocks"), self.blocks.len());
|
||||
sizes.insert(
|
||||
format!("{}{}", insert_prefix, "parents_len"),
|
||||
self.parents.len(),
|
||||
);
|
||||
sizes.insert(
|
||||
format!("{}{}", insert_prefix, "header_ids_len"),
|
||||
self.header_ids.len(),
|
||||
);
|
||||
sizes.insert(
|
||||
format!("{}{}", insert_prefix, "downloading_headers_len"),
|
||||
self.downloading_headers.len(),
|
||||
);
|
||||
sizes.insert(
|
||||
format!("{}{}", insert_prefix, "downloading_bodies_len"),
|
||||
self.downloading_bodies.len(),
|
||||
);
|
||||
|
||||
if self.need_receipts {
|
||||
sizes.insert(
|
||||
format!("{}{}", insert_prefix, "downloading_receipts_len"),
|
||||
self.downloading_receipts.len(),
|
||||
);
|
||||
sizes.insert(
|
||||
format!("{}{}", insert_prefix, "receipt_ids_len"),
|
||||
self.receipt_ids.len(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if given block hash is marked as being downloaded.
|
||||
|
||||
@@ -599,7 +599,7 @@ impl SyncHandler {
|
||||
}
|
||||
|
||||
// check service status
|
||||
let status = io.snapshot_service().status();
|
||||
let status = io.snapshot_service().restoration_status();
|
||||
match status {
|
||||
RestorationStatus::Inactive | RestorationStatus::Failed => {
|
||||
trace!(target: "sync", "{}: Snapshot restoration aborted", peer_id);
|
||||
|
||||
@@ -105,7 +105,6 @@ use ethcore::{
|
||||
use ethereum_types::{H256, U256};
|
||||
use fastmap::{H256FastMap, H256FastSet};
|
||||
use hash::keccak;
|
||||
use heapsize::HeapSizeOf;
|
||||
use network::{self, client_version::ClientVersion, PeerId};
|
||||
use parking_lot::{Mutex, RwLock, RwLockWriteGuard};
|
||||
use rand::Rng;
|
||||
@@ -214,7 +213,7 @@ pub enum SyncState {
|
||||
}
|
||||
|
||||
/// Syncing status and statistics
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone)]
|
||||
pub struct SyncStatus {
|
||||
/// State
|
||||
pub state: SyncState,
|
||||
@@ -236,14 +235,14 @@ pub struct SyncStatus {
|
||||
pub num_peers: usize,
|
||||
/// Total number of active peers.
|
||||
pub num_active_peers: usize,
|
||||
/// Heap memory used in bytes.
|
||||
pub mem_used: usize,
|
||||
/// Snapshot chunks
|
||||
pub num_snapshot_chunks: usize,
|
||||
/// Snapshot chunks downloaded
|
||||
pub snapshot_chunks_done: usize,
|
||||
/// Last fully downloaded and imported ancient block number (if any).
|
||||
pub last_imported_old_block_number: Option<BlockNumber>,
|
||||
/// Internal structure item numbers
|
||||
pub item_sizes: BTreeMap<String, usize>,
|
||||
}
|
||||
|
||||
impl SyncStatus {
|
||||
@@ -297,6 +296,16 @@ pub enum BlockSet {
|
||||
/// Missing old blocks
|
||||
OldBlocks,
|
||||
}
|
||||
|
||||
impl BlockSet {
|
||||
pub fn to_string(&self) -> &'static str {
|
||||
match *self {
|
||||
Self::NewBlocks => "new_blocks",
|
||||
Self::OldBlocks => "old_blocks",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
pub enum ForkConfirmation {
|
||||
/// Fork block confirmation pending.
|
||||
@@ -708,6 +717,12 @@ impl ChainSync {
|
||||
/// Returns synchonization status
|
||||
pub fn status(&self) -> SyncStatus {
|
||||
let last_imported_number = self.new_blocks.last_imported_block_number();
|
||||
let mut item_sizes = BTreeMap::<String, usize>::new();
|
||||
self.old_blocks
|
||||
.as_ref()
|
||||
.map_or((), |d| d.get_sizes(&mut item_sizes));
|
||||
self.new_blocks.get_sizes(&mut item_sizes);
|
||||
|
||||
SyncStatus {
|
||||
state: self.state.clone(),
|
||||
protocol_version: ETH_PROTOCOL_VERSION_63.0,
|
||||
@@ -738,9 +753,7 @@ impl ChainSync {
|
||||
.count(),
|
||||
num_snapshot_chunks: self.snapshot.total_chunks(),
|
||||
snapshot_chunks_done: self.snapshot.done_chunks(),
|
||||
mem_used: self.new_blocks.heap_size()
|
||||
+ self.old_blocks.as_ref().map_or(0, |d| d.heap_size())
|
||||
+ self.peers.heap_size_of_children(),
|
||||
item_sizes: item_sizes,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1108,7 +1121,7 @@ impl ChainSync {
|
||||
}
|
||||
},
|
||||
SyncState::SnapshotData => {
|
||||
match io.snapshot_service().status() {
|
||||
match io.snapshot_service().restoration_status() {
|
||||
RestorationStatus::Ongoing { state_chunks_done, block_chunks_done, .. } => {
|
||||
// Initialize the snapshot if not already done
|
||||
self.snapshot.initialize(io.snapshot_service());
|
||||
@@ -1309,13 +1322,13 @@ impl ChainSync {
|
||||
self.state = SyncState::Blocks;
|
||||
self.continue_sync(io);
|
||||
}
|
||||
SyncState::SnapshotData => match io.snapshot_service().status() {
|
||||
SyncState::SnapshotData => match io.snapshot_service().restoration_status() {
|
||||
RestorationStatus::Inactive | RestorationStatus::Failed => {
|
||||
self.state = SyncState::SnapshotWaiting;
|
||||
}
|
||||
RestorationStatus::Initializing { .. } | RestorationStatus::Ongoing { .. } => (),
|
||||
},
|
||||
SyncState::SnapshotWaiting => match io.snapshot_service().status() {
|
||||
SyncState::SnapshotWaiting => match io.snapshot_service().restoration_status() {
|
||||
RestorationStatus::Inactive => {
|
||||
trace!(target:"sync", "Snapshot restoration is complete");
|
||||
self.restart(io);
|
||||
@@ -1541,7 +1554,7 @@ pub mod tests {
|
||||
blocks_received: 0,
|
||||
num_peers: 0,
|
||||
num_active_peers: 0,
|
||||
mem_used: 0,
|
||||
item_sizes: BTreeMap::new(),
|
||||
num_snapshot_chunks: 0,
|
||||
snapshot_chunks_done: 0,
|
||||
last_imported_old_block_number: None,
|
||||
|
||||
@@ -36,6 +36,7 @@ extern crate parity_bytes as bytes;
|
||||
extern crate parking_lot;
|
||||
extern crate rand;
|
||||
extern crate rlp;
|
||||
extern crate stats;
|
||||
extern crate triehash_ethereum;
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -18,7 +18,7 @@ use super::helpers::*;
|
||||
use bytes::Bytes;
|
||||
use ethcore::{
|
||||
client::EachBlockWith,
|
||||
snapshot::{ManifestData, RestorationStatus, SnapshotService},
|
||||
snapshot::{CreationStatus, ManifestData, RestorationStatus, SnapshotService},
|
||||
};
|
||||
use ethereum_types::H256;
|
||||
use hash::keccak;
|
||||
@@ -101,7 +101,11 @@ impl SnapshotService for TestSnapshotService {
|
||||
self.chunks.get(&hash).cloned()
|
||||
}
|
||||
|
||||
fn status(&self) -> RestorationStatus {
|
||||
fn creation_status(&self) -> CreationStatus {
|
||||
CreationStatus::Inactive
|
||||
}
|
||||
|
||||
fn restoration_status(&self) -> RestorationStatus {
|
||||
match *self.restoration_manifest.lock() {
|
||||
Some(ref manifest)
|
||||
if self.state_restoration_chunks.lock().len() == manifest.state_hashes.len()
|
||||
@@ -111,6 +115,7 @@ impl SnapshotService for TestSnapshotService {
|
||||
RestorationStatus::Inactive
|
||||
}
|
||||
Some(ref manifest) => RestorationStatus::Ongoing {
|
||||
block_number: 0,
|
||||
state_chunks: manifest.state_hashes.len() as u32,
|
||||
block_chunks: manifest.block_hashes.len() as u32,
|
||||
state_chunks_done: self.state_restoration_chunks.lock().len() as u32,
|
||||
|
||||
27
ethcore/types/src/creation_status.rs
Normal file
27
ethcore/types/src/creation_status.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity Ethereum.
|
||||
|
||||
// Parity Ethereum is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity Ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/// Statuses for snapshot creation.
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
pub enum CreationStatus {
|
||||
/// No creation activity currently.
|
||||
Inactive,
|
||||
/// Snapshot creation is in progress.
|
||||
Ongoing {
|
||||
/// Current created snapshot.
|
||||
block_number: u32,
|
||||
},
|
||||
}
|
||||
@@ -59,6 +59,7 @@ pub mod block;
|
||||
pub mod block_status;
|
||||
pub mod blockchain_info;
|
||||
pub mod call_analytics;
|
||||
pub mod creation_status;
|
||||
pub mod data_format;
|
||||
pub mod encoded;
|
||||
pub mod engines;
|
||||
|
||||
@@ -28,6 +28,8 @@ pub enum RestorationStatus {
|
||||
},
|
||||
/// Ongoing restoration.
|
||||
Ongoing {
|
||||
/// Block number specified in the manifest.
|
||||
block_number: u64,
|
||||
/// Total number of state chunks.
|
||||
state_chunks: u32,
|
||||
/// Total number of block chunks.
|
||||
|
||||
Reference in New Issue
Block a user