Skip to content
This repository was archived by the owner on Feb 1, 2024. It is now read-only.

Commit 290d791

Browse files
committed
change TransactionCommitCache to LRU
TransactionCommitCache is currently based on a HashSet which depends on its clients to properly clean up their items in a timely fashion. However, under high load circumstances, this can be too long resulting in quiet OOM issues and in practice freezing the whole network. This changes the TransactionCommitCache to an uluru LRU. This is safe since the commit cache is based on data that cannot change and the worst that happens on a miss is a refetch from the store. uluru is also updated to 3.0.0 which requires a minor change to `block_validator.rs` to account for the changed construction Signed-off-by: Kevin O'Donnell <kevin.odonnell@btp.works>
1 parent 2989a1c commit 290d791

File tree

3 files changed

+23
-13
lines changed

3 files changed

+23
-13
lines changed

validator/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ cbor-codec = "0.7"
1515
openssl = "0.10"
1616
protobuf = "2.0"
1717
python3-sys = "0.2"
18-
uluru = "0.2.0"
18+
uluru = "3.0.0"
1919

2020
[dev-dependencies]
2121
rand = "0.4"

validator/src/journal/block_validator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub enum ValidationError {
5757
}
5858

5959
type BlockValidationResultCache =
60-
uluru::LRUCache<[uluru::Entry<BlockValidationResult>; BLOCK_VALIDATION_RESULT_CACHE_SIZE]>;
60+
uluru::LRUCache<BlockValidationResult, BLOCK_VALIDATION_RESULT_CACHE_SIZE>;
6161

6262
#[derive(Clone, Default)]
6363
pub struct BlockValidationResultStore {
@@ -73,7 +73,7 @@ impl BlockValidationResultStore {
7373
self.validation_result_cache
7474
.lock()
7575
.expect("The mutex is poisoned")
76-
.insert(result)
76+
.insert(result);
7777
}
7878

7979
pub fn get(&self, block_id: &str) -> Option<BlockValidationResult> {

validator/src/journal/chain_commit_state.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use std::collections::HashSet;
2020
use batch::Batch;
2121
use journal::block_manager::BlockManager;
2222
use journal::commit_store::CommitStore;
23+
use std::sync::{Arc, RwLock};
2324
use transaction::Transaction;
2425

2526
#[derive(Debug, PartialEq)]
@@ -124,21 +125,26 @@ pub fn validate_transaction_dependencies(
124125
Ok(())
125126
}
126127

128+
type TransactionCommitCacheLRU = uluru::LRUCache<String, 300>;
129+
127130
pub struct TransactionCommitCache {
128-
committed: HashSet<String>,
131+
committed: Arc<RwLock<TransactionCommitCacheLRU>>,
129132
commit_store: CommitStore,
130133
}
131134

132135
impl TransactionCommitCache {
133136
pub fn new(commit_store: CommitStore) -> Self {
134137
TransactionCommitCache {
135-
committed: HashSet::new(),
138+
committed: Arc::new(RwLock::new(TransactionCommitCacheLRU::default())),
136139
commit_store,
137140
}
138141
}
139142

140143
pub fn add(&mut self, transaction_id: String) {
141-
self.committed.insert(transaction_id);
144+
self.committed
145+
.write()
146+
.expect("Failed to acquire write lock on commit cache")
147+
.insert(transaction_id);
142148
}
143149

144150
pub fn add_batch(&mut self, batch: &Batch) {
@@ -148,8 +154,8 @@ impl TransactionCommitCache {
148154
.for_each(|txn| self.add(txn.header_signature.clone()));
149155
}
150156

151-
pub fn remove(&mut self, transaction_id: &str) {
152-
self.committed.remove(transaction_id);
157+
fn remove(&mut self, transaction_id: &str) {
158+
()
153159
}
154160

155161
pub fn remove_batch(&mut self, batch: &Batch) {
@@ -161,7 +167,11 @@ impl TransactionCommitCache {
161167

162168
pub fn contains(&self, transaction_id: &str) -> bool {
163169
// Shouldn't expect here
164-
self.committed.contains(transaction_id)
170+
self.committed
171+
.write()
172+
.expect("Failed to acquire write lock on commit cache")
173+
.find(|x| x == transaction_id)
174+
.is_some()
165175
|| self
166176
.commit_store
167177
.contains_transaction(transaction_id)
@@ -281,7 +291,7 @@ mod test {
281291
let block_manager = setup_state();
282292

283293
let transactions: Vec<Transaction> = ["B6b0t0", "B6b0t1", "B6b0t2"]
284-
.into_iter()
294+
.iter()
285295
.map(|t_id| create_transaction((*t_id).into(), vec!["B2b0t0".into()]))
286296
.collect();
287297

@@ -300,7 +310,7 @@ mod test {
300310
let block_manager = setup_state();
301311

302312
let transactions: Vec<Transaction> = ["B6b0t0", "B6b0t1", "B6b0t2"]
303-
.into_iter()
313+
.iter()
304314
.map(|t_id| create_transaction((*t_id).into(), vec!["B1b0t0".into()]))
305315
.collect();
306316

@@ -319,7 +329,7 @@ mod test {
319329
let block_manager = setup_state();
320330

321331
let transactions: Vec<Transaction> = ["B3-1b0t0", "B3-1b0t1", "B3-1b0t2"]
322-
.into_iter()
332+
.iter()
323333
.map(|t_id| create_transaction((*t_id).into(), vec!["B1b0t0".into()]))
324334
.collect();
325335

@@ -338,7 +348,7 @@ mod test {
338348
let block_manager = setup_state();
339349

340350
let transactions: Vec<Transaction> = ["B6b0t0", "B6b0t1", "B6b0t2"]
341-
.into_iter()
351+
.iter()
342352
.map(|t_id| create_transaction((*t_id).into(), vec!["B4-3b0t0".into()]))
343353
.collect();
344354

0 commit comments

Comments
 (0)