@@ -6,12 +6,10 @@ use std::{
66 time:: Duration ,
77} ;
88
9- use LidoCSMRegistry :: getNodeOperatorSummaryReturn;
109use alloy:: {
11- primitives:: { Address , Bytes , U256 , address } ,
10+ primitives:: { Address , Bytes , U256 } ,
1211 providers:: ProviderBuilder ,
1312 rpc:: { client:: RpcClient , types:: beacon:: constants:: BLS_PUBLIC_KEY_BYTES_LEN } ,
14- sol,
1513 transports:: http:: Http ,
1614} ;
1715use eyre:: { Context , bail, ensure} ;
@@ -23,9 +21,9 @@ use url::Url;
2321use super :: { MUX_PATH_ENV , PbsConfig , RelayConfig , load_optional_env_var} ;
2422use crate :: {
2523 config:: { remove_duplicate_keys, safe_read_http_response} ,
26- interop:: ssv:: utils:: fetch_ssv_pubkeys_from_url ,
24+ interop:: { lido :: utils :: * , ssv:: utils:: * } ,
2725 pbs:: RelayClient ,
28- types:: { BlsPublicKey , Chain , HoleskyLidoModule , HoodiLidoModule , MainnetLidoModule } ,
26+ types:: { BlsPublicKey , Chain } ,
2927 utils:: default_bool,
3028} ;
3129
@@ -291,194 +289,6 @@ fn get_mux_path(mux_id: &str) -> String {
291289 format ! ( "/{mux_id}-mux_keys.json" )
292290}
293291
294- sol ! {
295- #[ allow( missing_docs) ]
296- #[ sol( rpc) ]
297- LidoRegistry ,
298- "src/abi/LidoNORegistry.json"
299- }
300-
301- sol ! {
302- #[ allow( missing_docs) ]
303- #[ sol( rpc) ]
304- LidoCSMRegistry ,
305- "src/abi/LidoCSModuleNORegistry.json"
306- }
307-
308- fn lido_registry_addresses_by_module ( ) -> HashMap < Chain , HashMap < u8 , Address > > {
309- let mut map: HashMap < Chain , HashMap < u8 , Address > > = HashMap :: new ( ) ;
310-
311- // --- Mainnet ---
312- let mut mainnet = HashMap :: new ( ) ;
313- mainnet. insert (
314- MainnetLidoModule :: Curated as u8 ,
315- address ! ( "55032650b14df07b85bF18A3a3eC8E0Af2e028d5" ) ,
316- ) ;
317- mainnet. insert (
318- MainnetLidoModule :: SimpleDVT as u8 ,
319- address ! ( "aE7B191A31f627b4eB1d4DaC64eaB9976995b433" ) ,
320- ) ;
321- mainnet. insert (
322- MainnetLidoModule :: CommunityStaking as u8 ,
323- address ! ( "dA7dE2ECdDfccC6c3AF10108Db212ACBBf9EA83F" ) ,
324- ) ;
325- map. insert ( Chain :: Mainnet , mainnet) ;
326-
327- // --- Holesky ---
328- let mut holesky = HashMap :: new ( ) ;
329- holesky. insert (
330- HoleskyLidoModule :: Curated as u8 ,
331- address ! ( "595F64Ddc3856a3b5Ff4f4CC1d1fb4B46cFd2bAC" ) ,
332- ) ;
333- holesky. insert (
334- HoleskyLidoModule :: SimpleDVT as u8 ,
335- address ! ( "11a93807078f8BB880c1BD0ee4C387537de4b4b6" ) ,
336- ) ;
337- holesky. insert (
338- HoleskyLidoModule :: Sandbox as u8 ,
339- address ! ( "D6C2ce3BB8bea2832496Ac8b5144819719f343AC" ) ,
340- ) ;
341- holesky. insert (
342- HoleskyLidoModule :: CommunityStaking as u8 ,
343- address ! ( "4562c3e63c2e586cD1651B958C22F88135aCAd4f" ) ,
344- ) ;
345- map. insert ( Chain :: Holesky , holesky) ;
346-
347- // --- Hoodi ---
348- let mut hoodi = HashMap :: new ( ) ;
349- hoodi. insert (
350- HoodiLidoModule :: Curated as u8 ,
351- address ! ( "5cDbE1590c083b5A2A64427fAA63A7cfDB91FbB5" ) ,
352- ) ;
353- hoodi. insert (
354- HoodiLidoModule :: SimpleDVT as u8 ,
355- address ! ( "0B5236BECA68004DB89434462DfC3BB074d2c830" ) ,
356- ) ;
357- hoodi. insert (
358- HoodiLidoModule :: Sandbox as u8 ,
359- address ! ( "682E94d2630846a503BDeE8b6810DF71C9806891" ) ,
360- ) ;
361- hoodi. insert (
362- HoodiLidoModule :: CommunityStaking as u8 ,
363- address ! ( "79CEf36D84743222f37765204Bec41E92a93E59d" ) ,
364- ) ;
365- map. insert ( Chain :: Hoodi , hoodi) ;
366-
367- // --- Sepolia --
368- let mut sepolia = HashMap :: new ( ) ;
369- sepolia. insert ( 1 , address ! ( "33d6E15047E8644F8DDf5CD05d202dfE587DA6E3" ) ) ;
370- map. insert ( Chain :: Sepolia , sepolia) ;
371-
372- map
373- }
374-
375- // Fetching appropiate registry address
376- fn lido_registry_address ( chain : Chain , lido_module_id : u8 ) -> eyre:: Result < Address > {
377- lido_registry_addresses_by_module ( )
378- . get ( & chain)
379- . ok_or_else ( || eyre:: eyre!( "Lido registry not supported for chain: {chain:?}" ) ) ?
380- . get ( & lido_module_id)
381- . copied ( )
382- . ok_or_else ( || {
383- eyre:: eyre!( "Lido module id {:?} not found for chain: {chain:?}" , lido_module_id)
384- } )
385- }
386-
387- fn is_csm_module ( chain : Chain , module_id : u8 ) -> bool {
388- match chain {
389- Chain :: Mainnet => module_id == MainnetLidoModule :: CommunityStaking as u8 ,
390- Chain :: Holesky => module_id == HoleskyLidoModule :: CommunityStaking as u8 ,
391- Chain :: Hoodi => module_id == HoodiLidoModule :: CommunityStaking as u8 ,
392- _ => false ,
393- }
394- }
395-
396- fn get_lido_csm_registry < P > (
397- registry_address : Address ,
398- provider : P ,
399- ) -> LidoCSMRegistry :: LidoCSMRegistryInstance < P >
400- where
401- P : Clone + Send + Sync + ' static + alloy:: providers:: Provider ,
402- {
403- LidoCSMRegistry :: new ( registry_address, provider)
404- }
405-
406- fn get_lido_module_registry < P > (
407- registry_address : Address ,
408- provider : P ,
409- ) -> LidoRegistry :: LidoRegistryInstance < P >
410- where
411- P : Clone + Send + Sync + ' static + alloy:: providers:: Provider ,
412- {
413- LidoRegistry :: new ( registry_address, provider)
414- }
415-
416- async fn fetch_lido_csm_keys_total < P > (
417- registry : & LidoCSMRegistry :: LidoCSMRegistryInstance < P > ,
418- node_operator_id : U256 ,
419- ) -> eyre:: Result < u64 >
420- where
421- P : Clone + Send + Sync + ' static + alloy:: providers:: Provider ,
422- {
423- let summary: getNodeOperatorSummaryReturn =
424- registry. getNodeOperatorSummary ( node_operator_id) . call ( ) . await ?;
425-
426- let total_u256 = summary. totalDepositedValidators + summary. depositableValidatorsCount ;
427-
428- let total_u64 = u64:: try_from ( total_u256)
429- . wrap_err_with ( || format ! ( "total keys ({total_u256}) does not fit into u64" ) ) ?;
430-
431- Ok ( total_u64)
432- }
433-
434- async fn fetch_lido_module_keys_total < P > (
435- registry : & LidoRegistry :: LidoRegistryInstance < P > ,
436- node_operator_id : U256 ,
437- ) -> eyre:: Result < u64 >
438- where
439- P : Clone + Send + Sync + ' static + alloy:: providers:: Provider ,
440- {
441- let total_keys: u64 =
442- registry. getTotalSigningKeyCount ( node_operator_id) . call ( ) . await ?. try_into ( ) ?;
443-
444- Ok ( total_keys)
445- }
446-
447- async fn fetch_lido_csm_keys_batch < P > (
448- registry : & LidoCSMRegistry :: LidoCSMRegistryInstance < P > ,
449- node_operator_id : U256 ,
450- offset : u64 ,
451- limit : u64 ,
452- ) -> eyre:: Result < Bytes >
453- where
454- P : Clone + Send + Sync + ' static + alloy:: providers:: Provider ,
455- {
456- let pubkeys = registry
457- . getSigningKeys ( node_operator_id, U256 :: from ( offset) , U256 :: from ( limit) )
458- . call ( )
459- . await ?;
460-
461- Ok ( pubkeys)
462- }
463-
464- async fn fetch_lido_module_keys_batch < P > (
465- registry : & LidoRegistry :: LidoRegistryInstance < P > ,
466- node_operator_id : U256 ,
467- offset : u64 ,
468- limit : u64 ,
469- ) -> eyre:: Result < Bytes >
470- where
471- P : Clone + Send + Sync + ' static + alloy:: providers:: Provider ,
472- {
473- let pubkeys = registry
474- . getSigningKeys ( node_operator_id, U256 :: from ( offset) , U256 :: from ( limit) )
475- . call ( )
476- . await ?
477- . pubkeys ;
478-
479- Ok ( pubkeys)
480- }
481-
482292async fn collect_registry_keys < F , Fut > (
483293 total_keys : u64 ,
484294 mut fetch_batch : F ,
@@ -634,80 +444,3 @@ async fn fetch_ssv_pubkeys(
634444
635445 Ok ( pubkeys)
636446}
637-
638- #[ cfg( test) ]
639- mod tests {
640- use alloy:: { primitives:: U256 , providers:: ProviderBuilder } ;
641- use url:: Url ;
642-
643- use super :: * ;
644-
645- #[ tokio:: test]
646- async fn test_lido_registry_address ( ) -> eyre:: Result < ( ) > {
647- let url = Url :: parse ( "https://ethereum-rpc.publicnode.com" ) ?;
648- let provider = ProviderBuilder :: new ( ) . connect_http ( url) ;
649-
650- let registry =
651- LidoRegistry :: new ( address ! ( "55032650b14df07b85bF18A3a3eC8E0Af2e028d5" ) , provider) ;
652-
653- const LIMIT : usize = 3 ;
654- let node_operator_id = U256 :: from ( 1 ) ;
655-
656- let total_keys: u64 =
657- registry. getTotalSigningKeyCount ( node_operator_id) . call ( ) . await ?. try_into ( ) ?;
658-
659- assert ! ( total_keys > LIMIT as u64 ) ;
660-
661- let pubkeys = registry
662- . getSigningKeys ( node_operator_id, U256 :: ZERO , U256 :: from ( LIMIT ) )
663- . call ( )
664- . await ?
665- . pubkeys ;
666-
667- let mut vec = vec ! [ ] ;
668- for chunk in pubkeys. chunks ( BLS_PUBLIC_KEY_BYTES_LEN ) {
669- vec. push (
670- BlsPublicKey :: deserialize ( chunk)
671- . map_err ( |_| eyre:: eyre!( "invalid BLS public key" ) ) ?,
672- ) ;
673- }
674-
675- assert_eq ! ( vec. len( ) , LIMIT ) ;
676-
677- Ok ( ( ) )
678- }
679-
680- #[ tokio:: test]
681- async fn test_lido_csm_registry_address ( ) -> eyre:: Result < ( ) > {
682- let url = Url :: parse ( "https://ethereum-rpc.publicnode.com" ) ?;
683- let provider = ProviderBuilder :: new ( ) . connect_http ( url) ;
684-
685- let registry =
686- LidoCSMRegistry :: new ( address ! ( "dA7dE2ECdDfccC6c3AF10108Db212ACBBf9EA83F" ) , provider) ;
687-
688- const LIMIT : usize = 3 ;
689- let node_operator_id = U256 :: from ( 1 ) ;
690-
691- let summary = registry. getNodeOperatorSummary ( node_operator_id) . call ( ) . await ?;
692-
693- let total_keys_u256 = summary. totalDepositedValidators + summary. depositableValidatorsCount ;
694- let total_keys: u64 = total_keys_u256. try_into ( ) ?;
695-
696- assert ! ( total_keys > LIMIT as u64 , "expected more than {LIMIT} keys, got {total_keys}" ) ;
697-
698- let pubkeys =
699- registry. getSigningKeys ( node_operator_id, U256 :: ZERO , U256 :: from ( LIMIT ) ) . call ( ) . await ?;
700-
701- let mut vec = Vec :: new ( ) ;
702- for chunk in pubkeys. chunks ( BLS_PUBLIC_KEY_BYTES_LEN ) {
703- vec. push (
704- BlsPublicKey :: deserialize ( chunk)
705- . map_err ( |_| eyre:: eyre!( "invalid BLS public key" ) ) ?,
706- ) ;
707- }
708-
709- assert_eq ! ( vec. len( ) , LIMIT , "expected {LIMIT} keys, got {}" , vec. len( ) ) ;
710-
711- Ok ( ( ) )
712- }
713- }
0 commit comments