@@ -33,15 +33,14 @@ impl ChainSyncClient for MockChainSync {
3333 }
3434
3535 // what are you waiting for?
36- let requested_block_number = match & self . consumer_tip {
37- BlockReference :: Origin => 0 ,
38- BlockReference :: Point ( number , _ ) => * number + 1 ,
36+ let next_index = match & self . consumer_tip {
37+ BlockReference :: Origin => Some ( 1 ) ,
38+ BlockReference :: Point ( _ , hash ) => self . chain . indexes . get ( hash ) . map ( |i| * i + 1 ) ,
3939 } ;
4040
4141 // if we have it, give it
42- if let Some ( info) = chain. get ( requested_block_number as usize ) {
43- self . consumer_tip =
44- BlockReference :: Point ( requested_block_number, info. block_hash . clone ( ) ) ;
42+ if let Some ( info) = next_index. and_then ( |i| chain. get ( i) ) {
43+ self . consumer_tip = BlockReference :: Point ( info. block_slot , info. block_hash . clone ( ) ) ;
4544 return Ok ( RequestNextResponse :: RollForward ( info. clone ( ) , tip) ) ;
4645 }
4746
@@ -58,9 +57,9 @@ impl ChainSyncClient for MockChainSync {
5857 let chain = self . chain . read_lock ( ) . await ;
5958 let intersect = points. iter ( ) . find_map ( |point| match point {
6059 BlockReference :: Origin => chain. first ( ) ,
61- BlockReference :: Point ( number , hash) => chain
62- . get ( * number as usize )
63- . filter ( |b| b . block_hash == * hash ) ,
60+ BlockReference :: Point ( _ , hash) => {
61+ self . chain . indexes . get ( hash ) . and_then ( |i| chain . get ( * i ) )
62+ }
6463 } ) ;
6564 self . consumer_tip = intersect. map ( |b| b. as_reference ( ) ) . unwrap_or_default ( ) ;
6665 let tip = chain. last ( ) . map ( |b| b. as_reference ( ) ) . unwrap_or_default ( ) ;
@@ -77,29 +76,42 @@ impl ChainSyncClient for MockChainSync {
7776pub struct MockChain {
7877 // the real implementation of course won't be in memory
7978 chain : Arc < RwLock < Vec < BlockInfo > > > ,
79+ indexes : Arc < DashMap < String , usize > > ,
8080 new_block : Arc < Notify > ,
8181 rolled_back : Arc < DashMap < BlockReference , BlockReference > > ,
8282}
8383
8484impl MockChain {
8585 pub fn new ( initial_height : usize ) -> Self {
8686 let chain = Arc :: new ( RwLock :: new ( vec ! [ ] ) ) ;
87+ let indexes = Arc :: new ( DashMap :: new ( ) ) ;
8788 let new_block = Arc :: new ( Notify :: new ( ) ) ;
8889 let rolled_back = Arc :: new ( DashMap :: new ( ) ) ;
8990 tokio:: spawn ( Self :: generate (
9091 chain. clone ( ) ,
92+ indexes. clone ( ) ,
9193 new_block. clone ( ) ,
9294 rolled_back. clone ( ) ,
9395 initial_height,
9496 ) ) ;
9597
9698 Self {
9799 chain,
100+ indexes,
98101 new_block,
99102 rolled_back,
100103 }
101104 }
102105
106+ pub fn genesis_hash ( & self ) -> String {
107+ self . chain
108+ . blocking_read ( )
109+ . first ( )
110+ . unwrap ( )
111+ . block_hash
112+ . clone ( )
113+ }
114+
103115 pub fn sync ( & self ) -> MockChainSync {
104116 MockChainSync {
105117 chain : self . clone ( ) ,
@@ -130,11 +142,13 @@ impl MockChain {
130142 pub async fn request_block ( & self , block_ref : & BlockReference ) -> Result < Option < BlockInfo > > {
131143 match block_ref {
132144 BlockReference :: Origin => Ok ( None ) ,
133- BlockReference :: Point ( number , hash) => {
145+ BlockReference :: Point ( slot , hash) => {
134146 let chain = self . chain . read ( ) . await ;
135147 Ok ( chain
136- . get ( * number as usize )
137- . filter ( |b| b. block_hash == * hash)
148+ . iter ( )
149+ . rev ( )
150+ . find ( |b| b. block_hash == * hash)
151+ . filter ( |b| b. block_slot == * slot)
138152 . cloned ( ) )
139153 }
140154 }
@@ -143,6 +157,7 @@ impl MockChain {
143157 // TODO: roll back sometimes
144158 async fn generate (
145159 chain : Arc < RwLock < Vec < BlockInfo > > > ,
160+ indexes : Arc < DashMap < String , usize > > ,
146161 new_block : Arc < Notify > ,
147162 _rolled_back : Arc < DashMap < BlockReference , BlockReference > > ,
148163 initial_height : usize ,
@@ -151,33 +166,39 @@ impl MockChain {
151166 {
152167 let mut lock = chain. write ( ) . await ;
153168 for _ in 0 ..initial_height {
154- Self :: generate_block ( & mut rng, & mut lock) ;
169+ Self :: generate_block ( & mut rng, & mut lock, & indexes ) ;
155170 }
156171 }
157172 loop {
158173 time:: sleep ( Duration :: from_secs ( 1 ) ) . await ;
159174 let mut lock = chain. write ( ) . await ;
160- Self :: generate_block ( & mut rng, & mut lock) ;
175+ Self :: generate_block ( & mut rng, & mut lock, & indexes ) ;
161176 new_block. notify_waiters ( ) ;
162177 }
163178 }
164179
165- fn generate_block ( rng : & mut ChaChaRng , chain : & mut Vec < BlockInfo > ) {
166- let ( block_number, parent_hash) = match chain. last ( ) {
167- Some ( block) => ( block. block_number + 1 , block. block_hash . clone ( ) ) ,
168- None => ( 0 , "" . into ( ) ) ,
180+ fn generate_block (
181+ rng : & mut ChaChaRng ,
182+ chain : & mut Vec < BlockInfo > ,
183+ indexes : & DashMap < String , usize > ,
184+ ) {
185+ let ( block_height, parent_hash) = match chain. last ( ) {
186+ Some ( block) => ( Some ( chain. len ( ) as u64 ) , Some ( block. block_hash . clone ( ) ) ) ,
187+ None => ( None , None ) ,
169188 } ;
170189
171190 let mut transaction_hashes = vec ! [ ] ;
172191 for _ in 0 ..rng. gen_range ( 0 ..10 ) {
173192 transaction_hashes. push ( Self :: generate_hash ( rng) ) ;
174193 }
175194 let block = BlockInfo {
176- block_number,
195+ block_height,
196+ block_slot : block_height,
177197 block_hash : Self :: generate_hash ( rng) ,
178198 parent_hash,
179199 transaction_hashes,
180200 } ;
201+ indexes. insert ( block. block_hash . clone ( ) , chain. len ( ) ) ;
181202 chain. push ( block) ;
182203 }
183204
0 commit comments