|
14 | 14 | // You should have received a copy of the GNU General Public License
|
15 | 15 | // along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16 | 16 |
|
| 17 | +use std::cell::RefCell; |
17 | 18 | use std::cmp::Ordering;
|
18 | 19 | use std::collections::{HashMap, HashSet};
|
19 | 20 | use std::io::{ErrorKind, Write};
|
20 | 21 | use std::ops::{Deref, DerefMut};
|
21 | 22 | use std::str::FromStr;
|
| 23 | +use std::sync::{Arc, LazyLock, Mutex}; |
22 | 24 | use std::{cmp, fmt, fs};
|
23 | 25 |
|
| 26 | +use clarity::util::lru_cache::LruCache; |
24 | 27 | use clarity::vm::ast::ASTRules;
|
25 | 28 | use clarity::vm::costs::ExecutionCost;
|
26 | 29 | use clarity::vm::representations::{ClarityName, ContractName};
|
@@ -95,6 +98,9 @@ pub const REWARD_WINDOW_END: u64 = 144 * 90 + REWARD_WINDOW_START;
|
95 | 98 |
|
96 | 99 | pub type BlockHeaderCache = HashMap<ConsensusHash, (Option<BlockHeaderHash>, ConsensusHash)>;
|
97 | 100 |
|
| 101 | +static DESCENDANCY_CACHE: LazyLock<Arc<Mutex<LruCache<(SortitionId, BlockHeaderHash), bool>>>> = |
| 102 | + LazyLock::new(|| Arc::new(Mutex::new(LruCache::new(2000)))); |
| 103 | + |
98 | 104 | pub enum FindIter<R> {
|
99 | 105 | Found(R),
|
100 | 106 | Continue,
|
@@ -1112,12 +1118,46 @@ pub trait SortitionHandle {
|
1112 | 1118 | test_debug!("No snapshot at height {}", block_at_burn_height);
|
1113 | 1119 | db_error::NotFoundError
|
1114 | 1120 | })?;
|
| 1121 | + let top_sortition_id = sn.sortition_id; |
| 1122 | + |
| 1123 | + let mut cache = DESCENDANCY_CACHE |
| 1124 | + .lock() |
| 1125 | + .expect("FATAL: lock poisoned in SortitionDB"); |
1115 | 1126 |
|
1116 | 1127 | 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 | + |
1117 | 1147 | 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 | + } |
1118 | 1153 | return Ok(false);
|
1119 | 1154 | }
|
1120 | 1155 | 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 | + } |
1121 | 1161 | return Ok(true);
|
1122 | 1162 | }
|
1123 | 1163 |
|
@@ -1153,6 +1193,9 @@ pub trait SortitionHandle {
|
1153 | 1193 | }
|
1154 | 1194 | }
|
1155 | 1195 | }
|
| 1196 | + if let Err(_) = cache.insert_clean((top_sortition_id, potential_ancestor.clone()), false) { |
| 1197 | + *cache = LruCache::new(2000); |
| 1198 | + } |
1156 | 1199 | return Ok(false);
|
1157 | 1200 | }
|
1158 | 1201 | }
|
|
0 commit comments