Skip to content

v1.0.0 - mainnet slashing

Latest
Compare
Choose a tag to compare
@github-actions github-actions released this 20 Jun 16:52
· 129 commits to dev since this release
27a77ac

πŸŽ‰ 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.

  • Bump middleware to v1.3.1 in PR 488 and 443.

  • Added an additional implementation for OperatorInfoService for retrieving operator BLS pubkeys and sockets directly from middleware in #414. The new OperatorInfoOnChain 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 the AvsRegistryServiceChainCaller 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 function create_server to start the Node API. Now, there are two functions NodeApi::new and NodeApi::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 to OperatorInfo 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 πŸ“š

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.

Full Changelog: v0.5.0...v1.0.0