-
Notifications
You must be signed in to change notification settings - Fork 676
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
feat: add chunk application stats #12797
base: master
Are you sure you want to change the base?
Changes from all commits
14322e2
58aed33
54a147b
903d592
7a56c4a
9faeb48
4aaa9e9
488cb79
fad294f
c09da48
7fdbbda
d28f43b
ccd5e01
d23358c
95e1c4a
11caf8a
ccb1e6e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -649,6 +649,7 @@ impl<'a> ChainStoreUpdate<'a> { | |
self.gc_outgoing_receipts(&block_hash, shard_id); | ||
self.gc_col(DBCol::IncomingReceipts, &block_shard_id); | ||
self.gc_col(DBCol::StateTransitionData, &block_shard_id); | ||
self.gc_col(DBCol::ChunkApplyStats, &block_shard_id); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we could use some other garbage collection logic to keep the stats for longer than three epochs. Maybe something similar to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed that it would be cool to keep those longer and agreed to keep the first version simple. |
||
|
||
// For incoming State Parts it's done in chain.clear_downloaded_parts() | ||
// The following code is mostly for outgoing State Parts. | ||
|
@@ -1017,6 +1018,9 @@ impl<'a> ChainStoreUpdate<'a> { | |
DBCol::StateSyncNewChunks => { | ||
store_update.delete(col, key); | ||
} | ||
DBCol::ChunkApplyStats => { | ||
store_update.delete(col, key); | ||
} | ||
DBCol::DbVersion | ||
| DBCol::BlockMisc | ||
| DBCol::_GCCount | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ use near_chain_primitives::error::Error; | |
use near_epoch_manager::EpochManagerAdapter; | ||
use near_primitives::block::Tip; | ||
use near_primitives::checked_feature; | ||
use near_primitives::chunk_apply_stats::{ChunkApplyStats, ChunkApplyStatsV0}; | ||
use near_primitives::errors::InvalidTxError; | ||
use near_primitives::hash::CryptoHash; | ||
use near_primitives::merkle::{MerklePath, PartialMerkleTree}; | ||
|
@@ -112,6 +113,11 @@ pub trait ChainStoreAccess { | |
block_hash: &CryptoHash, | ||
shard_uid: &ShardUId, | ||
) -> Result<Arc<ChunkExtra>, Error>; | ||
fn get_chunk_apply_stats( | ||
&self, | ||
block_hash: &CryptoHash, | ||
shard_id: &ShardId, | ||
) -> Result<Option<ChunkApplyStats>, Error>; | ||
/// Get block header. | ||
fn get_block_header(&self, h: &CryptoHash) -> Result<BlockHeader, Error>; | ||
/// Returns hash of the block on the main chain for given height. | ||
|
@@ -941,6 +947,14 @@ impl ChainStoreAccess for ChainStore { | |
ChainStoreAdapter::get_chunk_extra(self, block_hash, shard_uid) | ||
} | ||
|
||
fn get_chunk_apply_stats( | ||
&self, | ||
block_hash: &CryptoHash, | ||
shard_id: &ShardId, | ||
) -> Result<Option<ChunkApplyStats>, Error> { | ||
ChainStoreAdapter::get_chunk_apply_stats(&self, block_hash, shard_id) | ||
} | ||
|
||
/// Get block header. | ||
fn get_block_header(&self, h: &CryptoHash) -> Result<BlockHeader, Error> { | ||
ChainStoreAdapter::get_block_header(self, h) | ||
|
@@ -1084,6 +1098,7 @@ pub struct ChainStoreUpdate<'a> { | |
add_state_sync_infos: Vec<StateSyncInfo>, | ||
remove_state_sync_infos: Vec<CryptoHash>, | ||
challenged_blocks: HashSet<CryptoHash>, | ||
chunk_apply_stats: HashMap<(CryptoHash, ShardId), ChunkApplyStats>, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. small suggestion: shard uid is the better unique identifier of a shard. that being said it's often not readily available, in that case don't worry about it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAIU from now on the plan is to add new shard ids instead of increasing UId versions, so it should be unique enough. ShardId is more user friendly so I went with that. |
||
} | ||
|
||
impl<'a> ChainStoreUpdate<'a> { | ||
|
@@ -1107,6 +1122,7 @@ impl<'a> ChainStoreUpdate<'a> { | |
add_state_sync_infos: vec![], | ||
remove_state_sync_infos: vec![], | ||
challenged_blocks: HashSet::default(), | ||
chunk_apply_stats: HashMap::default(), | ||
} | ||
} | ||
} | ||
|
@@ -1234,6 +1250,18 @@ impl<'a> ChainStoreAccess for ChainStoreUpdate<'a> { | |
} | ||
} | ||
|
||
fn get_chunk_apply_stats( | ||
&self, | ||
block_hash: &CryptoHash, | ||
shard_id: &ShardId, | ||
) -> Result<Option<ChunkApplyStats>, Error> { | ||
if let Some(stats) = self.chunk_apply_stats.get(&(*block_hash, *shard_id)) { | ||
Ok(Some(stats.clone())) | ||
} else { | ||
self.chain_store.get_chunk_apply_stats(block_hash, shard_id) | ||
} | ||
} | ||
|
||
/// Get block header. | ||
fn get_block_header(&self, hash: &CryptoHash) -> Result<BlockHeader, Error> { | ||
if let Some(header) = self.chain_store_cache_update.headers.get(hash).cloned() { | ||
|
@@ -1746,6 +1774,15 @@ impl<'a> ChainStoreUpdate<'a> { | |
self.chain_store_cache_update.processed_block_heights.insert(height); | ||
} | ||
|
||
pub fn save_chunk_apply_stats( | ||
&mut self, | ||
block_hash: CryptoHash, | ||
shard_id: ShardId, | ||
stats: ChunkApplyStatsV0, | ||
) { | ||
self.chunk_apply_stats.insert((block_hash, shard_id), ChunkApplyStats::V0(stats)); | ||
} | ||
|
||
pub fn inc_block_refcount(&mut self, block_hash: &CryptoHash) -> Result<(), Error> { | ||
let refcount = match self.get_block_refcount(block_hash) { | ||
Ok(refcount) => refcount, | ||
|
@@ -2159,6 +2196,13 @@ impl<'a> ChainStoreUpdate<'a> { | |
&(), | ||
)?; | ||
} | ||
for ((block_hash, shard_id), stats) in self.chunk_apply_stats.iter() { | ||
store_update.set_ser( | ||
DBCol::ChunkApplyStats, | ||
&get_block_shard_id(block_hash, *shard_id), | ||
stats, | ||
)?; | ||
} | ||
for other in self.store_updates.drain(..) { | ||
store_update.merge(other); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ use near_primitives::bandwidth_scheduler::BlockBandwidthRequests; | |
pub use near_primitives::block::{Block, BlockHeader, Tip}; | ||
use near_primitives::challenge::ChallengesResult; | ||
use near_primitives::checked_feature; | ||
use near_primitives::chunk_apply_stats::ChunkApplyStatsV0; | ||
use near_primitives::congestion_info::BlockCongestionInfo; | ||
use near_primitives::congestion_info::CongestionInfo; | ||
use near_primitives::congestion_info::ExtendedCongestionInfo; | ||
|
@@ -115,6 +116,7 @@ pub struct ApplyChunkResult { | |
pub bandwidth_scheduler_state_hash: CryptoHash, | ||
/// Contracts accessed and deployed while applying the chunk. | ||
pub contract_updates: ContractUpdates, | ||
pub stats: ChunkApplyStatsV0, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why the versioned struct instead of the enum? nit: please add a comment |
||
} | ||
|
||
impl ApplyChunkResult { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Saving chunk stats here means that only chunks applied inside blocks will have their stats saved. Stateless chunk validators will not save any stats. In the future we could change it to save it somewhere else, but it's good enough for the first version.