Skip to content

Commit

Permalink
Compliance tests verification (Layr-Labs#103)
Browse files Browse the repository at this point in the history
Co-authored-by: tomasarrachea <[email protected]>
  • Loading branch information
pablodeymo and TomasArrachea committed Sep 12, 2024
1 parent dd8a745 commit 982758b
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 30 deletions.
6 changes: 6 additions & 0 deletions Cargo.lock

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

65 changes: 65 additions & 0 deletions crates/crypto/bls/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,50 @@ impl BlsG2Point {
}
}

impl Serialize for BlsG2Point {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut buffer = Vec::new();
self.g2().serialize_uncompressed(&mut buffer).unwrap();
serializer.serialize_bytes(&buffer)
}
}

impl<'de> Deserialize<'de> for BlsG2Point {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct BlsG2PointVisitor;

impl<'de> Visitor<'de> for BlsG2PointVisitor {
type Value = BlsG2Point;

fn expecting(&self, formatter: &mut ark_std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a byte array representing a G1Affine point")
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let mut buffer = Vec::new();

while let Some(value) = seq.next_element()? {
buffer.push(value);
}

let g2 = G2Affine::deserialize_uncompressed(&*buffer).map_err(de::Error::custom)?;
Ok(BlsG2Point { g2 })
}
}

deserializer.deserialize_seq(BlsG2PointVisitor)
}
}

/// Bls key pair with public key on G1
#[derive(Debug, Clone)]
pub struct BlsKeyPair {
Expand Down Expand Up @@ -616,4 +660,25 @@ mod tests {
"The deserialized point does not match the original"
);
}

#[test]
fn test_serialize_deserialize_bls_g2_point() {
let bls_priv_key =
"12248929636257230549931416853095037629726205319386239410403476017439825112537";
let bls_key_pair = BlsKeyPair::new(bls_priv_key.to_string()).unwrap();

let original_point = bls_key_pair.public_key_g2();
// Serialize the BlsG2Point to a JSON string
let serialized = serde_json::to_string(&original_point).expect("Failed to serialize");

// Deserialize the JSON string back to a BlsG2Point
let deserialized: BlsG2Point =
serde_json::from_str(&serialized).expect("Failed to deserialize");

// Check that the deserialized point matches the original
assert_eq!(
original_point, deserialized,
"The deserialized point does not match the original"
);
}
}
19 changes: 14 additions & 5 deletions crates/eigen-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,16 @@ mod test {
generate::{KeyGenerator, DEFAULT_KEY_FOLDER, PASSWORD_FILE, PRIVATE_KEY_HEX_FILE},
operator_id::derive_operator_id,
};
use alloy_primitives::Address;
use eigen_testing_utils::anvil_constants::{
get_registry_coordinator_address, get_service_manager_address, ANVIL_HTTP_URL,
};
use eigen_testing_utils::test_data::TestData;
use eth_keystore::decrypt_key;
use k256::SecretKey;
use rstest::rstest;
use rust_bls_bn254::keystores::base_keystore::Keystore;
use serde::Deserialize;
use std::fs;
use tempfile::tempdir;

Expand Down Expand Up @@ -270,10 +273,16 @@ mod test {
assert_eq!(private_key, decrypted_key);
}

#[tokio::test]
async fn test_egnaddrs_with_service_manager_flag() {
let service_manager_address = get_service_manager_address().await;
#[derive(Deserialize, Debug)]
struct Input {
service_manager_address: Address,
}

#[tokio::test]
async fn test_egn_addrs_with_service_manager_flag() {
let test_data = TestData::new(Input {
service_manager_address: get_service_manager_address().await,
});
let expected_addresses: ContractAddresses = serde_json::from_str(
r#"{
"avs": {
Expand All @@ -296,7 +305,7 @@ mod test {
)
.unwrap();
let addresses = ContractAddresses::get_addresses(
Some(service_manager_address),
Some(test_data.input.service_manager_address),
None,
ANVIL_HTTP_URL.into(),
)
Expand All @@ -307,7 +316,7 @@ mod test {
}

#[tokio::test]
async fn test_egnaddrs_with_registry_coordinator_flag() {
async fn test_egn_addrs_with_registry_coordinator_flag() {
let registry_coordinator_address = get_registry_coordinator_address().await;

let expected_addresses: ContractAddresses = serde_json::from_str(
Expand Down
2 changes: 2 additions & 0 deletions crates/services/avsregistry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,7 @@ eigen-types.workspace = true
eigen-utils.workspace = true

[dev-dependencies]
eigen-testing-utils.workspace = true
hex.workspace = true
tokio.workspace = true
serde.workspace = true
81 changes: 65 additions & 16 deletions crates/services/avsregistry/src/chaincaller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,24 +156,35 @@ mod tests {
use std::collections::HashMap;
use std::str::FromStr;

use crate::AvsRegistryService;

use super::AvsRegistryServiceChainCaller;
use crate::AvsRegistryService;
use alloy_primitives::{Address, FixedBytes, U256};
use eigen_client_avsregistry::fake_reader::FakeAvsRegistryReader;
use eigen_crypto_bls::BlsKeyPair;
use eigen_services_operatorsinfo::fake_operator_info::FakeOperatorInfoService;
use eigen_types::operator::{OperatorAvsState, OperatorInfo, OperatorPubKeys, QuorumAvsState};
use eigen_testing_utils::test_data::TestData;
use eigen_types::operator::{
OperatorAvsState, OperatorInfo, OperatorPubKeys, QuorumAvsState, QuorumNum,
};
use eigen_types::test::TestOperator;
use serde::Deserialize;

#[derive(Deserialize, Debug)]
struct InputOperatorInfo {
private_key_decimal: String,
operator_id: String,
operator_address: String,
}

const PRIVATE_KEY_DECIMAL: &str =
"13710126902690889134622698668747132666439281256983827313388062967626731803599";
const OPERATOR_ID: &str = "48beccce16ccdf8000c13d5af5f91c7c3dac6c47b339d993d229af1500dbe4a9";
const OPERATOR_ADDRESS: &str = "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720";
fn build_test_operator() -> TestOperator {
let bls_keypair = BlsKeyPair::new(PRIVATE_KEY_DECIMAL.into()).unwrap();

fn build_test_operator(private_key_decimal: &str, operator_id: &str) -> TestOperator {
let bls_keypair = BlsKeyPair::new(private_key_decimal.into()).unwrap();
let operator_id =
FixedBytes::<32>::from_slice(hex::decode(OPERATOR_ID).unwrap().as_slice());
FixedBytes::<32>::from_slice(hex::decode(operator_id).unwrap().as_slice());
TestOperator {
operator_id,
bls_keypair: bls_keypair.clone(),
Expand All @@ -183,19 +194,33 @@ mod tests {

fn build_avs_registry_service_chaincaller(
test_operator: TestOperator,
operator_address: &str,
) -> AvsRegistryServiceChainCaller<FakeAvsRegistryReader, FakeOperatorInfoService> {
let operator_address = Address::from_str(OPERATOR_ADDRESS).unwrap();
let operator_address = Address::from_str(operator_address).unwrap();
let avs_registry = FakeAvsRegistryReader::new(test_operator.clone(), operator_address);
let operator_info_service = FakeOperatorInfoService::new(test_operator.bls_keypair.clone());
AvsRegistryServiceChainCaller::new(avs_registry, operator_info_service)
}

#[tokio::test]
async fn test_get_operator_info() {
let test_operator = build_test_operator();
let default_input = InputOperatorInfo {
private_key_decimal: PRIVATE_KEY_DECIMAL.to_owned(),
operator_id: OPERATOR_ID.to_owned(),
operator_address: OPERATOR_ADDRESS.to_owned(),
};
let test_data: TestData<InputOperatorInfo> = TestData::new(default_input);

let test_operator = build_test_operator(
test_data.input.private_key_decimal.as_str(),
test_data.input.operator_id.as_str(),
);
let bls_keypair = test_operator.bls_keypair.clone();

let service = build_avs_registry_service_chaincaller(test_operator.clone());
let service = build_avs_registry_service_chaincaller(
test_operator.clone(),
test_data.input.operator_address.as_str(),
);
let operator_info = service
.get_operator_info(test_operator.operator_id.into())
.await
Expand All @@ -204,13 +229,36 @@ mod tests {
assert_eq!(expected_operator_info, Some(operator_info));
}

#[derive(Deserialize, Debug)]
struct Input {
quorum_numbers: Vec<QuorumNum>,
block_num: u32,
private_key_decimal: String, // TODO!!!! replace this in the JSON
operator_id: String, // TODO!!!! replace this in the JSON
}

#[tokio::test]
async fn test_get_operator_avs_state() {
let test_operator = build_test_operator();
let service = build_avs_registry_service_chaincaller(test_operator.clone());
async fn test_get_operators_avs_state() {
let default_input = Input {
quorum_numbers: vec![1],
block_num: 1,
private_key_decimal: PRIVATE_KEY_DECIMAL.to_owned(),
operator_id: OPERATOR_ID.to_owned(),
};
let test_data: TestData<Input> = TestData::new(default_input);

let test_operator = build_test_operator(
test_data.input.private_key_decimal.as_str(),
test_data.input.operator_id.as_str(),
);
let service =
build_avs_registry_service_chaincaller(test_operator.clone(), OPERATOR_ADDRESS);

let operator_avs_state = service
.get_operators_avs_state_at_block(1, &[1u8])
.get_operators_avs_state_at_block(
test_data.input.block_num,
&test_data.input.quorum_numbers,
)
.await
.unwrap();

Expand All @@ -220,18 +268,19 @@ mod tests {
pub_keys: Some(OperatorPubKeys::from(test_operator.bls_keypair)),
},
stake_per_quorum: test_operator.stake_per_quorum,
block_num: 1.into(),
block_num: test_data.input.block_num.into(),
};
let operator_state = operator_avs_state.get(&test_operator.operator_id).unwrap();
assert_eq!(expected_operator_avs_state, *operator_state);
}

#[tokio::test]
async fn test_get_quorum_avs_state() {
let test_operator = build_test_operator();
let test_operator = build_test_operator(PRIVATE_KEY_DECIMAL, OPERATOR_ID);
let quorum_num = 1;
let block_num = 1u32;
let service = build_avs_registry_service_chaincaller(test_operator.clone());
let service =
build_avs_registry_service_chaincaller(test_operator.clone(), OPERATOR_ADDRESS);
let quorum_state_per_number = service
.get_quorums_avs_state_at_block(&[quorum_num], 1)
.await
Expand Down
2 changes: 2 additions & 0 deletions crates/services/bls_aggregation/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ eigen-types.workspace = true
parking_lot.workspace = true
thiserror.workspace = true
tokio = { workspace = true, features = ["full"] }
serde_json.workspace = true
serde.workspace = true

[dev-dependencies]
alloy-node-bindings.workspace = true
Expand Down
3 changes: 2 additions & 1 deletion crates/services/bls_aggregation/src/bls_agg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use eigen_types::{
operator::{OperatorAvsState, QuorumThresholdPercentage, QuorumThresholdPercentages},
};
use parking_lot::RwLock;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Arc;
use thiserror::Error;
Expand All @@ -21,7 +22,7 @@ use tokio::sync::{
use tokio::time::{timeout, Duration};

#[allow(unused)]
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct BlsAggregationServiceResponse {
pub task_index: TaskIndex,
pub task_response_digest: TaskResponseDigest,
Expand Down
32 changes: 27 additions & 5 deletions crates/services/bls_aggregation/src/bls_agg_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,19 @@ pub mod integration_test {
get_erc20_mock_strategy, get_operator_state_retriever_address,
get_registry_coordinator_address, get_service_manager_address,
};
use eigen_types::{avs::TaskIndex, operator::QuorumThresholdPercentages};
use eigen_testing_utils::test_data::TestData;
use eigen_types::{
avs::TaskIndex,
operator::{QuorumNum, QuorumThresholdPercentages},
};
use eigen_utils::{
binding::{
IBLSSignatureChecker::{self, G1Point, NonSignerStakesAndSignature},
RegistryCoordinator::{self, OperatorSetParam, StrategyParams},
},
get_provider, get_signer,
};
use serde::Deserialize;
use serial_test::serial;
use sha2::{Digest, Sha256};
use std::{
Expand Down Expand Up @@ -85,18 +90,35 @@ pub mod integration_test {
.expect("Failed to execute command");
}

#[derive(Deserialize, Debug)]
struct Input {
bls_key: String,
quorum_numbers: Vec<QuorumNum>,
quorum_threshold_percentages: QuorumThresholdPercentages,
}

#[tokio::test]
#[serial]
async fn test_1_quorum_1_operator() {
async fn test_bls_agg() {
// test 1 quorum, 1 operator
// if TEST_DATA_PATH is set, load the test data from the json file
let default_input = Input {
bls_key: BLS_KEY_1.to_string(),
quorum_numbers: vec![0],
quorum_threshold_percentages: vec![100_u8],
};
let test_data: TestData<Input> = TestData::new(default_input);

let registry_coordinator_address = get_registry_coordinator_address().await;
let operator_state_retriever_address = get_operator_state_retriever_address().await;
let service_manager_address = get_service_manager_address().await;
let provider = get_provider(HTTP_ENDPOINT);
let salt: FixedBytes<32> = FixedBytes::from([0x02; 32]);
let quorum_nums = Bytes::from([0]);
let quorum_threshold_percentages: QuorumThresholdPercentages = vec![100];
let quorum_nums = Bytes::from(test_data.input.quorum_numbers);
let quorum_threshold_percentages: QuorumThresholdPercentages =
test_data.input.quorum_threshold_percentages;

let bls_key_pair = BlsKeyPair::new(BLS_KEY_1.to_string()).unwrap();
let bls_key_pair = BlsKeyPair::new(test_data.input.bls_key).unwrap();
let operator_id =
hex!("fd329fe7e54f459b9c104064efe0172db113a50b5f394949b4ef80b3c34ca7f5").into();

Expand Down
Loading

0 comments on commit 982758b

Please sign in to comment.