@@ -202,7 +202,7 @@ const FETCH_FULL_EXIT_TMPL: &str = "/exp/exit/{lock_hash}/{share_index}/{validat
202202
203203impl Client {
204204 /// Posts the set of msg's to the Obol API, for a given lock hash.
205- // It respects the timeout specified in the Client instance.
205+ /// It respects the timeout specified in the Client instance.
206206 pub async fn post_partial_exits (
207207 & self ,
208208 lock_hash : & [ u8 ] ,
@@ -301,11 +301,9 @@ impl Client {
301301 let mut sig = [ 0u8 ; 96 ] ;
302302 sig. copy_from_slice ( & sig_bytes) ;
303303
304- // Signature indices are 1-based in threshold BLS
305- let share_idx = sig_idx
306- . checked_add ( 1 )
307- . and_then ( |idx| u8:: try_from ( idx) . ok ( ) )
308- . ok_or_else ( || Error :: InvalidSignatureSize ( sig_idx. saturating_add ( 1 ) ) ) ?;
304+ // `BlstImpl::threshold_aggregate` shifts the index to 1-based internally
305+ let share_idx = u8:: try_from ( sig_idx)
306+ . map_err ( |_| Error :: InvalidSignatureSize ( sig_idx. saturating_add ( 1 ) ) ) ?;
309307 raw_signatures. insert ( share_idx, sig) ;
310308 }
311309
@@ -328,7 +326,7 @@ impl Client {
328326
329327 /// Deletes the partial exit message for a given validator public key, lock
330328 /// hash and share index.
331- // It respects the timeout specified in the Client instance.
329+ /// It respects the timeout specified in the Client instance.
332330 pub async fn delete_partial_exit (
333331 & self ,
334332 val_pubkey : & str ,
@@ -608,4 +606,74 @@ mod tests {
608606 "https://api.obol.tech/v1/exp/exit/0xlockhash/5/0xpubkey"
609607 ) ;
610608 }
609+
610+ /// These test vectors were generated from Go `charon/app/obolapi` using
611+ /// fastssz
612+ #[ test]
613+ fn test_ssz_root_parity_exit_models ( ) -> std:: result:: Result < ( ) , Box < dyn std:: error:: Error > > {
614+ fn decode_hex ( s : & str ) -> std:: result:: Result < Vec < u8 > , hex:: FromHexError > {
615+ hex:: decode ( s)
616+ }
617+
618+ fn decode_hex_32 ( s : & str ) -> std:: result:: Result < [ u8 ; 32 ] , Box < dyn std:: error:: Error > > {
619+ let bytes = decode_hex ( s) ?;
620+ let len = bytes. len ( ) ;
621+ let arr: [ u8 ; 32 ] = bytes
622+ . try_into ( )
623+ . map_err ( |_| format ! ( "expected 32 bytes, got {}" , len) ) ?;
624+ Ok ( arr)
625+ }
626+
627+ let lock_hash: Vec < u8 > =
628+ decode_hex ( "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" ) ?;
629+ let validator_pubkey: Vec < u8 > = decode_hex (
630+ "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20\
631+ 2122232425262728292a2b2c2d2e2f30",
632+ ) ?;
633+ let bls_sig_hex = "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\
634+ 202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f\
635+ 404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f";
636+
637+ let exit_blob = ExitBlob {
638+ public_key : Some ( to_0x ( & validator_pubkey) ) ,
639+ signed_exit_message : SignedVoluntaryExit {
640+ message : Phase0SignedVoluntaryExitMessage {
641+ epoch : "194048" . to_string ( ) ,
642+ validator_index : "42" . to_string ( ) ,
643+ } ,
644+ signature : bls_sig_hex. to_string ( ) ,
645+ } ,
646+ } ;
647+ let partial_exits: PartialExits = vec ! [ exit_blob. clone( ) ] . into ( ) ;
648+ let unsigned = UnsignedPartialExitRequest {
649+ partial_exits : partial_exits. clone ( ) ,
650+ share_idx : 3 ,
651+ } ;
652+ let auth = FullExitAuthBlob {
653+ lock_hash,
654+ validator_pubkey,
655+ share_index : 3 ,
656+ } ;
657+
658+ let got_exit = exit_blob. hash_tree_root ( ) ?;
659+ let got_partial = partial_exits. hash_tree_root ( ) ?;
660+ let got_unsigned = unsigned. hash_tree_root ( ) ?;
661+ let got_auth = auth. hash_tree_root ( ) ?;
662+
663+ let want_exit =
664+ decode_hex_32 ( "af0b1a9d98ac628035219391f59ee2708d813a3d860c6d17fa8cae0fb0746d20" ) ?;
665+ let want_partial =
666+ decode_hex_32 ( "9f310361788c9dfc6b0a3cfd77febad4c9a834c368be91ae0e570a40f82e810e" ) ?;
667+ let want_unsigned =
668+ decode_hex_32 ( "b58b5989634e567fa82b7c141918e30e44051c1ed6d0c36c3269021c531f4669" ) ?;
669+ let want_auth =
670+ decode_hex_32 ( "f7fec0dccbdeba7a7aa5978058df8891d1c403bb455a481677ecb5360b2f7fd6" ) ?;
671+
672+ assert_eq ! ( got_exit, want_exit) ;
673+ assert_eq ! ( got_partial, want_partial) ;
674+ assert_eq ! ( got_unsigned, want_unsigned) ;
675+ assert_eq ! ( got_auth, want_auth) ;
676+
677+ Ok ( ( ) )
678+ }
611679}
0 commit comments