Skip to content

Commit c0faf3e

Browse files
committed
perf: do not read whole snapshot for ancestor check in find_new_block_arrivals
1 parent 4a7b908 commit c0faf3e

File tree

3 files changed

+42
-15
lines changed

3 files changed

+42
-15
lines changed

stackslib/src/chainstate/burn/db/sortdb.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,13 +1264,25 @@ impl<'a> SortitionHandleTx<'a> {
12641264
burn_header_hash: &BurnchainHeaderHash,
12651265
chain_tip: &SortitionId,
12661266
) -> Result<Option<BlockSnapshot>, db_error> {
1267+
let Some(sortition_id) = self.get_sortition_id_for_bhh(burn_header_hash, chain_tip)? else {
1268+
return Ok(None);
1269+
};
1270+
1271+
SortitionDB::get_block_snapshot(self.tx(), &sortition_id)
1272+
}
1273+
1274+
fn get_sortition_id_for_bhh(
1275+
&mut self,
1276+
burn_header_hash: &BurnchainHeaderHash,
1277+
chain_tip: &SortitionId,
1278+
) -> Result<Option<SortitionId>, db_error> {
12671279
let sortition_identifier_key = db_keys::sortition_id_for_bhh(burn_header_hash);
12681280
let sortition_id = match self.get_indexed(chain_tip, &sortition_identifier_key)? {
12691281
None => return Ok(None),
12701282
Some(x) => SortitionId::from_hex(&x).expect("FATAL: bad Sortition ID stored in DB"),
12711283
};
12721284

1273-
SortitionDB::get_block_snapshot(self.tx(), &sortition_id)
1285+
Ok(Some(sortition_id))
12741286
}
12751287

12761288
/// Get a leader key at a specific location in the burn chain's fork history, given the
@@ -6528,25 +6540,25 @@ impl SortitionHandleTx<'_> {
65286540
}
65296541

65306542
// must be an ancestor of this tip, or must be this tip
6531-
if let Some(sn) =
6532-
self.get_block_snapshot(&arrival_sn.burn_header_hash, &parent_tip.sortition_id)?
6543+
if let Some(sortition_id) = self
6544+
.get_sortition_id_for_bhh(&arrival_sn.burn_header_hash, &parent_tip.sortition_id)?
65336545
{
6534-
if !sn.pox_valid || sn != arrival_sn {
6546+
if sortition_id != arrival_sn.sortition_id {
65356547
continue;
65366548
}
65376549

65386550
debug!(
65396551
"New Stacks anchored block arrived: block {}/{} ({}) ari={} tip={}",
6540-
&sn.consensus_hash,
6541-
&sn.winning_stacks_block_hash,
6542-
sn.stacks_block_height,
6552+
&arrival_sn.consensus_hash,
6553+
&arrival_sn.winning_stacks_block_hash,
6554+
arrival_sn.stacks_block_height,
65436555
ari,
65446556
&parent_tip.burn_header_hash
65456557
);
65466558
new_block_arrivals.push((
6547-
sn.consensus_hash,
6548-
sn.winning_stacks_block_hash,
6549-
sn.stacks_block_height,
6559+
arrival_sn.consensus_hash,
6560+
arrival_sn.winning_stacks_block_hash,
6561+
arrival_sn.stacks_block_height,
65506562
));
65516563
} else {
65526564
// this block did not arrive on an ancestor block

stackslib/src/chainstate/stacks/index/cache.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

1717
use std::char::from_digit;
18+
use std::collections::hash_map::Entry;
1819
use std::collections::{HashMap, HashSet, VecDeque};
1920
use std::hash::{Hash, Hasher};
2021
use std::io::{BufWriter, Cursor, Read, Seek, SeekFrom, Write};
@@ -137,6 +138,11 @@ impl<T: MarfTrieId> TrieCacheState<T> {
137138
self.block_hash_cache.get(&block_id).cloned()
138139
}
139140

141+
/// Return the HashMap Entry for a block_id
142+
pub fn entry_block_hash(&mut self, block_id: u32) -> Entry<'_, u32, T> {
143+
self.block_hash_cache.entry(block_id)
144+
}
145+
140146
/// Cache a block hash, given its ID
141147
pub fn store_block_hash(&mut self, block_id: u32, block_hash: T) {
142148
assert!(!self.block_hash_cache.contains_key(&block_id));
@@ -309,6 +315,11 @@ impl<T: MarfTrieId> TrieCache<T> {
309315
self.state_mut().load_block_hash(block_id)
310316
}
311317

318+
/// Get entry for a block hash, given its ID
319+
pub fn entry_block_hash<'a>(&'a mut self, block_id: u32) -> Entry<'a, u32, T> {
320+
self.state_mut().entry_block_hash(block_id)
321+
}
322+
312323
/// Store a block's ID and hash to teh cache.
313324
pub fn store_block_hash(&mut self, block_id: u32, block_hash: T) {
314325
self.state_mut().store_block_hash(block_id, block_hash)

stackslib/src/chainstate/stacks/index/storage.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

1717
use std::char::from_digit;
18+
use std::collections::hash_map::Entry;
1819
use std::collections::{HashMap, HashSet, VecDeque};
1920
use std::hash::{Hash, Hasher};
2021
use std::io::{BufWriter, Cursor, Read, Seek, SeekFrom, Write};
@@ -108,12 +109,15 @@ impl<T: MarfTrieId> BlockMap for TrieStorageConnection<'_, T> {
108109
trie_sql::get_block_hash(&self.db, id)
109110
}
110111

111-
fn get_block_hash_caching(&mut self, id: u32) -> Result<&T, Error> {
112-
if !self.is_block_hash_cached(id) {
113-
let block_hash = self.get_block_hash(id)?;
114-
self.cache.store_block_hash(id, block_hash);
112+
fn get_block_hash_caching<'a>(&'a mut self, id: u32) -> Result<&'a T, Error> {
113+
match self.cache.entry_block_hash(id) {
114+
Entry::Occupied(occupied_entry) => Ok(occupied_entry.into_mut()),
115+
Entry::Vacant(vacant_entry) => {
116+
let block_hash = trie_sql::get_block_hash(&self.db, id)?;
117+
let block_hash_ref = vacant_entry.insert(block_hash);
118+
Ok(block_hash_ref)
119+
}
115120
}
116-
self.cache.ref_block_hash(id).ok_or(Error::NotFoundError)
117121
}
118122

119123
fn is_block_hash_cached(&self, id: u32) -> bool {

0 commit comments

Comments
 (0)