2
2
//! # Cached data for APIs
3
3
//!
4
4
5
+ use std:: sync:: {
6
+ atomic:: { AtomicBool , Ordering } ,
7
+ Arc ,
8
+ } ;
5
9
use {
6
10
crate :: {
7
11
data_model:: {
@@ -16,12 +20,18 @@ use {
16
20
} ,
17
21
fbnc:: { new_mapx, new_mapxnk, Mapx , Mapxnk } ,
18
22
globutils:: wallet,
23
+ lazy_static:: lazy_static,
24
+ parking_lot:: RwLock ,
19
25
ruc:: * ,
20
26
serde:: { Deserialize , Serialize } ,
21
27
std:: collections:: HashSet ,
22
28
zei:: xfr:: { sig:: XfrPublicKey , structs:: OwnerMemo } ,
23
29
} ;
24
30
31
+ lazy_static ! {
32
+ static ref CHECK_LOST_DATA : AtomicBool = AtomicBool :: new( false ) ;
33
+ }
34
+
25
35
type Issuances = Vec < ( TxOutput , Option < OwnerMemo > ) > ;
26
36
27
37
/// Used in APIs
@@ -314,12 +324,12 @@ pub fn get_transferred_nonconfidential_assets(
314
324
}
315
325
316
326
/// 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 < ( ) > {
318
328
// 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 ;
321
331
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 ( ) {
323
333
if let Some ( sid) = api_cache. last_sid . get ( & "last_txn_sid" . to_string ( ) ) {
324
334
last_txn_sid = sid as usize ;
325
335
} ;
@@ -329,6 +339,8 @@ pub fn check_lost_data(ledger: &mut LedgerState) -> Result<()> {
329
339
330
340
if last_txn_sid < cur_txn_sid {
331
341
for index in last_txn_sid..cur_txn_sid {
342
+ let mut ledger = arc_ledger. write ( ) ;
343
+
332
344
if !ledger
333
345
. api_cache
334
346
. as_mut ( )
@@ -365,10 +377,11 @@ pub fn check_lost_data(ledger: &mut LedgerState) -> Result<()> {
365
377
}
366
378
367
379
// 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 ( )
370
383
. api_cache
371
- . as_mut ( )
384
+ . as_ref ( )
372
385
. unwrap ( )
373
386
. last_sid
374
387
. get ( & "last_txo_sid" . to_string ( ) ) ;
@@ -380,6 +393,7 @@ pub fn check_lost_data(ledger: &mut LedgerState) -> Result<()> {
380
393
381
394
if last_txo_sid < cur_txo_sid {
382
395
for index in last_txo_sid..cur_txo_sid {
396
+ let mut ledger = arc_ledger. write ( ) ;
383
397
if !ledger
384
398
. api_cache
385
399
. as_mut ( )
@@ -388,6 +402,7 @@ pub fn check_lost_data(ledger: &mut LedgerState) -> Result<()> {
388
402
. contains_key ( & TxoSID ( index) )
389
403
{
390
404
let utxo_opt = ledger. get_utxo ( TxoSID ( index) ) ;
405
+
391
406
if let Some ( utxo) = utxo_opt {
392
407
let ftx = ledger
393
408
. get_transaction_light (
@@ -455,17 +470,28 @@ pub fn check_lost_data(ledger: &mut LedgerState) -> Result<()> {
455
470
. insert ( "last_txo_sid" . to_string ( ) , index as u64 ) ;
456
471
}
457
472
}
473
+
458
474
Ok ( ( ) )
459
475
}
460
476
461
477
/// 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 < ( ) > {
463
479
if !* KEEP_HIST {
464
480
return Ok ( ( ) ) ;
465
481
}
466
482
467
- check_lost_data ( ledger ) ? ;
483
+ let is_checking = CHECK_LOST_DATA . load ( Ordering :: Acquire ) ;
468
484
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 ( ) ;
469
495
ledger. api_cache . as_mut ( ) . unwrap ( ) . cache_hist_data ( ) ;
470
496
471
497
let block = if let Some ( b) = ledger. blocks . last ( ) {
@@ -474,33 +500,36 @@ pub fn update_api_cache(ledger: &mut LedgerState) -> Result<()> {
474
500
return Ok ( ( ) ) ;
475
501
} ;
476
502
477
- let prefix = ledger. api_cache . as_mut ( ) . unwrap ( ) . prefix . clone ( ) ;
478
-
503
+ let prefix = ledger. api_cache . as_ref ( ) . unwrap ( ) . prefix . clone ( ) ;
479
504
// Update ownership status
480
505
for ( txn_sid, txo_sids) in block. txns . iter ( ) . map ( |v| ( v. tx_id , v. txo_ids . as_slice ( ) ) )
481
506
{
482
507
let curr_txn = ledger. get_transaction_light ( txn_sid) . c ( d ! ( ) ) ?. txn ;
483
508
// get the transaction, ownership addresses, and memos associated with each transaction
484
509
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
+ }
499
526
let owner_memos = curr_txn. get_owner_memos_ref ( ) ;
500
527
501
528
( addresses, owner_memos)
502
529
} ;
503
530
531
+ // Update related addresses
532
+ // Apply classify_op for each operation in curr_txn
504
533
let classify_op = |op : & Operation | {
505
534
match op {
506
535
Operation :: Claim ( i) => {
@@ -526,8 +555,8 @@ pub fn update_api_cache(ledger: &mut LedgerState) -> Result<()> {
526
555
let key = XfrAddress {
527
556
key : me. utxo . record . public_key ,
528
557
} ;
529
- # [ allow ( unused_mut ) ]
530
- let mut hist = ledger
558
+
559
+ ledger
531
560
. api_cache
532
561
. as_mut ( )
533
562
. unwrap ( )
@@ -539,8 +568,8 @@ pub fn update_api_cache(ledger: &mut LedgerState) -> Result<()> {
539
568
prefix,
540
569
key. to_base64( )
541
570
) )
542
- } ) ;
543
- hist . insert ( i. height , me. clone ( ) ) ;
571
+ } )
572
+ . insert ( i. height , me. clone ( ) ) ;
544
573
} ) ,
545
574
_ => { /* filter more operations before this line */ }
546
575
} ;
@@ -586,7 +615,7 @@ pub fn update_api_cache(ledger: &mut LedgerState) -> Result<()> {
586
615
}
587
616
588
617
// Add created asset
589
- for op in & curr_txn. body . operations {
618
+ for op in curr_txn. body . operations . iter ( ) {
590
619
match op {
591
620
Operation :: DefineAsset ( define_asset) => {
592
621
ledger
0 commit comments