Skip to content

Commit d41b6a8

Browse files
committed
refactor descendancy cache handling
1 parent ff97989 commit d41b6a8

File tree

1 file changed

+36
-27
lines changed

1 file changed

+36
-27
lines changed

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

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use std::collections::{HashMap, HashSet};
2020
use std::io::{ErrorKind, Write};
2121
use std::ops::{Deref, DerefMut};
2222
use std::str::FromStr;
23-
use std::sync::{Arc, LazyLock, Mutex};
23+
use std::sync::{Arc, LazyLock, Mutex, MutexGuard};
2424
use std::{cmp, fmt, fs};
2525

2626
use clarity::util::lru_cache::LruCache;
@@ -98,8 +98,9 @@ pub const REWARD_WINDOW_END: u64 = 144 * 90 + REWARD_WINDOW_START;
9898

9999
pub type BlockHeaderCache = HashMap<ConsensusHash, (Option<BlockHeaderHash>, ConsensusHash)>;
100100

101+
const DESCENDANCY_CACHE_SIZE: usize = 2000;
101102
static DESCENDANCY_CACHE: LazyLock<Arc<Mutex<LruCache<(SortitionId, BlockHeaderHash), bool>>>> =
102-
LazyLock::new(|| Arc::new(Mutex::new(LruCache::new(2000))));
103+
LazyLock::new(|| Arc::new(Mutex::new(LruCache::new(DESCENDANCY_CACHE_SIZE))));
103104

104105
pub enum FindIter<R> {
105106
Found(R),
@@ -1091,6 +1092,31 @@ pub trait SortitionHandle {
10911092
Ok(Some(StacksBlockId::new(&ch, &bhh)))
10921093
}
10931094

1095+
/// Check if the descendancy cache has an entry for whether or not the winning block in `key.0`
1096+
/// descends from `key.1`
1097+
///
1098+
/// If it does, return the cached entry
1099+
fn descendancy_cache_get(cache: &mut MutexGuard<'_, LruCache<(SortitionId, BlockHeaderHash), bool>>, key: &(SortitionId, BlockHeaderHash)) -> Option<bool> {
1100+
match cache.get(key) {
1101+
Ok(result) => result,
1102+
// cache is broken, create a new one
1103+
Err(e) => {
1104+
error!("SortitionDB's descendant cache errored. Will continue operation with cleared cache"; "err" => %e);
1105+
**cache = LruCache::new(DESCENDANCY_CACHE_SIZE);
1106+
None
1107+
}
1108+
}
1109+
}
1110+
1111+
/// Cache the result of the descendancy check on whether or not the winning block in `key.0`
1112+
/// descends from `key.1`
1113+
fn descendancy_cache_put(cache: &mut MutexGuard<'_, LruCache<(SortitionId, BlockHeaderHash), bool>>, key: (SortitionId, BlockHeaderHash), is_descended: bool) {
1114+
if let Err(e) = cache.insert_clean(key, is_descended) {
1115+
error!("SortitionDB's descendant cache errored. Will continue operation with cleared cache"; "err" => %e);
1116+
**cache = LruCache::new(DESCENDANCY_CACHE_SIZE);
1117+
}
1118+
}
1119+
10941120
/// is the given block a descendant of `potential_ancestor`?
10951121
/// * block_at_burn_height: the burn height of the sortition that chose the stacks block to check
10961122
/// * potential_ancestor: the stacks block hash of the potential ancestor
@@ -1125,39 +1151,24 @@ pub trait SortitionHandle {
11251151
.expect("FATAL: lock poisoned in SortitionDB");
11261152

11271153
while sn.block_height >= earliest_block_height {
1128-
match cache.get(&(sn.sortition_id, potential_ancestor.clone())) {
1129-
Ok(Some(result)) => {
1154+
let cache_check_key = (sn.sortition_id, potential_ancestor.clone());
1155+
match Self::descendancy_cache_get(&mut cache, &cache_check_key) {
1156+
Some(result) => {
11301157
if sn.sortition_id != top_sortition_id {
1131-
if let Err(_) = cache
1132-
.insert_clean((top_sortition_id, potential_ancestor.clone()), result)
1133-
{
1134-
*cache = LruCache::new(2000);
1135-
}
1158+
Self::descendancy_cache_put(&mut cache, (top_sortition_id, cache_check_key.1), result);
11361159
}
11371160
return Ok(result);
11381161
}
11391162
// not cached, don't need to do anything.
1140-
Ok(None) => {}
1141-
// cache is broken, create a new one
1142-
Err(_) => {
1143-
*cache = LruCache::new(2000);
1144-
}
1163+
None => {}
11451164
}
11461165

11471166
if !sn.sortition {
1148-
if let Err(_) =
1149-
cache.insert_clean((top_sortition_id, potential_ancestor.clone()), false)
1150-
{
1151-
*cache = LruCache::new(2000);
1152-
}
1167+
Self::descendancy_cache_put(&mut cache, (top_sortition_id, cache_check_key.1), false);
11531168
return Ok(false);
11541169
}
11551170
if &sn.winning_stacks_block_hash == potential_ancestor {
1156-
if let Err(_) =
1157-
cache.insert_clean((top_sortition_id, potential_ancestor.clone()), true)
1158-
{
1159-
*cache = LruCache::new(2000);
1160-
}
1171+
Self::descendancy_cache_put(&mut cache, (top_sortition_id, cache_check_key.1), true);
11611172
return Ok(true);
11621173
}
11631174

@@ -1193,9 +1204,7 @@ pub trait SortitionHandle {
11931204
}
11941205
}
11951206
}
1196-
if let Err(_) = cache.insert_clean((top_sortition_id, potential_ancestor.clone()), false) {
1197-
*cache = LruCache::new(2000);
1198-
}
1207+
Self::descendancy_cache_put(&mut cache, (top_sortition_id, potential_ancestor.clone()), false);
11991208
return Ok(false);
12001209
}
12011210
}

0 commit comments

Comments
 (0)