Skip to content
This repository has been archived by the owner on Nov 23, 2023. It is now read-only.

Commit

Permalink
fix(lib): scores calculation (#352)
Browse files Browse the repository at this point in the history
  • Loading branch information
brech1 authored Sep 11, 2023
1 parent 1cab80b commit 0cdc001
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 57 deletions.
2 changes: 1 addition & 1 deletion eigentrust-cli/assets/attestations.csv
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
about,domain,value,message,sig_r,sig_s,rec_id
0x70997970c51812dc3a010c7d01b50e0d17dc7668,0x0000000000000000000000000000000000000000,8,0x0000000000000000000000000000000000000000000000000000000000000000,0x274c5c01d85bbc9bf69f498d08ecca54f692ba2111910c35fb68e89f6a6de2a1,0x06215a213b4bf6a5b9608a7ac23d7f01e0a6e29b088df7d5a50ebd8d2896d03a,0
0x70997970c51812dc3a010c7d01b50e0d17dc79c8,0x0000000000000000000000000000000000000000,5,0x0000000000000000000000000000000000000000000000000000000000000000,0x1cc60bf64279111e233842283422f63cc34235adb4622a905aa325b6c8c44c4f,0xefa0e00156ab25f681075542d005f82e4b53ecdedee9d776268c0d7e7f325a21,1
4 changes: 1 addition & 3 deletions eigentrust-cli/assets/scores.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
peer_address,score_fr,numerator,denominator,score
0x70997970c51812dc3a010c7d01b50e0d17dc7666,0x268ac16f8598e86f93c3c0323f9d890b116e644167ea4b476dcc06209c0f274a,55358500,59049,937
0x70997970c51812dc3a010c7d01b50e0d17dc7667,0x28aef48fc67971ad01291f460e61d68e24b76dd4fe8a94b62dec5ac09d96966f,59787100,59049,1012
0x70997970c51812dc3a010c7d01b50e0d17dc7668,0x118ee6e67650e636dbb3abf4b50351211a41fe7a8cfe0124ec0b8a46a65a4e01,62001400,59049,1049
0x70997970c51812dc3a010c7d01b50e0d17dc79c8,0x00000000000000000000000000000000000000000000000000000000000003e8,1000,1,1000
0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266,0x00000000000000000000000000000000000000000000000000000000000003e8,1000,1,1000
36 changes: 29 additions & 7 deletions eigentrust-zk/src/circuits/dynamic_sets/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::{
FieldExt, Hasher, SpongeHasher,
};
use halo2::halo2curves::CurveAffine;
use itertools::Itertools;
use num_bigint::{BigInt, ToBigInt};
use num_rational::BigRational;
use num_traits::{FromPrimitive, One, Zero};
Expand Down Expand Up @@ -51,6 +50,14 @@ where

Self { attestation, signature }
}

/// Constructs a new empty attestation with about
pub fn empty_with_about(about: N, domain: N) -> Self {
let attestation = Attestation::<N> { about, domain, ..Default::default() };
let signature = Signature { r: Integer::one(), s: Integer::one(), ..Default::default() };

Self { attestation, signature }
}
}

impl<C: CurveAffine, N: FieldExt, const NUM_LIMBS: usize, const NUM_BITS: usize, P> Default
Expand Down Expand Up @@ -195,13 +202,28 @@ impl<
&mut self, from: PublicKey<C, N, NUM_LIMBS, NUM_BITS, P, EC>,
op: Vec<Option<SignedAttestation<C, N, NUM_LIMBS, NUM_BITS, P>>>,
) -> N {
let empty_att = SignedAttestation::empty(self.domain);
let op_unwrapped = op.iter().map(|x| x.clone().unwrap_or(empty_att.clone())).collect_vec();
let op = Opinion::<NUM_NEIGHBOURS, C, N, NUM_LIMBS, NUM_BITS, P, EC, H, SH>::new(
from, op_unwrapped, self.domain,
// Get participant set addresses
let set: Vec<N> = self.set.iter().map(|&(addr, _)| addr).collect();

// Build the opinion group by unwrapping attestations and filling the empty ones with default values.
// Enumerating to keep track of the participant this opinion is about.
let opinion_group = op
.into_iter()
.enumerate()
.map(|(index, attestation)| {
attestation.unwrap_or_else(|| {
SignedAttestation::<C, N, NUM_LIMBS, NUM_BITS, P>::empty_with_about(
set[index], self.domain,
)
})
})
.collect();

// Build opinion from the opinion group and validate
let opinion = Opinion::<NUM_NEIGHBOURS, C, N, NUM_LIMBS, NUM_BITS, P, EC, H, SH>::new(
from, opinion_group, self.domain,
);
let set = self.set.iter().map(|&(addr, _)| addr).collect();
let (addr, scores, op_hash) = op.validate(set);
let (addr, scores, op_hash) = opinion.validate(set);

self.ops.insert(addr, scores);

Expand Down
18 changes: 9 additions & 9 deletions eigentrust-zk/src/ecdsa/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,18 @@ where
let rev_y: Vec<u8> = y.iter().rev().cloned().collect();
let pub_key = [rev_x, rev_y].concat();

// Hash and get first 20 bytes.
let hashed_public_key = Keccak256::digest(&pub_key);
let address_slice = &Keccak256::digest(&pub_key)[hashed_public_key.len() - 20..];
// Hash and get the last 20 bytes.
let pub_key_hash = Keccak256::digest(pub_key);
let address: &[u8] = &pub_key_hash[pub_key_hash.len() - 20..];

// Build fixed-size array.
let mut address = [0u8; 32];
address[..20].copy_from_slice(address_slice);
// Get little endian address
let le_address: Vec<u8> = address.iter().rev().cloned().collect();

let mut address_bytes = <N as PrimeField>::Repr::default();
address.as_ref().read_exact(address_bytes.as_mut()).unwrap();
// Build fixed-size array.
let mut address = [0u8; 64];
address[..20].copy_from_slice(&le_address);

N::from_repr(address_bytes).unwrap()
N::from_uniform_bytes(&address)
}
}

Expand Down
10 changes: 7 additions & 3 deletions eigentrust/src/attestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -646,9 +646,13 @@ mod tests {

let signed_attestation = SignedAttestationEth::new(attestation_eth, signature_eth);

// Replace with expected address
let expected_address_bytes = keypair.public_key.to_address().to_bytes();
let expected_address = Address::from_slice(&expected_address_bytes[..20]);
// Create expected address
let le_address = keypair.public_key.to_address().to_bytes();
let mut expected_address_bytes: [u8; 20] = [0; 20];
expected_address_bytes.copy_from_slice(&le_address[0..20]);
expected_address_bytes.reverse();

let expected_address = Address::from(expected_address_bytes);

let public_key = signed_attestation.recover_public_key().unwrap();
let address = address_from_ecdsa_key(&public_key);
Expand Down
21 changes: 11 additions & 10 deletions eigentrust/src/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,9 @@ pub fn ecdsa_keypairs_from_mnemonic(

/// Constructs an Ethereum address for the given ECDSA public key.
pub fn address_from_ecdsa_key(pub_key: &ECDSAPublicKey) -> Address {
let address: Vec<u8> = pub_key.to_address().to_bytes().to_vec();

let mut address_array = [0; 20];
address_array.copy_from_slice(&address[0..20]);

Address::from(address_array)
let mut address_bytes = pub_key.to_address().to_bytes();
address_bytes[..20].reverse();
Address::from_slice(&address_bytes[0..20])
}

/// Constructs a Scalar from the given Ethereum address.
Expand Down Expand Up @@ -134,12 +131,16 @@ mod tests {
hex::decode(address_str).expect("Decoding failed").try_into().expect("Wrong length");

let keypairs = ecdsa_keypairs_from_mnemonic(TEST_MNEMONIC, 1).unwrap();
let recovered_address = keypairs[0].public_key.to_address().to_bytes().to_vec();

let mut recovered_address_bytes: [u8; 20] = [0; 20];
recovered_address_bytes.copy_from_slice(&recovered_address[0..20]);
// Get the little-endian address from the public key.
let le_address = keypairs[0].public_key.to_address().to_bytes();

// Convert the first 20 bytes of the little-endian address back to the original format.
let mut rec_address_bytes: [u8; 20] = [0; 20];
rec_address_bytes.copy_from_slice(&le_address[0..20]);
rec_address_bytes.reverse();

assert_eq!(recovered_address_bytes, expected_address_bytes);
assert_eq!(rec_address_bytes, expected_address_bytes);
}

#[test]
Expand Down
22 changes: 14 additions & 8 deletions eigentrust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ use eigentrust_zk::{
ecdsa::native::{EcdsaKeypair, PublicKey, Signature},
halo2::halo2curves::{
bn256,
ff::PrimeField,
secp256k1::{Fq, Secp256k1Affine},
},
params::{
Expand All @@ -86,13 +85,14 @@ use ethers::{
prelude::EthDisplay,
providers::{Http, Middleware, Provider},
signers::{coins_bip39::English, LocalWallet, MnemonicBuilder, Signer},
types::{Filter, Log, H256},
types::{Filter, Log, H160, H256},
};
use log::{info, warn};
use num_rational::BigRational;
use serde::{Deserialize, Serialize};
use std::{
collections::{BTreeSet, HashMap},
str::FromStr,
sync::Arc,
};

Expand All @@ -106,8 +106,6 @@ const INITIAL_SCORE: u128 = 1000;
const NUM_DECIMAL_LIMBS: usize = 2;
/// Number of digits of each limbs for threshold checking.
const POWER_OF_TEN: usize = 72;
/// Attestation domain value
const DOMAIN: u128 = 42;

/// Client Signer.
pub type ClientSigner = SignerMiddleware<Provider<Http>, LocalWallet>;
Expand Down Expand Up @@ -290,7 +288,11 @@ impl Client {
attestation_matrix[attester_pos][attested_pos] = Some(signed_attestation_fr);
}

let domain = Scalar::from_u128(DOMAIN);
// Build domain
let domain_bytes: H160 = H160::from_str(&self.config.domain)
.map_err(|e| EigenError::ParsingError(format!("Error parsing domain: {}", e)))?;
let domain = Scalar::from_bytes(H256::from(domain_bytes).as_fixed_bytes()).unwrap();

// Initialize EigenTrustSet
let mut eigen_trust_set = EigenTrustSet::<
MAX_NEIGHBOURS,
Expand Down Expand Up @@ -349,14 +351,18 @@ impl Client {
let mut scalar = score_fr.to_bytes();
scalar.reverse();

let num_bytes = score_rat.numer().to_bytes_be().1;
let den_bytes = score_rat.denom().to_bytes_be().1;
let score_bytes = score_rat.to_integer().to_bytes_be().1;

let mut numerator: [u8; 32] = [0; 32];
numerator.copy_from_slice(score_rat.numer().to_bytes_be().1.as_slice());
numerator[32 - num_bytes.len()..].copy_from_slice(&num_bytes);

let mut denominator: [u8; 32] = [0; 32];
denominator.copy_from_slice(score_rat.denom().to_bytes_be().1.as_slice());
denominator[32 - den_bytes.len()..].copy_from_slice(&den_bytes);

let mut score_hex: [u8; 32] = [0; 32];
score_hex.copy_from_slice(score_rat.to_integer().to_bytes_be().1.as_slice());
score_hex[32 - score_bytes.len()..].copy_from_slice(&score_bytes);

Score { address, score_fr: scalar, score_rat: (numerator, denominator), score_hex }
})
Expand Down
22 changes: 6 additions & 16 deletions eigentrust/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
};
use csv::{ReaderBuilder, WriterBuilder};
use ethers::{
types::{H160, H256},
types::{H160, H256, U256},
utils::hex,
};
use serde::Deserialize;
Expand Down Expand Up @@ -132,11 +132,11 @@ impl ScoreRecord {

/// Creates a new score record from a score.
pub fn from_score(score: Score) -> Self {
let peer_address = Self::to_hex_string(&score.address, true);
let score_fr_hex = Self::to_hex_string(&score.score_fr, true);
let numerator = Self::to_hex_string(&score.score_rat.0, false);
let denominator = Self::to_hex_string(&score.score_rat.1, false);
let score_hex = Self::to_hex_string(&score.score_hex, true);
let peer_address = format!("0x{}", hex::encode(score.address));
let score_fr_hex = format!("0x{}", hex::encode(score.score_fr));
let numerator = U256::from_big_endian(&score.score_rat.0).to_string();
let denominator = U256::from_big_endian(&score.score_rat.1).to_string();
let score_hex = U256::from_big_endian(&score.score_hex).to_string();

Self::new(
peer_address, score_fr_hex, numerator, denominator, score_hex,
Expand Down Expand Up @@ -167,16 +167,6 @@ impl ScoreRecord {
pub fn score(&self) -> &String {
&self.score
}

/// Converts bytes to a hexadecimal string.
fn to_hex_string(bytes: &[u8], prefix: bool) -> String {
let hex_string = bytes.iter().map(|byte| format!("{:02x}", byte)).collect::<String>();
if prefix {
format!("0x{}", hex_string)
} else {
hex_string
}
}
}

/// Attestation record.
Expand Down

0 comments on commit 0cdc001

Please sign in to comment.