@@ -18,6 +18,8 @@ use webb_primitives::utils::{
1818 compute_chain_id_type, derive_resource_id, get_typed_chain_id_in_u64,
1919} ;
2020
21+ use webb_proposals:: substrate:: AnchorUpdateProposal ;
22+
2123const TEST_MAX_EDGES : u32 = 100 ;
2224const TEST_TREE_DEPTH : u8 = 32 ;
2325
@@ -74,6 +76,15 @@ fn make_proposal_data(encoded_r_id: Vec<u8>, nonce: [u8; 4], encoded_call: Vec<u
7476 prop_data
7577}
7678
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+
7788// Signature Bridge Tests
7889
7990#[ test]
@@ -83,12 +94,8 @@ fn should_create_anchor_with_sig_succeed() {
8394 let this_chain_id_u32 = 5u32 ;
8495 let this_chain_id = get_typed_chain_id_in_u64 ( this_chain_id_u32) ;
8596 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 ( ) ;
9299
93100 new_test_ext_initialized ( src_id, r_id, b"AnchorHandler.execute_anchor_create_proposal" . to_vec ( ) )
94101 . execute_with ( || {
@@ -145,14 +152,8 @@ fn should_add_anchor_edge_with_sig_succeed() {
145152 let this_chain_id_u32 = 5u32 ;
146153 let this_chain_id = get_typed_chain_id_in_u64 ( this_chain_id_u32) ;
147154 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 ( ) ;
156157
157158 new_test_ext_initialized ( src_id, r_id, b"AnchorHandler.execute_anchor_update_proposal" . to_vec ( ) )
158159 . execute_with ( || {
@@ -227,14 +228,8 @@ fn should_update_anchor_edge_with_sig_succeed() {
227228 let this_chain_id_u32 = 5u32 ;
228229 let this_chain_id = get_typed_chain_id_in_u64 ( this_chain_id_u32) ;
229230 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 ( ) ;
238233
239234 new_test_ext_initialized ( src_id, r_id, b"AnchorHandler.execute_anchor_update_proposal" . to_vec ( ) )
240235 . execute_with ( || {
@@ -345,14 +340,8 @@ fn should_fail_to_whitelist_chain_already_whitelisted() {
345340 let this_chain_id_u32 = 5u32 ;
346341 let this_chain_id = get_typed_chain_id_in_u64 ( this_chain_id_u32) ;
347342 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 ( ) ;
356345
357346 new_test_ext_initialized ( src_id, r_id, b"AnchorHandler.execute_anchor_create_proposal" . to_vec ( ) )
358347 . execute_with ( || {
@@ -371,14 +360,8 @@ fn should_fail_to_whitelist_this_chain() {
371360 let this_chain_id_u32 = 5u32 ;
372361 let this_chain_id = get_typed_chain_id_in_u64 ( this_chain_id_u32) ;
373362 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 ( ) ;
382365
383366 new_test_ext_initialized ( src_id, r_id, b"AnchorHandler.execute_anchor_create_proposal" . to_vec ( ) )
384367 . execute_with ( || {
@@ -400,14 +383,8 @@ fn should_fail_to_execute_proposal_from_non_whitelisted_chain() {
400383 let this_chain_id_u32 = 5u32 ;
401384 let this_chain_id = get_typed_chain_id_in_u64 ( this_chain_id_u32) ;
402385 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 ( ) ;
411388
412389 new_test_ext_initialized ( src_id, r_id, b"AnchorHandler.execute_anchor_create_proposal" . to_vec ( ) )
413390 . execute_with ( || {
@@ -445,14 +422,8 @@ fn should_fail_to_execute_proposal_with_non_existent_resource_id() {
445422 let this_chain_id_u32 = 5u32 ;
446423 let this_chain_id = get_typed_chain_id_in_u64 ( this_chain_id_u32) ;
447424 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 ( ) ;
456427
457428 new_test_ext_initialized ( src_id, r_id, b"AnchorHandler.execute_anchor_create_proposal" . to_vec ( ) )
458429 . execute_with ( || {
@@ -493,14 +464,8 @@ fn should_fail_to_verify_proposal_with_tampered_signature() {
493464 let this_chain_id_u32 = 5u32 ;
494465 let this_chain_id = get_typed_chain_id_in_u64 ( this_chain_id_u32) ;
495466 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 ( ) ;
504469
505470 new_test_ext_initialized ( src_id, r_id, b"AnchorHandler.execute_anchor_create_proposal" . to_vec ( ) )
506471 . execute_with ( || {
@@ -534,3 +499,150 @@ hex!("8db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd913ebbe148dd
534499 ) ;
535500 } )
536501}
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