@@ -23,12 +23,13 @@ pub mod test_helper;
2323use aes_gcm:: { Aes256Gcm , Key , KeyInit } ;
2424use byteorder:: { BigEndian , ByteOrder } ;
2525use entryfile:: entrybuffer;
26+ use merkletree:: proof:: ProofPath ;
2627use parking_lot:: RwLock ;
2728use std:: collections:: VecDeque ;
2829use std:: fs;
2930use std:: path:: Path ;
3031use std:: sync:: mpsc:: { sync_channel, Receiver , SyncSender } ;
31- use std:: sync:: Arc ;
32+ use std:: sync:: { Arc , Condvar , Mutex } ;
3233use std:: thread;
3334use threadpool:: ThreadPool ;
3435
@@ -38,13 +39,13 @@ use crate::def::{
3839 TWIG_SHIFT ,
3940} ;
4041use crate :: entryfile:: { entry:: sentry_entry, EntryBz , EntryCache , EntryFile } ;
41- use crate :: flusher:: { Flusher , FlusherShard } ;
42+ use crate :: flusher:: { Flusher , FlusherShard , ProofReqElem } ;
4243use crate :: indexer:: Indexer ;
4344use crate :: merkletree:: {
4445 recover:: { bytes_to_edge_nodes, recover_tree} ,
4546 Tree ,
4647} ;
47- use crate :: metadb:: MetaDB ;
48+ use crate :: metadb:: { MetaDB , MetaInfo } ;
4849use log:: { debug, error, info} ;
4950
5051#[ cfg( all( target_os = "linux" , feature = "directio" ) ) ]
@@ -65,6 +66,7 @@ pub struct AdsCore {
6566 entry_files : Vec < Arc < EntryFile > > ,
6667 meta : Arc < RwLock < MetaDB > > ,
6768 wrbuf_size : usize ,
69+ proof_req_senders : Vec < SyncSender < ProofReqElem > > ,
6870}
6971
7072fn get_ciphers (
@@ -112,7 +114,7 @@ impl AdsCore {
112114 pub fn new (
113115 task_hub : Arc < dyn TaskHub > ,
114116 config : & config:: Config ,
115- ) -> ( Self , Receiver < i64 > , Flusher ) {
117+ ) -> ( Self , Receiver < Arc < MetaInfo > > , Flusher ) {
116118 #[ cfg( feature = "tee_cipher" ) ]
117119 assert ! ( config. aes_keys. unwrap( ) . len( ) == 96 ) ;
118120
@@ -133,7 +135,7 @@ impl AdsCore {
133135 file_segment_size : usize ,
134136 with_twig_file : bool ,
135137 aes_keys : & Option < [ u8 ; 96 ] > ,
136- ) -> ( Self , Receiver < i64 > , Flusher ) {
138+ ) -> ( Self , Receiver < Arc < MetaInfo > > , Flusher ) {
137139 let ( ciphers, idx_cipher, meta_db_cipher) = get_ciphers ( aes_keys) ;
138140 let ( data_dir, meta_dir, _indexer_dir) = Self :: get_sub_dirs ( dir) ;
139141
@@ -185,10 +187,35 @@ impl AdsCore {
185187 entry_files,
186188 meta : meta. clone ( ) ,
187189 wrbuf_size,
190+ proof_req_senders : flusher. get_proof_req_senders ( ) ,
188191 } ;
189192 ( ads_core, eb_receiver, flusher)
190193 }
191194
195+ pub fn get_proof ( & self , shard_id : usize , sn : u64 ) -> Result < ProofPath , String > {
196+ if cfg ! ( feature = "slow_hashing" ) {
197+ return Err ( "do not support proof in slow hashing mode" . to_owned ( ) ) ;
198+ }
199+
200+ let pair = Arc :: new ( ( Mutex :: new ( ( sn, Option :: None ) ) , Condvar :: new ( ) ) ) ;
201+
202+ if let Err ( er) = self . proof_req_senders [ shard_id] . send ( Arc :: clone ( & pair) ) {
203+ return Err ( format ! ( "send proof request failed: {:?}" , er) ) ;
204+ }
205+
206+ // wait for the request to be handled
207+ let ( lock, cvar) = & * pair;
208+ let mut sn_proof = lock. lock ( ) . unwrap ( ) ;
209+ while sn_proof. 1 . is_none ( ) {
210+ sn_proof = cvar. wait ( sn_proof) . unwrap ( ) ;
211+ }
212+
213+ if let Err ( er) = sn_proof. 1 . as_ref ( ) . unwrap ( ) {
214+ return Err ( format ! ( "get proof failed: {:?}" , er) ) ;
215+ }
216+ sn_proof. 1 . take ( ) . unwrap ( )
217+ }
218+
192219 pub fn get_entry_files ( & self ) -> Vec < Arc < EntryFile > > {
193220 let mut res = Vec :: with_capacity ( self . entry_files . len ( ) ) ;
194221 for ef in self . entry_files . iter ( ) {
@@ -401,7 +428,7 @@ impl AdsCore {
401428 meta. set_next_serial_num ( shard_id, SENTRY_COUNT as u64 ) ;
402429 }
403430 meta. insert_extra_data ( 0 , "" . to_owned ( ) ) ;
404- meta. commit ( )
431+ meta. commit ( ) ;
405432 }
406433
407434 pub fn check_entry ( key_hash : & [ u8 ] , key : & [ u8 ] , entry_bz : & EntryBz ) -> bool {
@@ -598,7 +625,8 @@ pub struct AdsWrap<T: Task> {
598625 ads : Arc < AdsCore > ,
599626 cache : Arc < EntryCache > ,
600627 cache_list : Vec < Arc < EntryCache > > ,
601- end_block_chan : Receiver < i64 > , // when ads finish the prev block disk job, there will receive something.
628+ // when ads finish the prev block disk job, end_block_chan will receive MetaInfo
629+ end_block_chan : Receiver < Arc < MetaInfo > > ,
602630 stop_height : i64 ,
603631}
604632
@@ -689,11 +717,18 @@ impl<T: Task + 'static> AdsWrap<T> {
689717 self . ads . get_entry_files ( )
690718 }
691719
692- pub fn flush ( & mut self ) {
720+ pub fn get_proof ( & self , shard_id : usize , sn : u64 ) -> Result < ProofPath , String > {
721+ self . ads . get_proof ( shard_id, sn)
722+ }
723+
724+ pub fn flush ( & mut self ) -> Vec < Arc < MetaInfo > > {
725+ let mut v = Vec :: with_capacity ( 2 ) ;
693726 while self . task_hub . free_slot_count ( ) < 2 {
694- let height = self . end_block_chan . recv ( ) . unwrap ( ) ;
695- self . task_hub . end_block ( height) ;
727+ let meta_info = self . end_block_chan . recv ( ) . unwrap ( ) ;
728+ self . task_hub . end_block ( meta_info. curr_height ) ;
729+ v. push ( meta_info) ;
696730 }
731+ v
697732 }
698733
699734 fn allocate_cache ( & mut self ) -> Arc < EntryCache > {
@@ -718,21 +753,27 @@ impl<T: Task + 'static> AdsWrap<T> {
718753 self . stop_height = height;
719754 }
720755
721- pub fn start_block ( & mut self , height : i64 , tasks_manager : Arc < TasksManager < T > > ) -> bool {
756+ pub fn start_block (
757+ & mut self ,
758+ height : i64 ,
759+ tasks_manager : Arc < TasksManager < T > > ,
760+ ) -> ( bool , Option < Arc < MetaInfo > > ) {
722761 if height == self . stop_height + 1 {
723- return false ;
762+ return ( false , Option :: None ) ;
724763 }
725764 self . cache = self . allocate_cache ( ) ;
726765
766+ let mut meta_info = Option :: None ;
727767 if self . task_hub . free_slot_count ( ) == 0 {
728768 // adscore and task_hub are busy, wait for them to finish an old block
729- let height = self . end_block_chan . recv ( ) . unwrap ( ) ;
730- self . task_hub . end_block ( height) ;
769+ let _meta_info = self . end_block_chan . recv ( ) . unwrap ( ) ;
770+ self . task_hub . end_block ( _meta_info. curr_height ) ;
771+ meta_info = Some ( _meta_info) ;
731772 }
732773
733774 self . task_hub
734775 . start_block ( height, tasks_manager, self . cache . clone ( ) ) ;
735- true
776+ ( true , meta_info )
736777 }
737778
738779 pub fn get_shared ( & self ) -> SharedAdsWrap {
0 commit comments