@@ -62,6 +62,46 @@ pub mod benchmarks {
6262 _ ( RawOrigin :: Signed ( caller) , block. header , height) ;
6363 }
6464
65+ #[ benchmark]
66+ pub fn set_chainwork_for_block ( ) {
67+ let caller: T :: AccountId = whitelisted_caller ( ) ;
68+
69+ let init_block = initialize_relay :: < T > ( caller. clone ( ) ) ;
70+ let init_block_hash = init_block. header . hash ;
71+
72+ migration:: v1:: migrate_from_v0_to_v1 :: < T > ( ) ;
73+
74+ let block = add_new_block_to_relay :: < T > ( caller. clone ( ) , init_block_hash, 0 ) ;
75+
76+ #[ extrinsic_call]
77+ _ ( RawOrigin :: Signed ( caller) , block. header . hash ) ;
78+
79+ // make sure chain work is stored
80+ assert_eq ! ( BtcRelay :: <T >:: contains_chainwork( block. header. hash) , true ) ;
81+ }
82+
83+ #[ benchmark]
84+ pub fn store_block_header_when_adding_chainwork ( ) {
85+ let caller: T :: AccountId = whitelisted_caller ( ) ;
86+
87+ let init_block = initialize_relay :: < T > ( caller. clone ( ) ) ;
88+ let init_block_hash = init_block. header . hash ;
89+
90+ migration:: v1:: migrate_from_v0_to_v1 :: < T > ( ) ;
91+
92+ let block = new_block :: < T > ( init_block_hash, 0 ) ;
93+
94+ #[ extrinsic_call]
95+ store_block_header ( RawOrigin :: Signed ( caller) , block. header , u32:: MAX ) ;
96+
97+ // make sure block is stored
98+ let rich_header = BtcRelay :: < T > :: get_block_header_from_hash ( block. header . hash ) . unwrap ( ) ;
99+ assert_eq ! ( rich_header. chain_id, MAIN_CHAIN_ID ) ;
100+
101+ // make sure chain work is stored
102+ assert_eq ! ( BtcRelay :: <T >:: contains_chainwork( block. header. hash) , true ) ;
103+ }
104+
65105 #[ benchmark]
66106 pub fn store_block_header ( ) {
67107 let caller: T :: AccountId = whitelisted_caller ( ) ;
@@ -140,11 +180,8 @@ pub mod benchmarks {
140180 }
141181 }
142182
143- BtcRelay :: < T > :: insert_block_hash ( 0 , DIFFICULTY_ADJUSTMENT_INTERVAL , init_block_hash) ;
144-
145183 // new fork up to block before swapping the main chain
146- for chain_id in 1 ..( BestBlockHeight :: < T > :: get ( ) + SECURE_BITCOIN_CONFIRMATIONS ) {
147- BtcRelay :: < T > :: insert_block_hash ( chain_id, DIFFICULTY_ADJUSTMENT_INTERVAL , init_block_hash) ;
184+ for _ in 1 ..( BestBlockHeight :: < T > :: get ( ) + SECURE_BITCOIN_CONFIRMATIONS ) {
148185 let block = add_new_block_to_relay :: < T > ( caller. clone ( ) , init_block_hash, f as usize ) ;
149186 init_block_hash = block. header . hash ;
150187 }
@@ -169,5 +206,55 @@ pub mod benchmarks {
169206 assert_eq ! ( rich_header. chain_id, MAIN_CHAIN_ID ) ;
170207 }
171208
209+ #[ benchmark]
210+ pub fn store_block_header_reorganize_chains_based_on_chainwork ( f : Linear < 3 , 6 > ) {
211+ let caller: T :: AccountId = whitelisted_caller ( ) ;
212+ StableBitcoinConfirmations :: < T > :: put ( SECURE_BITCOIN_CONFIRMATIONS ) ;
213+
214+ let init_block = initialize_relay :: < T > ( caller. clone ( ) ) ;
215+ let mut init_block_hash = init_block. header . hash ;
216+
217+ migration:: v1:: migrate_from_v0_to_v1 :: < T > ( ) ;
218+
219+ for i in 1 ..f {
220+ let mut block_hash = init_block_hash;
221+ for _ in 0 ..SECURE_BITCOIN_CONFIRMATIONS {
222+ let block = add_new_block_to_relay :: < T > ( caller. clone ( ) , block_hash, i as usize ) ;
223+ block_hash = block. header . hash ;
224+ }
225+ }
226+
227+ // new fork up to block before swapping the main chain
228+ for _ in 1 ..( BestBlockHeight :: < T > :: get ( ) + SECURE_BITCOIN_CONFIRMATIONS ) {
229+ let block = add_new_block_to_relay :: < T > ( caller. clone ( ) , init_block_hash, f as usize ) ;
230+ init_block_hash = block. header . hash ;
231+ }
232+
233+ let prev_best_block_height = BestBlockHeight :: < T > :: get ( ) ;
234+ assert_eq ! ( prev_best_block_height, SECURE_BITCOIN_CONFIRMATIONS ) ;
235+ assert_eq ! ( ChainsIndex :: <T >:: iter( ) . collect:: <Vec <_>>( ) . len( ) , f as usize ) ;
236+
237+ let mut last_entered_block = BtcRelay :: < T > :: get_block_header_from_hash ( init_block_hash) . unwrap ( ) ;
238+ last_entered_block. block_header . target = U256 :: max_value ( ) ;
239+ BlockHeaders :: < T > :: insert ( last_entered_block. block_header . hash , last_entered_block) ;
240+
241+ // we can benchmark the worst-case complexity for swapping
242+ // since we know how many blocks are required
243+ let mut block = new_block :: < T > ( init_block_hash, f as usize ) ;
244+ block. header . target = U256 :: max_value ( ) ;
245+ block. header . update_hash ( ) . unwrap ( ) ;
246+
247+ #[ extrinsic_call]
248+ store_block_header ( RawOrigin :: Signed ( caller) , block. header , u32:: MAX ) ;
249+
250+ // make sure reorg occurred
251+ assert_eq ! (
252+ BestBlockHeight :: <T >:: get( ) ,
253+ prev_best_block_height + SECURE_BITCOIN_CONFIRMATIONS
254+ ) ;
255+ let rich_header = BtcRelay :: < T > :: get_block_header_from_hash ( block. header . hash ) . unwrap ( ) ;
256+ assert_eq ! ( rich_header. chain_id, MAIN_CHAIN_ID ) ;
257+ }
258+
172259 impl_benchmark_test_suite ! ( BtcRelay , crate :: mock:: ExtBuilder :: build( ) , crate :: mock:: Test ) ;
173260}
0 commit comments