Skip to content

feat: register challenger #156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
CHALLENGER_PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
OPERATOR_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
OPERATOR_RESPONSE_PERCENTAGE=80
RPC_URL=http://localhost:8545
WS_URL=ws://localhost:8545
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 14 additions & 8 deletions operator/rust/crates/operator/src/challenger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use hello_world_utils::{
HelloWorldServiceManager::{self},
IHelloWorldServiceManager::Task,
},
register_operator,
};
use tokio::signal::{self};

Expand All @@ -31,8 +32,12 @@ static RPC_URL: LazyLock<String> =
static WS_URL: LazyLock<String> =
LazyLock::new(|| env::var("WS_URL").expect("failed to retrieve WS URL"));

static KEY: LazyLock<String> =
LazyLock::new(|| env::var("PRIVATE_KEY").expect("failed to retrieve private key"));
static CHALLENGER_PRIVATE_KEY: LazyLock<String> =
LazyLock::new(|| env::var("CHALLENGER_PRIVATE_KEY").expect("failed to retrieve private key"));

static OPERATOR_PRIVATE_KEY: LazyLock<String> = LazyLock::new(|| {
env::var("OPERATOR_PRIVATE_KEY").expect("failed to retrieve operator private key")
});

/// Challenger struct
#[derive(Debug)]
Expand All @@ -48,10 +53,7 @@ pub struct Challenger {
/// Challenger implementation
impl Challenger {
/// Create a new challenger
pub async fn new(rpc_url: String, ws_url: String, private_key: String) -> Result<Self> {
let signer = PrivateKeySigner::from_str(&private_key)?;
let operator_address = signer.address();

pub async fn new(rpc_url: String, ws_url: String) -> Result<Self> {
let service_manager_address = get_hello_world_service_manager().unwrap();

let pr = get_provider(&rpc_url);
Expand All @@ -62,6 +64,8 @@ impl Challenger {
.await?
._0;

let operator_address = PrivateKeySigner::from_str(&OPERATOR_PRIVATE_KEY)?.address();

Ok(Self {
service_manager_address,
rpc_url,
Expand Down Expand Up @@ -178,7 +182,7 @@ impl Challenger {

/// Execute the slashing of an operator
async fn slash_operator(&self, task: Task, task_index: u32) -> Result<()> {
let pr = get_signer(&KEY.to_string(), &self.rpc_url);
let pr = get_signer(&CHALLENGER_PRIVATE_KEY.to_string(), &self.rpc_url);
let hello_world_contract = HelloWorldServiceManager::new(self.service_manager_address, &pr);

get_logger().info(
Expand Down Expand Up @@ -208,7 +212,9 @@ pub async fn main() -> Result<()> {
dotenv().ok();
init_logger(LogLevel::Info);

let mut challenger = Challenger::new(RPC_URL.to_string(), WS_URL.to_string(), KEY.to_string())
register_operator(&RPC_URL, &CHALLENGER_PRIVATE_KEY).await?;

let mut challenger = Challenger::new(RPC_URL.to_string(), WS_URL.to_string())
.await
.unwrap();

Expand Down
4 changes: 2 additions & 2 deletions operator/rust/crates/operator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ pub mod anvil;
mod tests {
use crate::anvil::start_anvil_container;
use crate::spam_tasks::create_new_task;
use crate::start_operator::register_operator;

use alloy::network::EthereumWallet;
use alloy::primitives::Address;
Expand All @@ -31,6 +30,7 @@ mod tests {
};
use hello_world_utils::{
get_anvil_eigenlayer_deployment_data, get_anvil_hello_world_deployment_data,
register_operator,
};
use reqwest::Url;
use serial_test::serial;
Expand All @@ -39,7 +39,7 @@ mod tests {
use std::sync::LazyLock;

static KEY: LazyLock<String> =
LazyLock::new(|| env::var("PRIVATE_KEY").expect("failed to retrieve private key"));
LazyLock::new(|| env::var("OPERATOR_PRIVATE_KEY").expect("failed to retrieve private key"));

#[tokio::test]
#[serial]
Expand Down
2 changes: 1 addition & 1 deletion operator/rust/crates/operator/src/spam_tasks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ static RPC_URL: LazyLock<String> =
LazyLock::new(|| env::var("RPC_URL").expect("failed to retrieve RPC URL"));

static KEY: LazyLock<String> =
LazyLock::new(|| env::var("PRIVATE_KEY").expect("failed to retrieve private key"));
LazyLock::new(|| env::var("OPERATOR_PRIVATE_KEY").expect("failed to retrieve private key"));

/// Generate random task names from the given adjectives and nouns
fn generate_random_name() -> String {
Expand Down
126 changes: 6 additions & 120 deletions operator/rust/crates/operator/src/start_operator.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,22 @@
#![allow(missing_docs)]
use alloy::dyn_abi::DynSolValue;
use alloy::{
primitives::{eip191_hash_message, keccak256, Address, FixedBytes, U256},
primitives::{eip191_hash_message, keccak256, Address, U256},
providers::Provider,
rpc::types::{BlockNumberOrTag, Filter},
signers::{local::PrivateKeySigner, SignerSync},
sol_types::{SolEvent, SolValue},
};
use chrono::Utc;
use dotenv::dotenv;
use eigensdk::client_elcontracts::{
reader::ELChainReader,
writer::{ELChainWriter, Operator},
};
use eigensdk::common::{get_provider, get_signer, get_ws_provider};
use eigensdk::logging::{get_logger, init_logger, log_level::LogLevel};
use eyre::Result;
use futures::StreamExt;
use hello_world_utils::ecdsastakeregistry::ECDSAStakeRegistry;
use hello_world_utils::{
ecdsastakeregistry::ISignatureUtilsMixinTypes::SignatureWithSaltAndExpiry,
helloworldservicemanager::{HelloWorldServiceManager, IHelloWorldServiceManager::Task},
};
use hello_world_utils::{
get_anvil_eigenlayer_deployment_data, get_hello_world_service_manager,
get_stake_registry_address,
use hello_world_utils::helloworldservicemanager::{
HelloWorldServiceManager, IHelloWorldServiceManager::Task,
};
use rand::{Rng, TryRngCore};
use hello_world_utils::{get_hello_world_service_manager, register_operator};
use rand::Rng;
use std::sync::LazyLock;
use std::{env, str::FromStr};

Expand All @@ -37,7 +27,7 @@ static WS_URL: LazyLock<String> =
LazyLock::new(|| env::var("WS_URL").expect("failed to retrieve WS URL"));

static KEY: LazyLock<String> =
LazyLock::new(|| env::var("PRIVATE_KEY").expect("failed to retrieve private key"));
LazyLock::new(|| env::var("OPERATOR_PRIVATE_KEY").expect("failed to retrieve private key"));

static OPERATOR_RESPONSE_PERCENTAGE: LazyLock<f64> = LazyLock::new(|| {
env::var("OPERATOR_RESPONSE_PERCENTAGE")
Expand Down Expand Up @@ -208,110 +198,6 @@ async fn monitor_new_tasks_polling(rpc_url: &str, private_key: &str) -> Result<(
}
}

pub async fn register_operator(rpc_url: &str, private_key: &str) -> Result<()> {
let pr = get_signer(private_key, rpc_url);
let signer = PrivateKeySigner::from_str(private_key)?;

let el_data = get_anvil_eigenlayer_deployment_data()?;
let delegation_manager_address: Address = el_data.addresses.delegation_manager.parse()?;
let avs_directory_address: Address = el_data.addresses.avs_directory.parse()?;

let elcontracts_reader_instance = ELChainReader::new(
get_logger().clone(),
None,
delegation_manager_address,
Address::ZERO,
avs_directory_address,
None,
rpc_url.to_string(),
);
let elcontracts_writer_instance = ELChainWriter::new(
Address::ZERO,
Address::ZERO,
None,
None,
Address::ZERO,
elcontracts_reader_instance.clone(),
rpc_url.to_string(),
private_key.to_string(),
);

let operator = Operator {
address: signer.address(),
delegation_approver_address: Address::ZERO,
staker_opt_out_window_blocks: Some(0),
metadata_url: Default::default(),
allocation_delay: Some(0),
_deprecated_earnings_receiver_address: None,
};

let is_registered = elcontracts_reader_instance
.is_operator_registered(signer.address())
.await
.unwrap();
get_logger().info(&format!("is registered {}", is_registered), "");
let tx_hash = elcontracts_writer_instance
.register_as_operator(operator)
.await?;
let receipt = pr.get_transaction_receipt(tx_hash).await?;
if !receipt.is_some_and(|r| r.inner.is_success()) {
get_logger().error("Operator registration failed", "");
return Err(eyre::eyre!("Operator registration failed"));
}
get_logger().info(
&format!(
"Operator registered on EL successfully tx_hash {:?}",
tx_hash
),
"",
);
let mut salt = [0u8; 32];
rand::rngs::OsRng.try_fill_bytes(&mut salt).unwrap();

let salt = FixedBytes::from_slice(&salt);
let now = Utc::now().timestamp();
let expiry: U256 = U256::from(now + 3600);

let hello_world_contract_address: Address = get_hello_world_service_manager()?;
let digest_hash = elcontracts_reader_instance
.calculate_operator_avs_registration_digest_hash(
signer.address(),
hello_world_contract_address,
salt,
expiry,
)
.await?;

let signature = signer.sign_hash_sync(&digest_hash)?;
let operator_signature = SignatureWithSaltAndExpiry {
signature: signature.as_bytes().into(),
salt,
expiry,
};
let stake_registry_address = get_stake_registry_address()?;
let contract_ecdsa_stake_registry = ECDSAStakeRegistry::new(stake_registry_address, &pr);
let registeroperator_details_call = contract_ecdsa_stake_registry
.registerOperatorWithSignature(operator_signature, signer.clone().address())
.gas(500000);
let register_hello_world_hash = registeroperator_details_call
.send()
.await?
.get_receipt()
.await?
.transaction_hash;

get_logger().info(
&format!(
"Operator registered on AVS successfully :{} , tx_hash :{}",
signer.address(),
register_hello_world_hash
),
"",
);

Ok(())
}

#[tokio::main]
pub async fn main() {
use tokio::signal;
Expand Down
3 changes: 3 additions & 0 deletions operator/rust/crates/utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ license-file.workspace = true

[dependencies]
alloy.workspace = true
eigensdk.workspace = true
serde.workspace = true
serde_json = "1.0.121"
eyre = "0.6.12"
rand = "0.9"
chrono = "0.4.38"
Loading
Loading