@@ -18,6 +18,8 @@ use webb_primitives::utils::{
18
18
compute_chain_id_type, derive_resource_id, get_typed_chain_id_in_u64,
19
19
} ;
20
20
21
+ use webb_proposals:: substrate:: AnchorUpdateProposal ;
22
+
21
23
const TEST_MAX_EDGES : u32 = 100 ;
22
24
const TEST_TREE_DEPTH : u8 = 32 ;
23
25
@@ -74,6 +76,15 @@ fn make_proposal_data(encoded_r_id: Vec<u8>, nonce: [u8; 4], encoded_call: Vec<u
74
76
prop_data
75
77
}
76
78
79
+ fn get_edsca_account ( ) -> ecdsa:: Pair {
80
+ let seed = "0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" ;
81
+ ecdsa:: Pair :: from_string ( seed, None ) . unwrap ( )
82
+ }
83
+
84
+ fn get_public_uncompressed_key ( ) -> [ u8 ; 64 ] {
85
+ hex ! ( "8db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd913ebbe148dd17c56551a52952371071a6c604b3f3abe8f2c8fa742158ea6dd7d4" )
86
+ }
87
+
77
88
// Signature Bridge Tests
78
89
79
90
#[ test]
@@ -83,12 +94,8 @@ fn should_create_anchor_with_sig_succeed() {
83
94
let this_chain_id_u32 = 5u32 ;
84
95
let this_chain_id = get_typed_chain_id_in_u64 ( this_chain_id_u32) ;
85
96
let r_id = derive_resource_id ( this_chain_id_u32, 5 ) . into ( ) ;
86
- let public_uncompressed = hex ! ( "8db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd913ebbe148dd17c56551a52952371071a6c604b3f3abe8f2c8fa742158ea6dd7d4" ) ;
87
- let pair = ecdsa:: Pair :: from_string (
88
- "0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" ,
89
- None ,
90
- )
91
- . unwrap ( ) ;
97
+ let public_uncompressed = get_public_uncompressed_key ( ) ;
98
+ let pair = get_edsca_account ( ) ;
92
99
93
100
new_test_ext_initialized ( src_id, r_id, b"AnchorHandler.execute_anchor_create_proposal" . to_vec ( ) )
94
101
. execute_with ( || {
@@ -145,14 +152,8 @@ fn should_add_anchor_edge_with_sig_succeed() {
145
152
let this_chain_id_u32 = 5u32 ;
146
153
let this_chain_id = get_typed_chain_id_in_u64 ( this_chain_id_u32) ;
147
154
let r_id = derive_resource_id ( this_chain_id_u32, 5 ) . into ( ) ;
148
- let public_uncompressed =
149
- hex ! ( "8db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd913ebbe148dd17c56551a52952371071a6c604b3f3abe8f2c8fa742158ea6dd7d4"
150
- ) ;
151
- let pair = ecdsa:: Pair :: from_string (
152
- "0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" ,
153
- None ,
154
- )
155
- . unwrap ( ) ;
155
+ let public_uncompressed = get_public_uncompressed_key ( ) ;
156
+ let pair = get_edsca_account ( ) ;
156
157
157
158
new_test_ext_initialized ( src_id, r_id, b"AnchorHandler.execute_anchor_update_proposal" . to_vec ( ) )
158
159
. execute_with ( || {
@@ -227,14 +228,8 @@ fn should_update_anchor_edge_with_sig_succeed() {
227
228
let this_chain_id_u32 = 5u32 ;
228
229
let this_chain_id = get_typed_chain_id_in_u64 ( this_chain_id_u32) ;
229
230
let r_id = derive_resource_id ( this_chain_id_u32, 5 ) . into ( ) ;
230
- let public_uncompressed =
231
- hex ! ( "8db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd913ebbe148dd17c56551a52952371071a6c604b3f3abe8f2c8fa742158ea6dd7d4"
232
- ) ;
233
- let pair = ecdsa:: Pair :: from_string (
234
- "0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" ,
235
- None ,
236
- )
237
- . unwrap ( ) ;
231
+ let public_uncompressed = get_public_uncompressed_key ( ) ;
232
+ let pair = get_edsca_account ( ) ;
238
233
239
234
new_test_ext_initialized ( src_id, r_id, b"AnchorHandler.execute_anchor_update_proposal" . to_vec ( ) )
240
235
. execute_with ( || {
@@ -345,14 +340,8 @@ fn should_fail_to_whitelist_chain_already_whitelisted() {
345
340
let this_chain_id_u32 = 5u32 ;
346
341
let this_chain_id = get_typed_chain_id_in_u64 ( this_chain_id_u32) ;
347
342
let r_id = derive_resource_id ( this_chain_id_u32, 5 ) . into ( ) ;
348
- let public_uncompressed =
349
- hex ! ( "8db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd913ebbe148dd17c56551a52952371071a6c604b3f3abe8f2c8fa742158ea6dd7d4"
350
- ) ;
351
- let pair = ecdsa:: Pair :: from_string (
352
- "0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" ,
353
- None ,
354
- )
355
- . unwrap ( ) ;
343
+ let public_uncompressed = get_public_uncompressed_key ( ) ;
344
+ let pair = get_edsca_account ( ) ;
356
345
357
346
new_test_ext_initialized ( src_id, r_id, b"AnchorHandler.execute_anchor_create_proposal" . to_vec ( ) )
358
347
. execute_with ( || {
@@ -371,14 +360,8 @@ fn should_fail_to_whitelist_this_chain() {
371
360
let this_chain_id_u32 = 5u32 ;
372
361
let this_chain_id = get_typed_chain_id_in_u64 ( this_chain_id_u32) ;
373
362
let r_id = derive_resource_id ( this_chain_id_u32, 5 ) . into ( ) ;
374
- let public_uncompressed =
375
- hex ! ( "8db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd913ebbe148dd17c56551a52952371071a6c604b3f3abe8f2c8fa742158ea6dd7d4"
376
- ) ;
377
- let pair = ecdsa:: Pair :: from_string (
378
- "0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" ,
379
- None ,
380
- )
381
- . unwrap ( ) ;
363
+ let public_uncompressed = get_public_uncompressed_key ( ) ;
364
+ let pair = get_edsca_account ( ) ;
382
365
383
366
new_test_ext_initialized ( src_id, r_id, b"AnchorHandler.execute_anchor_create_proposal" . to_vec ( ) )
384
367
. execute_with ( || {
@@ -400,14 +383,8 @@ fn should_fail_to_execute_proposal_from_non_whitelisted_chain() {
400
383
let this_chain_id_u32 = 5u32 ;
401
384
let this_chain_id = get_typed_chain_id_in_u64 ( this_chain_id_u32) ;
402
385
let r_id = derive_resource_id ( this_chain_id_u32, 5 ) . into ( ) ;
403
- let public_uncompressed =
404
- hex ! ( "8db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd913ebbe148dd17c56551a52952371071a6c604b3f3abe8f2c8fa742158ea6dd7d4"
405
- ) ;
406
- let pair = ecdsa:: Pair :: from_string (
407
- "0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" ,
408
- None ,
409
- )
410
- . unwrap ( ) ;
386
+ let public_uncompressed = get_public_uncompressed_key ( ) ;
387
+ let pair = get_edsca_account ( ) ;
411
388
412
389
new_test_ext_initialized ( src_id, r_id, b"AnchorHandler.execute_anchor_create_proposal" . to_vec ( ) )
413
390
. execute_with ( || {
@@ -445,14 +422,8 @@ fn should_fail_to_execute_proposal_with_non_existent_resource_id() {
445
422
let this_chain_id_u32 = 5u32 ;
446
423
let this_chain_id = get_typed_chain_id_in_u64 ( this_chain_id_u32) ;
447
424
let r_id = derive_resource_id ( this_chain_id_u32, 5 ) . into ( ) ;
448
- let public_uncompressed =
449
- hex ! ( "8db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd913ebbe148dd17c56551a52952371071a6c604b3f3abe8f2c8fa742158ea6dd7d4"
450
- ) ;
451
- let pair = ecdsa:: Pair :: from_string (
452
- "0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" ,
453
- None ,
454
- )
455
- . unwrap ( ) ;
425
+ let public_uncompressed = get_public_uncompressed_key ( ) ;
426
+ let pair = get_edsca_account ( ) ;
456
427
457
428
new_test_ext_initialized ( src_id, r_id, b"AnchorHandler.execute_anchor_create_proposal" . to_vec ( ) )
458
429
. execute_with ( || {
@@ -493,14 +464,8 @@ fn should_fail_to_verify_proposal_with_tampered_signature() {
493
464
let this_chain_id_u32 = 5u32 ;
494
465
let this_chain_id = get_typed_chain_id_in_u64 ( this_chain_id_u32) ;
495
466
let r_id = derive_resource_id ( this_chain_id_u32, 5 ) . into ( ) ;
496
- let public_uncompressed =
497
- hex ! ( "8db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd913ebbe148dd17c56551a52952371071a6c604b3f3abe8f2c8fa742158ea6dd7d4"
498
- ) ;
499
- let pair = ecdsa:: Pair :: from_string (
500
- "0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" ,
501
- None ,
502
- )
503
- . unwrap ( ) ;
467
+ let public_uncompressed = get_public_uncompressed_key ( ) ;
468
+ let pair = get_edsca_account ( ) ;
504
469
505
470
new_test_ext_initialized ( src_id, r_id, b"AnchorHandler.execute_anchor_create_proposal" . to_vec ( ) )
506
471
. execute_with ( || {
@@ -534,3 +499,150 @@ hex!("8db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd913ebbe148dd
534
499
) ;
535
500
} )
536
501
}
502
+
503
+ // Test AnchorUpdateProposal using webb-proposals
504
+ // 1. Create an anchor using `pallet-anchor` intrinsic call
505
+ // 2. Add an edge to the anchor using `pallet-anchor-handler` proposal through
506
+ // `pallet-signature-bridge`
507
+ // 3. Update the edge of the anchor using
508
+ // `pallet-anchor-handler` proposal through `pallet-signature-bridge`
509
+ #[ test]
510
+ fn should_update_anchor_edge_with_sig_succeed_using_webb_proposals ( ) {
511
+ let src_chain = webb_proposals:: TypedChainId :: Substrate ( 1 ) ;
512
+ let this_chain_id = webb_proposals:: TypedChainId :: Substrate ( 5 ) ;
513
+ let target_system = webb_proposals:: TargetSystem :: new_tree_id ( 5 ) ;
514
+ let resource = webb_proposals:: ResourceId :: new ( target_system, this_chain_id) ;
515
+
516
+ let src_id = src_chain. chain_id ( ) ;
517
+ let r_id = resource. to_bytes ( ) ;
518
+ let public_uncompressed = get_public_uncompressed_key ( ) ;
519
+ let pair = get_edsca_account ( ) ;
520
+
521
+ new_test_ext_initialized ( src_id, r_id, b"AnchorHandler.execute_anchor_update_proposal" . to_vec ( ) )
522
+ . execute_with ( || {
523
+ let curve = Curve :: Bn254 ;
524
+ let params = setup_params :: < ark_bn254:: Fr > ( curve, 5 , 3 ) ;
525
+ let res = HasherPallet :: force_set_parameters ( Origin :: root ( ) , params. to_bytes ( ) ) ;
526
+
527
+ mock_anchor_creation_using_pallet_call ( src_id, & r_id) ;
528
+
529
+ let root_bytes = [ 1u8 ; 32 ] ;
530
+ let root = Element :: from_bytes ( & root_bytes) ;
531
+ let latest_leaf_index = 5 ;
532
+ let target_bytes = [ 0u8 ; 32 ] ;
533
+ let target = Element :: from_bytes ( & target_bytes) ;
534
+
535
+ assert_eq ! ( 0 , Counts :: <Test >:: get( src_id) ) ;
536
+ let edge_metadata =
537
+ EdgeMetadata { src_chain_id : src_id, root, latest_leaf_index, target } ;
538
+
539
+ let anchor_update_proposal = AnchorUpdateProposal :: builder ( )
540
+ . resource_id ( resource)
541
+ . src_chain ( src_chain)
542
+ . merkle_root ( root_bytes)
543
+ . latest_leaf_index ( latest_leaf_index)
544
+ . target ( target_bytes)
545
+ . pallet_index ( 10 )
546
+ . build ( ) ;
547
+
548
+ let nonce = [ 0u8 , 0u8 , 0u8 , 1u8 ] ;
549
+ let anchor_update_proposal_bytes = anchor_update_proposal. to_bytes ( ) ;
550
+ let prop_data =
551
+ make_proposal_data ( r_id. encode ( ) , nonce, anchor_update_proposal_bytes. clone ( ) ) ;
552
+ let msg = keccak_256 ( & prop_data) ;
553
+ let sig: Signature = pair. sign_prehashed ( & msg) . into ( ) ;
554
+
555
+ // set the maintainer
556
+ assert_ok ! ( SignatureBridge :: force_set_maintainer(
557
+ Origin :: root( ) ,
558
+ public_uncompressed. to_vec( )
559
+ ) ) ;
560
+
561
+ let anchor_update_call: Call =
562
+ codec:: Decode :: decode ( & mut anchor_update_proposal_bytes. as_slice ( ) ) . unwrap ( ) ;
563
+ assert_ok ! ( SignatureBridge :: execute_proposal(
564
+ Origin :: signed( RELAYER_A ) ,
565
+ src_id,
566
+ Box :: new( anchor_update_call) ,
567
+ prop_data,
568
+ sig. 0 . to_vec( ) ,
569
+ ) ) ;
570
+ assert_eq ! ( 1 , Counts :: <Test >:: get( src_id) ) ;
571
+
572
+ // the anchor-handler callback must have been called by bridge
573
+ // event must be emitted in callback should exist
574
+ event_exists ( crate :: Event :: AnchorEdgeAdded ) ;
575
+ // edge count should be 1
576
+ assert_eq ! (
577
+ 1 ,
578
+ <pallet_linkable_tree:: EdgeList <Test >>:: iter_prefix_values( 0 )
579
+ . into_iter( )
580
+ . count( )
581
+ ) ;
582
+
583
+ let expected_tree_id = 0 ;
584
+ assert_eq ! (
585
+ edge_metadata,
586
+ <pallet_linkable_tree:: EdgeList <Test >>:: get( expected_tree_id, src_id)
587
+ ) ;
588
+
589
+ let expected_update_record =
590
+ UpdateRecord { tree_id : expected_tree_id, resource_id : r_id, edge_metadata } ;
591
+ assert_eq ! ( expected_update_record, UpdateRecords :: <Test >:: get( src_id, 0 ) ) ;
592
+
593
+ // Update Edge
594
+ let root_bytes = [ 2u8 ; 32 ] ;
595
+ let root = Element :: from_bytes ( & root_bytes) ;
596
+ let latest_leaf_index = 10 ;
597
+ let target_bytes = [ 0u8 ; 32 ] ;
598
+ let target = Element :: from_bytes ( & target_bytes) ;
599
+ let edge_metadata =
600
+ EdgeMetadata { src_chain_id : src_id, root, latest_leaf_index, target } ;
601
+
602
+ let anchor_update_proposal = AnchorUpdateProposal :: builder ( )
603
+ . resource_id ( resource)
604
+ . src_chain ( src_chain)
605
+ . merkle_root ( root_bytes)
606
+ . latest_leaf_index ( latest_leaf_index)
607
+ . target ( target_bytes)
608
+ . pallet_index ( 10 )
609
+ . build ( ) ;
610
+
611
+ let nonce = [ 0u8 , 0u8 , 0u8 , 2u8 ] ;
612
+ let anchor_update_proposal_bytes = anchor_update_proposal. to_bytes ( ) ;
613
+ let prop_data =
614
+ make_proposal_data ( r_id. encode ( ) , nonce, anchor_update_proposal_bytes. clone ( ) ) ;
615
+ let msg = keccak_256 ( & prop_data) ;
616
+ let sig: Signature = pair. sign_prehashed ( & msg) . into ( ) ;
617
+
618
+ let anchor_update_call: Call =
619
+ codec:: Decode :: decode ( & mut anchor_update_proposal_bytes. as_slice ( ) ) . unwrap ( ) ;
620
+ assert_ok ! ( SignatureBridge :: execute_proposal(
621
+ Origin :: signed( RELAYER_A ) ,
622
+ src_id,
623
+ Box :: new( anchor_update_call) ,
624
+ prop_data,
625
+ sig. 0 . to_vec( ) ,
626
+ ) ) ;
627
+
628
+ assert_eq ! ( 2 , Counts :: <Test >:: get( src_id) ) ;
629
+
630
+ // the anchor-handler callback must have been called by bridge
631
+ // event must be emitted in callback should exist
632
+ event_exists ( crate :: Event :: AnchorEdgeUpdated ) ;
633
+ // edge count should be 1
634
+ assert_eq ! (
635
+ 1 ,
636
+ <pallet_linkable_tree:: EdgeList <Test >>:: iter_prefix_values( 0 )
637
+ . into_iter( )
638
+ . count( )
639
+ ) ;
640
+ assert_eq ! (
641
+ edge_metadata,
642
+ <pallet_linkable_tree:: EdgeList <Test >>:: get( expected_tree_id, src_id)
643
+ ) ;
644
+ let expected_update_record =
645
+ UpdateRecord { tree_id : expected_tree_id, resource_id : r_id, edge_metadata } ;
646
+ assert_eq ! ( expected_update_record, UpdateRecords :: <Test >:: get( src_id, 1 ) ) ;
647
+ } )
648
+ }
0 commit comments