Skip to content

Commit 57327de

Browse files
committed
optimize update_api_cache, move check_lost_data to backend thread.
1 parent 783a3e6 commit 57327de

File tree

4 files changed

+2459
-37
lines changed

4 files changed

+2459
-37
lines changed

src/components/abciapp/src/abci/server/callback/mod.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -413,24 +413,27 @@ pub fn end_block(
413413
}
414414

415415
pub fn commit(s: &mut ABCISubmissionServer, req: &RequestCommit) -> ResponseCommit {
416-
let la = s.la.write();
417-
let mut state = la.get_committed_state().write();
416+
let state = s.la.read().borrowable_ledger_state();
418417

419418
// will change `struct LedgerStatus`
420419
let td_height = TENDERMINT_BLOCK_HEIGHT.load(Ordering::Relaxed);
421-
state.set_tendermint_height(td_height as u64);
420+
state.write().set_tendermint_height(td_height as u64);
422421

423422
// cache last block for QueryServer
424-
pnk!(api_cache::update_api_cache(&mut state));
423+
pnk!(api_cache::update_api_cache(state.clone()));
425424

426425
// snapshot them finally
427-
let path = format!("{}/{}", &CFG.ledger_dir, &state.get_status().snapshot_file);
428-
pnk!(serde_json::to_vec(&state.get_status())
426+
let path = format!(
427+
"{}/{}",
428+
&CFG.ledger_dir,
429+
&state.read().get_status().snapshot_file
430+
);
431+
pnk!(serde_json::to_vec(&state.read().get_status())
429432
.c(d!())
430433
.and_then(|s| fs::write(&path, s).c(d!(path))));
431434

432435
let mut r = ResponseCommit::new();
433-
let la_hash = state.get_state_commitment().0.as_ref().to_vec();
436+
let la_hash = state.read().get_state_commitment().0.as_ref().to_vec();
434437
let cs_hash = s.account_base_app.write().commit(req).data;
435438

436439
if CFG.checkpoint.disable_evm_block_height < td_height

src/components/abciapp/src/api/submission_server/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ where
222222
.apply_transaction(&mut block, txn_effect)
223223
.c(d!("Failed to apply transaction"))
224224
});
225+
225226
match temp_sid {
226227
Ok(temp_sid) => {
227228
self.pending_txns.push((temp_sid, handle.clone(), txn));

src/ledger/src/store/api_cache.rs

+59-30
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
//! # Cached data for APIs
33
//!
44
5+
use std::sync::{
6+
atomic::{AtomicBool, Ordering},
7+
Arc,
8+
};
59
use {
610
crate::{
711
data_model::{
@@ -16,12 +20,18 @@ use {
1620
},
1721
fbnc::{new_mapx, new_mapxnk, Mapx, Mapxnk},
1822
globutils::wallet,
23+
lazy_static::lazy_static,
24+
parking_lot::RwLock,
1925
ruc::*,
2026
serde::{Deserialize, Serialize},
2127
std::collections::HashSet,
2228
zei::xfr::{sig::XfrPublicKey, structs::OwnerMemo},
2329
};
2430

31+
lazy_static! {
32+
static ref CHECK_LOST_DATA: AtomicBool = AtomicBool::new(false);
33+
}
34+
2535
type Issuances = Vec<(TxOutput, Option<OwnerMemo>)>;
2636

2737
/// Used in APIs
@@ -314,12 +324,12 @@ pub fn get_transferred_nonconfidential_assets(
314324
}
315325

316326
/// check the lost data
317-
pub fn check_lost_data(ledger: &mut LedgerState) -> Result<()> {
327+
pub fn check_lost_data(arc_ledger: Arc<RwLock<LedgerState>>) -> Result<()> {
318328
// check the lost txn sids
319-
let cur_txn_sid = ledger.get_next_txn().0;
320-
let api_cache_opt = ledger.api_cache.as_mut();
329+
330+
let cur_txn_sid = arc_ledger.read().get_next_txn().0;
321331
let mut last_txn_sid: usize = 0;
322-
if let Some(api_cache) = api_cache_opt {
332+
if let Some(api_cache) = arc_ledger.read().api_cache.as_ref() {
323333
if let Some(sid) = api_cache.last_sid.get(&"last_txn_sid".to_string()) {
324334
last_txn_sid = sid as usize;
325335
};
@@ -329,6 +339,8 @@ pub fn check_lost_data(ledger: &mut LedgerState) -> Result<()> {
329339

330340
if last_txn_sid < cur_txn_sid {
331341
for index in last_txn_sid..cur_txn_sid {
342+
let mut ledger = arc_ledger.write();
343+
332344
if !ledger
333345
.api_cache
334346
.as_mut()
@@ -365,10 +377,11 @@ pub fn check_lost_data(ledger: &mut LedgerState) -> Result<()> {
365377
}
366378

367379
// check the lost memos
368-
let cur_txo_sid = ledger.get_next_txo().0;
369-
let last_txo_sid_opt = ledger
380+
let cur_txo_sid = arc_ledger.read().get_next_txo().0;
381+
let last_txo_sid_opt = arc_ledger
382+
.read()
370383
.api_cache
371-
.as_mut()
384+
.as_ref()
372385
.unwrap()
373386
.last_sid
374387
.get(&"last_txo_sid".to_string());
@@ -380,6 +393,7 @@ pub fn check_lost_data(ledger: &mut LedgerState) -> Result<()> {
380393

381394
if last_txo_sid < cur_txo_sid {
382395
for index in last_txo_sid..cur_txo_sid {
396+
let mut ledger = arc_ledger.write();
383397
if !ledger
384398
.api_cache
385399
.as_mut()
@@ -388,6 +402,7 @@ pub fn check_lost_data(ledger: &mut LedgerState) -> Result<()> {
388402
.contains_key(&TxoSID(index))
389403
{
390404
let utxo_opt = ledger.get_utxo(TxoSID(index));
405+
391406
if let Some(utxo) = utxo_opt {
392407
let ftx = ledger
393408
.get_transaction_light(
@@ -455,17 +470,28 @@ pub fn check_lost_data(ledger: &mut LedgerState) -> Result<()> {
455470
.insert("last_txo_sid".to_string(), index as u64);
456471
}
457472
}
473+
458474
Ok(())
459475
}
460476

461477
/// update the data of QueryServer when we create a new block in ABCI
462-
pub fn update_api_cache(ledger: &mut LedgerState) -> Result<()> {
478+
pub fn update_api_cache(arc_ledger: Arc<RwLock<LedgerState>>) -> Result<()> {
463479
if !*KEEP_HIST {
464480
return Ok(());
465481
}
466482

467-
check_lost_data(ledger)?;
483+
let is_checking = CHECK_LOST_DATA.load(Ordering::Acquire);
468484

485+
if !is_checking {
486+
CHECK_LOST_DATA.store(true, Ordering::Release);
487+
let ledger_cloned = arc_ledger.clone();
488+
std::thread::spawn(move || {
489+
pnk!(check_lost_data(ledger_cloned));
490+
CHECK_LOST_DATA.store(false, Ordering::Release);
491+
});
492+
}
493+
494+
let mut ledger = arc_ledger.write();
469495
ledger.api_cache.as_mut().unwrap().cache_hist_data();
470496

471497
let block = if let Some(b) = ledger.blocks.last() {
@@ -474,33 +500,36 @@ pub fn update_api_cache(ledger: &mut LedgerState) -> Result<()> {
474500
return Ok(());
475501
};
476502

477-
let prefix = ledger.api_cache.as_mut().unwrap().prefix.clone();
478-
503+
let prefix = ledger.api_cache.as_ref().unwrap().prefix.clone();
479504
// Update ownership status
480505
for (txn_sid, txo_sids) in block.txns.iter().map(|v| (v.tx_id, v.txo_ids.as_slice()))
481506
{
482507
let curr_txn = ledger.get_transaction_light(txn_sid).c(d!())?.txn;
483508
// get the transaction, ownership addresses, and memos associated with each transaction
484509
let (addresses, owner_memos) = {
485-
let addresses: Vec<XfrAddress> = txo_sids
486-
.iter()
487-
.map(|sid| XfrAddress {
488-
key: ((ledger
489-
.get_utxo_light(*sid)
490-
.or_else(|| ledger.get_spent_utxo_light(*sid))
491-
.unwrap()
492-
.utxo)
493-
.0)
494-
.record
495-
.public_key,
496-
})
497-
.collect();
498-
510+
let mut addresses: Vec<XfrAddress> = vec![];
511+
512+
for sid in txo_sids.iter() {
513+
let key_op = {
514+
if let Some(utxo) = ledger.get_utxo_light(*sid) {
515+
Some(utxo.utxo.0.record.public_key)
516+
} else {
517+
ledger
518+
.get_spent_utxo_light(*sid)
519+
.map(|u| u.utxo.0.record.public_key)
520+
}
521+
};
522+
if let Some(key) = key_op {
523+
addresses.push(XfrAddress { key });
524+
}
525+
}
499526
let owner_memos = curr_txn.get_owner_memos_ref();
500527

501528
(addresses, owner_memos)
502529
};
503530

531+
// Update related addresses
532+
// Apply classify_op for each operation in curr_txn
504533
let classify_op = |op: &Operation| {
505534
match op {
506535
Operation::Claim(i) => {
@@ -526,8 +555,8 @@ pub fn update_api_cache(ledger: &mut LedgerState) -> Result<()> {
526555
let key = XfrAddress {
527556
key: me.utxo.record.public_key,
528557
};
529-
#[allow(unused_mut)]
530-
let mut hist = ledger
558+
559+
ledger
531560
.api_cache
532561
.as_mut()
533562
.unwrap()
@@ -539,8 +568,8 @@ pub fn update_api_cache(ledger: &mut LedgerState) -> Result<()> {
539568
prefix,
540569
key.to_base64()
541570
))
542-
});
543-
hist.insert(i.height, me.clone());
571+
})
572+
.insert(i.height, me.clone());
544573
}),
545574
_ => { /* filter more operations before this line */ }
546575
};
@@ -586,7 +615,7 @@ pub fn update_api_cache(ledger: &mut LedgerState) -> Result<()> {
586615
}
587616

588617
// Add created asset
589-
for op in &curr_txn.body.operations {
618+
for op in curr_txn.body.operations.iter() {
590619
match op {
591620
Operation::DefineAsset(define_asset) => {
592621
ledger

0 commit comments

Comments
 (0)