Skip to content

Commit ff97989

Browse files
committed
perf: cache pox descendancy check in burnop processing
1 parent 3477059 commit ff97989

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,16 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

17+
use std::cell::RefCell;
1718
use std::cmp::Ordering;
1819
use std::collections::{HashMap, HashSet};
1920
use std::io::{ErrorKind, Write};
2021
use std::ops::{Deref, DerefMut};
2122
use std::str::FromStr;
23+
use std::sync::{Arc, LazyLock, Mutex};
2224
use std::{cmp, fmt, fs};
2325

26+
use clarity::util::lru_cache::LruCache;
2427
use clarity::vm::ast::ASTRules;
2528
use clarity::vm::costs::ExecutionCost;
2629
use clarity::vm::representations::{ClarityName, ContractName};
@@ -95,6 +98,9 @@ pub const REWARD_WINDOW_END: u64 = 144 * 90 + REWARD_WINDOW_START;
9598

9699
pub type BlockHeaderCache = HashMap<ConsensusHash, (Option<BlockHeaderHash>, ConsensusHash)>;
97100

101+
static DESCENDANCY_CACHE: LazyLock<Arc<Mutex<LruCache<(SortitionId, BlockHeaderHash), bool>>>> =
102+
LazyLock::new(|| Arc::new(Mutex::new(LruCache::new(2000))));
103+
98104
pub enum FindIter<R> {
99105
Found(R),
100106
Continue,
@@ -1112,12 +1118,46 @@ pub trait SortitionHandle {
11121118
test_debug!("No snapshot at height {}", block_at_burn_height);
11131119
db_error::NotFoundError
11141120
})?;
1121+
let top_sortition_id = sn.sortition_id;
1122+
1123+
let mut cache = DESCENDANCY_CACHE
1124+
.lock()
1125+
.expect("FATAL: lock poisoned in SortitionDB");
11151126

11161127
while sn.block_height >= earliest_block_height {
1128+
match cache.get(&(sn.sortition_id, potential_ancestor.clone())) {
1129+
Ok(Some(result)) => {
1130+
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+
}
1136+
}
1137+
return Ok(result);
1138+
}
1139+
// 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+
}
1145+
}
1146+
11171147
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+
}
11181153
return Ok(false);
11191154
}
11201155
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+
}
11211161
return Ok(true);
11221162
}
11231163

@@ -1153,6 +1193,9 @@ pub trait SortitionHandle {
11531193
}
11541194
}
11551195
}
1196+
if let Err(_) = cache.insert_clean((top_sortition_id, potential_ancestor.clone()), false) {
1197+
*cache = LruCache::new(2000);
1198+
}
11561199
return Ok(false);
11571200
}
11581201
}

0 commit comments

Comments
 (0)