@@ -9,7 +9,8 @@ use charon_crypto::{blst_impl::BlstImpl, tbls::Tbls, types::Signature};
99use serde:: { Deserialize , Serialize } ;
1010
1111use charon_cluster:: {
12- helpers:: left_pad,
12+ helpers:: to_0x_hex,
13+ ssz:: { SSZ_LEN_BLS_SIG , SSZ_LEN_PUB_KEY } ,
1314 ssz_hasher:: { HashWalker , Hasher } ,
1415} ;
1516use eth2api:: types:: {
@@ -19,12 +20,15 @@ use eth2api::types::{
1920use crate :: obolapi:: {
2021 client:: Client ,
2122 error:: { Error , Result } ,
22- helper:: { bearer_string, from_0x, to_0x } ,
23+ helper:: { bearer_string, from_0x} ,
2324} ;
2425
2526/// Type alias for signed voluntary exit from eth2api.
2627pub type SignedVoluntaryExit = GetPoolVoluntaryExitsResponseResponseDatum ;
2728
29+ // TODO: Unify SSZ hashing across the workspace. `charon-cluster` already has
30+ // SSZ hashing utilities. Consider extracting a shared SSZ crate (or promoting
31+ // the existing hasher) so all crates share one SSZ interface and error type.
2832/// Trait for types that can be hashed using SSZ hash tree root.
2933pub trait SszHashable {
3034 /// Hashes this value into the provided hasher.
@@ -44,7 +48,7 @@ impl SszHashable for SignedVoluntaryExit {
4448
4549 self . message . hash_with ( hh) ?;
4650 let sig_bytes = from_0x ( & self . signature , SSZ_LEN_BLS_SIG ) ?;
47- put_bytes_n ( hh, & sig_bytes, SSZ_LEN_BLS_SIG ) ?;
51+ charon_cluster :: helpers :: put_bytes_n ( hh, & sig_bytes, SSZ_LEN_BLS_SIG ) ?;
4852
4953 hh. merkleize ( index) ?;
5054 Ok ( ( ) )
@@ -190,7 +194,7 @@ impl From<PartialExitRequest> for PartialExitRequestDto {
190194 fn from ( req : PartialExitRequest ) -> Self {
191195 Self {
192196 unsigned : req. unsigned ,
193- signature : to_0x ( & req. signature ) ,
197+ signature : to_0x_hex ( & req. signature ) ,
194198 }
195199 }
196200}
@@ -232,16 +236,14 @@ impl SszHashable for FullExitAuthBlob {
232236 let index = hh. index ( ) ;
233237
234238 hh. put_bytes ( & self . lock_hash ) ?;
235- put_bytes_n ( hh, & self . validator_pubkey , SSZ_LEN_PUB_KEY ) ?;
239+ charon_cluster :: helpers :: put_bytes_n ( hh, & self . validator_pubkey , SSZ_LEN_PUB_KEY ) ?;
236240 hh. put_uint64 ( self . share_index ) ?;
237241
238242 hh. merkleize ( index) ?;
239243 Ok ( ( ) )
240244 }
241245}
242246const SSZ_MAX_EXITS : usize = 65536 ;
243- const SSZ_LEN_PUB_KEY : usize = 48 ;
244- const SSZ_LEN_BLS_SIG : usize = 96 ;
245247
246248impl Client {
247249 /// Posts the set of msg's to the Obol API, for a given lock hash.
@@ -253,7 +255,7 @@ impl Client {
253255 identity_key : & k256:: SecretKey ,
254256 mut exit_blobs : Vec < ExitBlob > ,
255257 ) -> Result < ( ) > {
256- let lock_hash_str = to_0x ( lock_hash) ;
258+ let lock_hash_str = to_0x_hex ( lock_hash) ;
257259 let path = submit_partial_exit_url ( & lock_hash_str) ;
258260
259261 let url = self . build_url ( & path) ?;
@@ -300,7 +302,7 @@ impl Client {
300302 // Validate public key is 48 bytes
301303 let val_pubkey_bytes = from_0x ( val_pubkey, 48 ) ?;
302304
303- let path = fetch_full_exit_url ( val_pubkey, & to_0x ( lock_hash) , share_index) ;
305+ let path = fetch_full_exit_url ( val_pubkey, & to_0x_hex ( lock_hash) , share_index) ;
304306
305307 let url = self . build_url ( & path) ?;
306308
@@ -362,7 +364,7 @@ impl Client {
362364 epoch : epoch_u64. to_string ( ) ,
363365 validator_index : exit_response. validator_index . to_string ( ) ,
364366 } ,
365- signature : to_0x ( & full_sig) ,
367+ signature : to_0x_hex ( & full_sig) ,
366368 } ,
367369 } )
368370 }
@@ -380,7 +382,7 @@ impl Client {
380382 // Validate public key is 48 bytes
381383 let val_pubkey_bytes = from_0x ( val_pubkey, 48 ) ?;
382384
383- let path = delete_partial_exit_url ( val_pubkey, & to_0x ( lock_hash) , share_index) ;
385+ let path = delete_partial_exit_url ( val_pubkey, & to_0x_hex ( lock_hash) , share_index) ;
384386
385387 let url = self . build_url ( & path) ?;
386388
@@ -423,19 +425,6 @@ fn fetch_full_exit_url(val_pubkey: &str, lock_hash: &str, share_index: u64) -> S
423425 format ! ( "/exp/exit/{}/{}/{}" , lock_hash, share_index, val_pubkey)
424426}
425427
426- fn put_bytes_n ( hh : & mut Hasher , bytes : & [ u8 ] , expected_len : usize ) -> Result < ( ) > {
427- if bytes. len ( ) > expected_len {
428- use charon_cluster:: ssz:: SSZError ;
429- return Err ( Error :: Ssz ( SSZError :: UnsupportedVersion ( format ! (
430- "bytes too long: expected {}, got {}" ,
431- expected_len,
432- bytes. len( )
433- ) ) ) ) ;
434- }
435- let padded: Vec < u8 > = left_pad ( bytes, expected_len) ;
436- Ok ( hh. put_bytes ( & padded) ?)
437- }
438-
439428#[ cfg( test) ]
440429mod tests {
441430 use super :: * ;
@@ -486,7 +475,7 @@ mod tests {
486475 404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f";
487476
488477 let exit_blob = ExitBlob {
489- public_key : Some ( to_0x ( & validator_pubkey) ) ,
478+ public_key : Some ( to_0x_hex ( & validator_pubkey) ) ,
490479 signed_exit_message : SignedVoluntaryExit {
491480 message : Phase0SignedVoluntaryExitMessage {
492481 epoch : "194048" . to_string ( ) ,
0 commit comments