π We are happy to announce the v1.0 release of the Rust SDK. π
This comes with support for v1.3.1 of eigenlayer-middleware and the current EigenLayer Protocol mainnet deployment.
What's Changed
Added π
-
Bump alloy to 0.13 and MSRV to 1.81 in PR 419.
-
Added an additional implementation for
OperatorInfoService
for retrieving operator BLS pubkeys and sockets directly from middleware in #414. The newOperatorInfoOnChain
is more stable and efficient since it doesn't subscribe or fetch events, but it requires functionality from the recent v1.3.0 middleware release.Old Implementation which indexes middleware events:
use eigen_services_operatorsinfo::{operatorsinfo_inmemory::OperatorInfoServiceInMemory}; let operators_info = OperatorInfoServiceInMemory::new( get_test_logger(), avs_registry_reader.clone(), ws_endpoint, ) .await .unwrap() .0; let cancellation_token = CancellationToken::new(); let operators_info_clone = operators_info.clone(); let token_clone = cancellation_token.clone(); task::spawn(async move { operators_info_clone.start_service(&token_clone, start_block, end_block).await }); // Sleep to wait for the operator info service to start sleep(Duration::from_secs(1)).await; let avs_registry_service = AvsRegistryServiceChainCaller::new(avs_registry_reader.clone(), operators_info);
New alternate implementation which directly queries from middleware using view call:
use eigen_services_operatorsinfo::{operatorsinfo_inmemory::OperatorInfoOnChain}; let operators_info_on_chain = OperatorInfoOnChain::new( &http_endpoint, bls_apk_registry_address, socket_registry_address, ); let avs_registry_service = AvsRegistryServiceChainCaller::new( avs_registry_reader.clone(), operators_info_on_chain, ); let pub_keys = operator_info_on_chain .get_operator_info(OPERATOR_ADDRESS) .await .unwrap(); let socket = operator_info_on_chain .get_operator_socket(OPERATOR_ADDRESS) .await .unwrap();
-
Added a method
get_operator_socket
to retrieve the socket from theAvsRegistryServiceChainCaller
in PR 464.let socket = self.get_operator_socket(*operator.operatorId).await.unwrap();
Breaking Changes π
-
Changing NodeApi to allow concurrent modifications of the internal state of the node in PR 401.
Before:
NodeApi
had the functioncreate_server
to start the Node API. Now, there are two functionsNodeApi::new
andNodeApi::start_server
to create the server and then start it.Also, users can now call functions to modify the information served dynamically by interacting with the
NodeApi
methods. As an end-to-end example:let mut node_info = NodeInfo::new("test_node", "v1.0.0"); node_info.register_service( "test_service", "Test Service", "Test service description", ServiceStatus::Up, ); // Set up a server running on a test address (e.g., 127.0.0.1:8081) let ip_port_addr = "127.0.0.1:8081"; let mut node_api = NodeApi::new(node_info); let server = node_api.start_server(ip_port_addr).unwrap(); // and then you can dinamically modify the state of the node: node_api .update_service_status("test_service", ServiceStatus::Down) .unwrap();
-
Added field
socket
toOperatorInfo
in PR 464// BEFORE let info = self.get_operator_info(*operator.operatorId).await?; let stake_per_quorum = HashMap::new(); let avs_state = operators_avs_state .entry(FixedBytes(*operator.operatorId)) .or_insert_with(|| OperatorAvsState { operator_id: operator.operatorId, operator_info: OperatorInfo { pub_keys: Some(info), }, stake_per_quorum, block_num: block_num.into(), }); avs_state .stake_per_quorum .insert(*quorum_num, U256::from(operator.stake)); // AFTER // Now we use the new method to retrieve the socket in `get_operators_avs_state_at_block` // And use the value in the new field `socket` in `OperatorInfo` let socket = self.get_operator_socket(*operator.operatorId).await?; let info = self.get_operator_info(*operator.operatorId).await?; let stake_per_quorum = HashMap::new(); let avs_state = operators_avs_state .entry(FixedBytes(*operator.operatorId)) .or_insert_with(|| OperatorAvsState { operator_id: operator.operatorId, operator_info: OperatorInfo { pub_keys: Some(info), socket: Some(socket), }, stake_per_quorum, block_num: block_num.into(), }); avs_state .stake_per_quorum .insert(*quorum_num, U256::from(operator.stake));
Documentation π
-
Added documentation for service crates:
- docs: avs registry service by @damiramirez in #409
- docs: operator info service by @damiramirez in #406
- docs: BLS Aggregator Service by @damiramirez in #387
-
Improved documentation compiling on docs.rs
- chore: apply cargo doc metadata to crates by @damiramirez in #441
- docs: fix doc warnings by @MegaRedHand in #438
- docs: inline
eigensdk
documentation by @MegaRedHand in #439
Other Changes
-
Moved test utils from chainio folder to testing/testutils folder by @maximopalopoli in #407
-
Added rewards utilities integration test by @maximopalopoli in #404
-
test: check quorum creation after service initialization is working by @MegaRedHand in #400
-
chore: use common testing utils in bls_agg_test in PR #420.
-
chore: remove unused dependency in
eigen-cli
by @MegaRedHand in #421 -
test: wait for transaction before doing call by @MegaRedHand in #422
-
chore: merge changes from main branch by @MegaRedHand in #446
-
Fixed release workflow. We now use release-plz for releases.
- ci: add workflow_dispatch for release-plz by @MegaRedHand in #448
- fix: ignore integration tests crate when publishing by @MegaRedHand in #449
- fix: use path-only dependency for testing utils by @MegaRedHand in #450
Full Changelog: v0.5.0...v1.0.0