Skip to content

Commit

Permalink
BLS-aggregation integration tests (#91)
Browse files Browse the repository at this point in the history
Implemented integration tests for `bls_aggregation` crate.
Added 5 tests:

- 2 quorums 1 operator (ignored)
- 2 quorums 2 operators shared (ignored)
- 1 quorum 1 operator
- 1 quorum 2 operators 
- 2 quorums 2 operators separated

Two cases are ignored as they are failing due to this bug: [bls
aggregation service doesn't support >1
quorum](Layr-Labs/eigensdk-go#261)

---------

Co-authored-by: supernovahs <[email protected]>
Co-authored-by: Supernovahs.eth <[email protected]>
Co-authored-by: Pablo Deymonnaz <[email protected]>
Co-authored-by: ricomateo <[email protected]>
  • Loading branch information
5 people authored Aug 30, 2024
1 parent 31e2333 commit 410b53a
Show file tree
Hide file tree
Showing 8 changed files with 1,085 additions and 69 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.

11 changes: 5 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ __CONTRACTS__: ##
start-anvil-chain-with-contracts-deployed: ##
./crates/contracts/anvil/start-anvil-chain-with-el-and-avs-deployed.sh

deploy-contracts-to-anvil-and-save-state: ##
deploy-contracts-to-anvil-and-save-state: ##
./crates/contracts/anvil/deploy-contracts-save-anvil-state.sh

__TESTING__: ##
Expand All @@ -14,17 +14,16 @@ reset-anvil:
-docker stop anvil
-docker rm anvil

pr: reset-anvil ##
$(MAKE) start-anvil-chain-with-contracts-deployed
docker start anvil
pr: reset-anvil ##
$(MAKE) start-anvil-chain-with-contracts-deployed > /dev/null &
sleep 4 # needed to wait for anvil setup to finish
cargo test --workspace
cargo clippy --workspace --lib --examples --tests --benches --all-features
cargo +nightly fmt -- --check
docker stop anvil

fireblocks-tests:
$(MAKE) start-anvil-chain-with-contracts-deployed
docker start anvil
$(MAKE) start-anvil-chain-with-contracts-deployed > /dev/null &
cargo test --workspace --features fireblock-tests

start-anvil: reset-anvil ##
Expand Down
2 changes: 1 addition & 1 deletion crates/chainio/clients/avsregistry/src/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ impl AvsRegistryChainWriter {
.await
.map_err(AvsRegistryError::AlloyContractError)?;

info!(tx_hash = ?tx,"Succesfully deregistered operator with the AVS's registry coordinator" );
info!(tx_hash = ?tx,"Sent transaction to deregister operator in the AVS's registry coordinator" );
Ok(*tx.tx_hash())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ cd ../../contracts
cast rpc anvil_mine 200 --rpc-url http://localhost:8545 > /dev/null
echo "Anvil is ready. Advanced chain to block-number:" $(cast block-number)

docker attach anvil
145 changes: 95 additions & 50 deletions crates/crypto/bls/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ use ark_ec::{AffineRepr, CurveGroup};
use ark_ff::{fields::PrimeField, BigInt, BigInteger256, Fp2};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use eigen_crypto_bn254::utils::map_to_curve;
use eigen_utils::binding::IBLSSignatureChecker::{
G1Point as G1PointChecker, G2Point as G2PointChecker,
};
use eigen_utils::binding::{
BLSApkRegistry,
RegistryCoordinator::{self},
Expand Down Expand Up @@ -113,17 +116,12 @@ pub struct BlsKeyPair {
impl BlsKeyPair {
/// Input [`Fr`] as a [`String`]
pub fn new(fr: String) -> Result<Self, BlsError> {
let sk_result = Fr::from_str(&fr);
match sk_result {
Ok(sk) => {
let pk = G1Projective::from(G1Affine::generator()) * sk;
Ok(Self {
priv_key: sk,
pub_key: BlsG1Point::new(pk.into_affine()),
})
}
Err(_) => Err(BlsError::InvalidBlsPrivateKey),
}
let sk = Fr::from_str(&fr).map_err(|_| BlsError::InvalidBlsPrivateKey)?;
let pk = G1Projective::from(G1Affine::generator()) * sk;
Ok(Self {
priv_key: sk,
pub_key: BlsG1Point::new(pk.into_affine()),
})
}

/// Get public key on G1
Expand Down Expand Up @@ -165,20 +163,69 @@ pub fn convert_to_g1_point(g1: G1Affine) -> Result<G1Point, BlsError> {
let x_point_result = g1.x();
let y_point_result = g1.y();

if let (Some(x_point), Some(y_point)) = (x_point_result, y_point_result) {
let x = BigInt::new(x_point.into_bigint().0);
let y = BigInt::new(y_point.into_bigint().0);
let (Some(x_point), Some(y_point)) = (x_point_result, y_point_result) else {
return Err(BlsError::InvalidG1Affine);
};

let x_u256 = U256::from_limbs(x.0);
let y_u256 = U256::from_limbs(y.0);
let x = BigInt::new(x_point.into_bigint().0);
let y = BigInt::new(y_point.into_bigint().0);

Ok(G1Point {
X: x_u256,
Y: y_u256,
})
} else {
Err(BlsError::InvalidG1Affine)
}
let x_u256 = U256::from_limbs(x.0);
let y_u256 = U256::from_limbs(y.0);

Ok(G1Point {
X: x_u256,
Y: y_u256,
})
}

/// Convert [`G1Affine`] to Alloy [`G1PointChecker`]
pub fn convert_to_bls_checker_g1_point(g1: G1Affine) -> Result<G1PointChecker, BlsError> {
let x_point_result = g1.x();
let y_point_result = g1.y();

let (Some(x_point), Some(y_point)) = (x_point_result, y_point_result) else {
return Err(BlsError::InvalidG1Affine);
};
let x = BigInt::new(x_point.into_bigint().0);
let y = BigInt::new(y_point.into_bigint().0);

let x_u256 = U256::from_limbs(x.0);
let y_u256 = U256::from_limbs(y.0);

Ok(G1PointChecker {
X: x_u256,
Y: y_u256,
})
}

/// Convert [`G2Affine`] to Alloy [`G2PointChecker`]
pub fn convert_to_bls_checker_g2_point(g2: G2Affine) -> Result<G2PointChecker, BlsError> {
let x_point_result = g2.x();
let y_point_result = g2.y();

let (Some(x_point), Some(y_point)) = (x_point_result, y_point_result) else {
return Err(BlsError::InvalidG2Affine);
};
let x_point_c0 = x_point.c0;
let x_point_c1 = x_point.c1;
let y_point_c0 = y_point.c0;
let y_point_c1 = y_point.c1;

let x_0 = BigInt::new(x_point_c0.into_bigint().0);
let x_1 = BigInt::new(x_point_c1.into_bigint().0);
let y_0 = BigInt::new(y_point_c0.into_bigint().0);
let y_1 = BigInt::new(y_point_c1.into_bigint().0);

let x_u256_0 = U256::from_limbs(x_0.0);
let x_u256_1 = U256::from_limbs(x_1.0);
let y_u256_0 = U256::from_limbs(y_0.0);
let y_u256_1 = U256::from_limbs(y_1.0);

Ok(G2PointChecker {
X: [x_u256_1, x_u256_0],
Y: [y_u256_1, y_u256_0],
})
}

/// Convert [`G2Affine`] to [`G2Point`]
Expand All @@ -189,32 +236,31 @@ pub fn convert_to_g2_point(g2: G2Affine) -> Result<G2Point, BlsError> {
let y_point_result = g2.y();
// let y_point_c1 = g2.y().unwrap().c1;

if let (Some(x_point), Some(y_point)) = (x_point_result, y_point_result) {
let x_point_c0 = x_point.c0;
let x_point_c1 = x_point.c1;
let y_point_c0 = y_point.c0;
let y_point_c1 = y_point.c1;

let x_0 = BigInt::new(x_point_c0.into_bigint().0);
let x_1 = BigInt::new(x_point_c1.into_bigint().0);
let y_0 = BigInt::new(y_point_c0.into_bigint().0);
let y_1 = BigInt::new(y_point_c1.into_bigint().0);

let x_u256_0 = U256::from_limbs(x_0.0);
let x_u256_1 = U256::from_limbs(x_1.0);
let y_u256_0 = U256::from_limbs(y_0.0);
let y_u256_1 = U256::from_limbs(y_1.0);

Ok(G2Point {
X: [x_u256_1, x_u256_0],
Y: [y_u256_1, y_u256_0],
})
} else {
Err(BlsError::InvalidG2Affine)
}
let (Some(x_point), Some(y_point)) = (x_point_result, y_point_result) else {
return Err(BlsError::InvalidG2Affine);
};
let x_point_c0 = x_point.c0;
let x_point_c1 = x_point.c1;
let y_point_c0 = y_point.c0;
let y_point_c1 = y_point.c1;

let x_0 = BigInt::new(x_point_c0.into_bigint().0);
let x_1 = BigInt::new(x_point_c1.into_bigint().0);
let y_0 = BigInt::new(y_point_c0.into_bigint().0);
let y_1 = BigInt::new(y_point_c1.into_bigint().0);

let x_u256_0 = U256::from_limbs(x_0.0);
let x_u256_1 = U256::from_limbs(x_1.0);
let y_u256_0 = U256::from_limbs(y_0.0);
let y_u256_1 = U256::from_limbs(y_1.0);

Ok(G2Point {
X: [x_u256_1, x_u256_0],
Y: [y_u256_1, y_u256_0],
})
}

/// Convert [`G1Point`] to [`G1Affine`]
/// Convert [`G1PointRegistry`] to [`G1Affine`]
pub fn alloy_registry_g1_point_to_g1_affine(g1_point: G1PointRegistry) -> G1Affine {
let x_point = g1_point.X.into_limbs();
let x = Fq::new(BigInteger256::new(x_point));
Expand All @@ -223,7 +269,7 @@ pub fn alloy_registry_g1_point_to_g1_affine(g1_point: G1PointRegistry) -> G1Affi
G1Affine::new(x, y)
}

/// Convert [`G1Point`] to [`G1Affine`]
/// Convert [`G2PointRegistry`] to [`G2Affine`]
pub fn alloy_registry_g2_point_to_g2_affine(g2_point: G2PointRegistry) -> G2Affine {
let x_fp2 = Fp2::new(
BigInteger256::new(g2_point.X[1].into_limbs()).into(),
Expand All @@ -236,7 +282,7 @@ pub fn alloy_registry_g2_point_to_g2_affine(g2_point: G2PointRegistry) -> G2Affi
G2Affine::new(x_fp2, y_fp2)
}

/// Convert [`G2Affine`] to [`G2Point`]
/// Convert [`G2Affine`] to [`G2PointRegistry`]
pub fn convert_to_registry_g2_point(g2: G2Affine) -> Result<G2PointRegistry, BlsError> {
let x_point_result = g2.x();
let y_point_result = g2.y();
Expand Down Expand Up @@ -286,7 +332,6 @@ impl Signature {

#[cfg(test)]
mod tests {

use super::*;
use ark_bn254::Fq2;
use eigen_crypto_bn254::utils::verify_message;
Expand Down
7 changes: 6 additions & 1 deletion crates/services/avsregistry/src/chaincaller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,12 @@ impl<R: AvsRegistryReader + Sync, S: OperatorInfoService + Sync> AvsRegistryServ
let mut pub_key_g1 = G1Projective::from(PublicKey::identity());
let mut total_stake: U256 = U256::from(0);
for operator in operators_avs_state.values() {
if !operator.stake_per_quorum[quorum_num].is_zero() {
if !operator
.stake_per_quorum
.get(quorum_num)
.unwrap_or(&U256::ZERO)
.is_zero()
{
if let Some(pub_keys) = &operator.operator_info.pub_keys {
pub_key_g1 += pub_keys.g1_pub_key.g1();
total_stake += operator.stake_per_quorum[quorum_num];
Expand Down
6 changes: 6 additions & 0 deletions crates/services/bls_aggregation/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,11 @@ tokio = { workspace = true, features = ["full"] }

[dev-dependencies]
alloy-node-bindings.workspace = true
alloy-provider.workspace = true
eigen-logging.workspace = true
eigen-testing-utils.workspace = true
eigen-utils.workspace = true
eigen-services-operatorsinfo.workspace = true
serial_test = "3.1"
sha2 = "0.10.8"
tokio-util = "0.7.11"
Loading

0 comments on commit 410b53a

Please sign in to comment.