From 84c4346ea9ace6666151b78f36b9600e7c51398b Mon Sep 17 00:00:00 2001 From: ryardley Date: Mon, 23 Sep 2024 10:20:51 +1000 Subject: [PATCH 01/35] Array -> [u8;20] --- packages/ciphernode/core/src/ciphernode.rs | 10 +++++----- .../ciphernode/core/src/ciphernode_selector.rs | 6 +++--- packages/ciphernode/core/src/events.rs | 15 +++++++-------- packages/ciphernode/core/src/lib.rs | 7 +++---- packages/ciphernode/core/src/logger.rs | 3 ++- .../ciphernode/core/src/main_ciphernode.rs | 4 ++-- packages/ciphernode/core/src/sortition.rs | 18 +++++++++++------- .../ciphernode/enclave_node/src/bin/cmd.rs | 10 ++++------ 8 files changed, 37 insertions(+), 36 deletions(-) diff --git a/packages/ciphernode/core/src/ciphernode.rs b/packages/ciphernode/core/src/ciphernode.rs index 8bf0e9c5..00a030ae 100644 --- a/packages/ciphernode/core/src/ciphernode.rs +++ b/packages/ciphernode/core/src/ciphernode.rs @@ -14,7 +14,7 @@ pub struct Ciphernode { fhe: Addr, data: Addr, bus: Addr, - address: Address, + address: [u8;20], } impl Actor for Ciphernode { @@ -22,7 +22,7 @@ impl Actor for Ciphernode { } impl Ciphernode { - pub fn new(bus: Addr, fhe: Addr, data: Addr, address: Address) -> Self { + pub fn new(bus: Addr, fhe: Addr, data: Addr, address: [u8;20]) -> Self { Self { bus, fhe, @@ -82,7 +82,7 @@ async fn on_ciphernode_selected( data: Addr, bus: Addr, event: CiphernodeSelected, - address: Address, + address: [u8;20], ) -> Result<()> { let CiphernodeSelected { e3_id, .. } = event; @@ -117,7 +117,7 @@ async fn on_decryption_requested( data: Addr, bus: Addr, event: CiphertextOutputPublished, - address: Address, + address: [u8;20], ) -> Result<()> { let CiphertextOutputPublished { e3_id, @@ -151,7 +151,7 @@ async fn on_decryption_requested( pub struct CiphernodeFactory; impl CiphernodeFactory { - pub fn create(bus: Addr, data: Addr, address: Address) -> ActorFactory { + pub fn create(bus: Addr, data: Addr, address: [u8;20]) -> ActorFactory { Box::new(move |ctx, evt| { // Save Ciphernode on CiphernodeSelected let EnclaveEvent::CiphernodeSelected { .. } = evt else { diff --git a/packages/ciphernode/core/src/ciphernode_selector.rs b/packages/ciphernode/core/src/ciphernode_selector.rs index 5502d947..7e90dd4c 100644 --- a/packages/ciphernode/core/src/ciphernode_selector.rs +++ b/packages/ciphernode/core/src/ciphernode_selector.rs @@ -8,7 +8,7 @@ use crate::{ pub struct CiphernodeSelector { bus: Addr, sortition: Addr, - address: Address, + address: [u8;20], } impl Actor for CiphernodeSelector { @@ -16,7 +16,7 @@ impl Actor for CiphernodeSelector { } impl CiphernodeSelector { - pub fn new(bus: Addr, sortition: Addr, address: Address) -> Self { + pub fn new(bus: Addr, sortition: Addr, address: [u8;20]) -> Self { Self { bus, sortition, @@ -24,7 +24,7 @@ impl CiphernodeSelector { } } - pub fn attach(bus: Addr, sortition: Addr, address: Address) -> Addr { + pub fn attach(bus: Addr, sortition: Addr, address: [u8;20]) -> Addr { let addr = CiphernodeSelector::new(bus.clone(), sortition, address).start(); bus.do_send(Subscribe::new( diff --git a/packages/ciphernode/core/src/events.rs b/packages/ciphernode/core/src/events.rs index 43a42fff..4e5ace8a 100644 --- a/packages/ciphernode/core/src/events.rs +++ b/packages/ciphernode/core/src/events.rs @@ -1,5 +1,4 @@ use actix::Message; -use alloy_primitives::Address; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; use std::{ @@ -10,8 +9,8 @@ use std::{ #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct EthAddr(pub Vec); -impl From
for EthAddr { - fn from(value: Address) -> Self { +impl From<[u8;20]> for EthAddr { + fn from(value: [u8;20]) -> Self { Self(value.to_vec()) } } @@ -246,7 +245,7 @@ impl fmt::Display for EnclaveEvent { pub struct KeyshareCreated { pub pubkey: Vec, pub e3_id: E3id, - pub node: Address, + pub node: [u8;20], } #[derive(Message, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -254,7 +253,7 @@ pub struct KeyshareCreated { pub struct DecryptionshareCreated { pub decryption_share: Vec, pub e3_id: E3id, - pub node: Address, + pub node: [u8;20], } #[derive(Message, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -307,7 +306,7 @@ pub struct PlaintextAggregated { #[derive(Message, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[rtype(result = "()")] pub struct CiphernodeAdded { - pub address: Address, + pub address: [u8;20], pub index: usize, pub num_nodes: usize, } @@ -315,7 +314,7 @@ pub struct CiphernodeAdded { #[derive(Message, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[rtype(result = "()")] pub struct CiphernodeRemoved { - pub address: Address, + pub address: [u8;20], pub index: usize, pub num_nodes: usize, } @@ -383,7 +382,7 @@ mod tests { let kse = EnclaveEvent::from(KeyshareCreated { e3_id: E3id::from(1001), pubkey, - node: address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045"), + node: address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into_array(), }); let kse_bytes = kse.to_bytes()?; let _ = EnclaveEvent::from_bytes(&kse_bytes.clone()); diff --git a/packages/ciphernode/core/src/lib.rs b/packages/ciphernode/core/src/lib.rs index 3131e409..c0e95d7b 100644 --- a/packages/ciphernode/core/src/lib.rs +++ b/packages/ciphernode/core/src/lib.rs @@ -62,7 +62,6 @@ mod tests { SharedRng, Sortition, }; use actix::prelude::*; - use alloy_primitives::Address; use anyhow::*; use fhe::{ bfv::{BfvParameters, Encoding, Plaintext, PublicKey, SecretKey}, @@ -81,7 +80,7 @@ mod tests { bus: Addr, rng: SharedRng, logging: bool, - addr: Address, + addr: [u8;20], ) { // create data actor for saving data let data = Data::new(logging).start(); // TODO: Use a sled backed Data Actor @@ -130,8 +129,8 @@ mod tests { let rng = Arc::new(std::sync::Mutex::new(ChaCha20Rng::seed_from_u64(42))); - let eth_addrs: Vec
= (0..3) - .map(|_| Address::from_slice(&rand::thread_rng().gen::<[u8; 20]>())) + let eth_addrs: Vec<[u8;20]> = (0..3) + .map(|_| rand::thread_rng().gen::<[u8; 20]>()) .collect(); setup_local_ciphernode(bus.clone(), rng.clone(), true, eth_addrs[0]).await; diff --git a/packages/ciphernode/core/src/logger.rs b/packages/ciphernode/core/src/logger.rs index 8b3ef1cf..d9840ccc 100644 --- a/packages/ciphernode/core/src/logger.rs +++ b/packages/ciphernode/core/src/logger.rs @@ -1,5 +1,6 @@ use crate::{EnclaveEvent, EventBus, Subscribe}; use actix::{Actor, Addr, Context, Handler}; +use alloy::primitives::Address; use base64::prelude::*; use std::fs; @@ -46,7 +47,7 @@ impl Handler for SimpleLogger { println!("[{}]: {}", self.name, msg); } EnclaveEvent::CiphernodeAdded { data, .. } => { - println!("[{}]: CiphernodeAdded({})", self.name, data.address); + println!("[{}]: CiphernodeAdded({})", self.name, Address::from(data.address)); } _ => println!("[{}]: {}", self.name, msg), } diff --git a/packages/ciphernode/core/src/main_ciphernode.rs b/packages/ciphernode/core/src/main_ciphernode.rs index 94af2618..4d0cd569 100644 --- a/packages/ciphernode/core/src/main_ciphernode.rs +++ b/packages/ciphernode/core/src/main_ciphernode.rs @@ -56,7 +56,7 @@ impl MainCiphernode { let bus = EventBus::new(true).start(); let data = Data::new(true).start(); // TODO: Use a sled backed Data Actor let sortition = Sortition::attach(bus.clone()); - let selector = CiphernodeSelector::attach(bus.clone(), sortition.clone(), address); + let selector = CiphernodeSelector::attach(bus.clone(), sortition.clone(), address.into_array()); let e3_manager = E3RequestManager::builder(bus.clone()) .add_hook(CommitteeMetaFactory::create()) @@ -64,7 +64,7 @@ impl MainCiphernode { .add_hook(CiphernodeFactory::create( bus.clone(), data.clone(), - address, + address.into_array(), )) .build(); diff --git a/packages/ciphernode/core/src/sortition.rs b/packages/ciphernode/core/src/sortition.rs index f808be3d..c8e0bd6f 100644 --- a/packages/ciphernode/core/src/sortition.rs +++ b/packages/ciphernode/core/src/sortition.rs @@ -10,7 +10,7 @@ use crate::{CiphernodeAdded, CiphernodeRemoved, EnclaveEvent, EthAddr, EventBus, #[rtype(result = "bool")] pub struct GetHasNode { pub seed: u64, - pub address: Address, + pub address: [u8; 20], pub size: usize, } @@ -21,7 +21,7 @@ pub trait SortitionList { } pub struct SortitionModule { - nodes: HashSet
, + nodes: HashSet<[u8; 20]>, } impl SortitionModule { @@ -38,11 +38,15 @@ impl Default for SortitionModule { } } -impl SortitionList
for SortitionModule { - fn contains(&self, seed: u64, size: usize, address: Address) -> bool { +impl SortitionList<[u8; 20]> for SortitionModule { + fn contains(&self, seed: u64, size: usize, address: [u8; 20]) -> bool { DistanceSortition::new( seed, - self.nodes.clone().into_iter().collect(), + self.nodes + .clone() + .into_iter() + .map(|b| Address::from(b)) + .collect(), size, ) .get_committee() @@ -50,11 +54,11 @@ impl SortitionList
for SortitionModule { .any(|(_, addr)| *addr == address) } - fn add(&mut self, address: Address) { + fn add(&mut self, address: [u8; 20]) { self.nodes.insert(address); } - fn remove(&mut self, address: Address) { + fn remove(&mut self, address: [u8; 20]) { self.nodes.remove(&address); } } diff --git a/packages/ciphernode/enclave_node/src/bin/cmd.rs b/packages/ciphernode/enclave_node/src/bin/cmd.rs index aca81e00..eb2ff360 100644 --- a/packages/ciphernode/enclave_node/src/bin/cmd.rs +++ b/packages/ciphernode/enclave_node/src/bin/cmd.rs @@ -7,8 +7,6 @@ use enclave_core::{ SimpleLogger, }; use enclave_core::{CiphernodeAdded, CiphertextOutputPublished}; -use fhe::bfv::{Encoding, Plaintext, PublicKey}; -use fhe_traits::{DeserializeParametrized, FheEncoder}; use rand::{thread_rng, RngCore, SeedableRng}; use rand_chacha::rand_core::OsRng; use std::fs; @@ -50,7 +48,7 @@ async fn main() -> Result<(), Box> { ["reg", "1"] => { println!("Registering Ciphernode {}", ADDRS[0]); bus.do_send(EnclaveEvent::from(CiphernodeAdded { - address: ADDRS[0], + address: ADDRS[0].into_array(), index: 0, num_nodes: 1, })); @@ -58,7 +56,7 @@ async fn main() -> Result<(), Box> { ["reg", "2"] => { println!("Registering Ciphernode {}", ADDRS[1]); bus.do_send(EnclaveEvent::from(CiphernodeAdded { - address: ADDRS[1], + address: ADDRS[1].into_array(), index: 1, num_nodes: 2, })) @@ -66,7 +64,7 @@ async fn main() -> Result<(), Box> { ["reg", "3"] => { println!("Registering Ciphernode {}", ADDRS[2]); bus.do_send(EnclaveEvent::from(CiphernodeAdded { - address: ADDRS[2], + address: ADDRS[2].into_array(), index: 2, num_nodes: 3, })) @@ -74,7 +72,7 @@ async fn main() -> Result<(), Box> { ["reg", "4"] => { println!("Registering Ciphernode {}", ADDRS[3]); bus.do_send(EnclaveEvent::from(CiphernodeAdded { - address: ADDRS[3], + address: ADDRS[3].into_array(), index: 3, num_nodes: 4, })) From 7e9586052c3ab8c7f30267c5e4a9dcd3de9ab7a4 Mon Sep 17 00:00:00 2001 From: ryardley Date: Mon, 23 Sep 2024 21:09:31 +1000 Subject: [PATCH 02/35] [u8;20] -> String --- packages/ciphernode/core/src/ciphernode.rs | 20 +++++----- .../core/src/ciphernode_selector.rs | 11 +++--- packages/ciphernode/core/src/events.rs | 19 +++------- packages/ciphernode/core/src/lib.rs | 37 +++++++++---------- packages/ciphernode/core/src/logger.rs | 2 +- .../ciphernode/core/src/main_ciphernode.rs | 9 ++--- packages/ciphernode/core/src/sortition.rs | 19 +++++----- .../ciphernode/enclave_node/src/bin/cmd.rs | 8 ++-- 8 files changed, 55 insertions(+), 70 deletions(-) diff --git a/packages/ciphernode/core/src/ciphernode.rs b/packages/ciphernode/core/src/ciphernode.rs index 00a030ae..fa92ef0f 100644 --- a/packages/ciphernode/core/src/ciphernode.rs +++ b/packages/ciphernode/core/src/ciphernode.rs @@ -7,14 +7,13 @@ use crate::{ DecryptionshareCreated, Get, }; use actix::prelude::*; -use alloy_primitives::Address; use anyhow::Result; pub struct Ciphernode { fhe: Addr, data: Addr, bus: Addr, - address: [u8;20], + address: String, } impl Actor for Ciphernode { @@ -22,12 +21,12 @@ impl Actor for Ciphernode { } impl Ciphernode { - pub fn new(bus: Addr, fhe: Addr, data: Addr, address: [u8;20]) -> Self { + pub fn new(bus: Addr, fhe: Addr, data: Addr, address: &str) -> Self { Self { bus, fhe, data, - address, + address:address.to_string(), } } } @@ -51,7 +50,7 @@ impl Handler for Ciphernode { let fhe = self.fhe.clone(); let data = self.data.clone(); let bus = self.bus.clone(); - let address = self.address; + let address = self.address.clone(); Box::pin(async move { on_ciphernode_selected(fhe, data, bus, event, address) .await @@ -68,7 +67,7 @@ impl Handler for Ciphernode { let fhe = self.fhe.clone(); let data = self.data.clone(); let bus = self.bus.clone(); - let address = self.address; + let address = self.address.clone(); Box::pin(async move { on_decryption_requested(fhe, data, bus, event, address) .await @@ -82,7 +81,7 @@ async fn on_ciphernode_selected( data: Addr, bus: Addr, event: CiphernodeSelected, - address: [u8;20], + address: String, ) -> Result<()> { let CiphernodeSelected { e3_id, .. } = event; @@ -117,7 +116,7 @@ async fn on_decryption_requested( data: Addr, bus: Addr, event: CiphertextOutputPublished, - address: [u8;20], + address: String, ) -> Result<()> { let CiphertextOutputPublished { e3_id, @@ -151,7 +150,8 @@ async fn on_decryption_requested( pub struct CiphernodeFactory; impl CiphernodeFactory { - pub fn create(bus: Addr, data: Addr, address: [u8;20]) -> ActorFactory { + pub fn create(bus: Addr, data: Addr, address: &str) -> ActorFactory { + let address = address.to_string(); Box::new(move |ctx, evt| { // Save Ciphernode on CiphernodeSelected let EnclaveEvent::CiphernodeSelected { .. } = evt else { @@ -163,7 +163,7 @@ impl CiphernodeFactory { }; ctx.ciphernode = - Some(Ciphernode::new(bus.clone(), fhe.clone(), data.clone(), address).start()) + Some(Ciphernode::new(bus.clone(), fhe.clone(), data.clone(), &address).start()) }) } } diff --git a/packages/ciphernode/core/src/ciphernode_selector.rs b/packages/ciphernode/core/src/ciphernode_selector.rs index 7e90dd4c..5589cefd 100644 --- a/packages/ciphernode/core/src/ciphernode_selector.rs +++ b/packages/ciphernode/core/src/ciphernode_selector.rs @@ -1,5 +1,4 @@ use actix::prelude::*; -use alloy_primitives::Address; use crate::{ CiphernodeSelected, EnclaveEvent, EventBus, GetHasNode, Sortition, Subscribe, @@ -8,7 +7,7 @@ use crate::{ pub struct CiphernodeSelector { bus: Addr, sortition: Addr, - address: [u8;20], + address: String, } impl Actor for CiphernodeSelector { @@ -16,15 +15,15 @@ impl Actor for CiphernodeSelector { } impl CiphernodeSelector { - pub fn new(bus: Addr, sortition: Addr, address: [u8;20]) -> Self { + pub fn new(bus: Addr, sortition: Addr, address: &str) -> Self { Self { bus, sortition, - address, + address:address.to_owned(), } } - pub fn attach(bus: Addr, sortition: Addr, address: [u8;20]) -> Addr { + pub fn attach(bus: Addr, sortition: Addr, address: &str) -> Addr { let addr = CiphernodeSelector::new(bus.clone(), sortition, address).start(); bus.do_send(Subscribe::new( @@ -40,7 +39,7 @@ impl Handler for CiphernodeSelector { type Result = ResponseFuture<()>; fn handle(&mut self, event: EnclaveEvent, _ctx: &mut Self::Context) -> Self::Result { - let address = self.address; + let address = self.address.clone(); let sortition = self.sortition.clone(); let bus = self.bus.clone(); diff --git a/packages/ciphernode/core/src/events.rs b/packages/ciphernode/core/src/events.rs index 4e5ace8a..586feae3 100644 --- a/packages/ciphernode/core/src/events.rs +++ b/packages/ciphernode/core/src/events.rs @@ -6,15 +6,6 @@ use std::{ hash::{DefaultHasher, Hash, Hasher}, }; -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub struct EthAddr(pub Vec); - -impl From<[u8;20]> for EthAddr { - fn from(value: [u8;20]) -> Self { - Self(value.to_vec()) - } -} - #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct E3id(pub String); impl fmt::Display for E3id { @@ -245,7 +236,7 @@ impl fmt::Display for EnclaveEvent { pub struct KeyshareCreated { pub pubkey: Vec, pub e3_id: E3id, - pub node: [u8;20], + pub node: String, } #[derive(Message, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -253,7 +244,7 @@ pub struct KeyshareCreated { pub struct DecryptionshareCreated { pub decryption_share: Vec, pub e3_id: E3id, - pub node: [u8;20], + pub node: String, } #[derive(Message, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -306,7 +297,7 @@ pub struct PlaintextAggregated { #[derive(Message, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[rtype(result = "()")] pub struct CiphernodeAdded { - pub address: [u8;20], + pub address: String, pub index: usize, pub num_nodes: usize, } @@ -314,7 +305,7 @@ pub struct CiphernodeAdded { #[derive(Message, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[rtype(result = "()")] pub struct CiphernodeRemoved { - pub address: [u8;20], + pub address: String, pub index: usize, pub num_nodes: usize, } @@ -382,7 +373,7 @@ mod tests { let kse = EnclaveEvent::from(KeyshareCreated { e3_id: E3id::from(1001), pubkey, - node: address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into_array(), + node: address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").to_string(), }); let kse_bytes = kse.to_bytes()?; let _ = EnclaveEvent::from_bytes(&kse_bytes.clone()); diff --git a/packages/ciphernode/core/src/lib.rs b/packages/ciphernode/core/src/lib.rs index c0e95d7b..b1ef51cd 100644 --- a/packages/ciphernode/core/src/lib.rs +++ b/packages/ciphernode/core/src/lib.rs @@ -62,6 +62,7 @@ mod tests { SharedRng, Sortition, }; use actix::prelude::*; + use alloy::primitives::Address; use anyhow::*; use fhe::{ bfv::{BfvParameters, Encoding, Plaintext, PublicKey, SecretKey}, @@ -80,7 +81,7 @@ mod tests { bus: Addr, rng: SharedRng, logging: bool, - addr: [u8;20], + addr: &str, ) { // create data actor for saving data let data = Data::new(logging).start(); // TODO: Use a sled backed Data Actor @@ -100,11 +101,7 @@ mod tests { bus.clone(), sortition.clone(), )) - .add_hook(CiphernodeFactory::create( - bus.clone(), - data.clone(), - addr, - )) + .add_hook(CiphernodeFactory::create(bus.clone(), data.clone(), addr)) .build(); } @@ -129,13 +126,13 @@ mod tests { let rng = Arc::new(std::sync::Mutex::new(ChaCha20Rng::seed_from_u64(42))); - let eth_addrs: Vec<[u8;20]> = (0..3) - .map(|_| rand::thread_rng().gen::<[u8; 20]>()) + let eth_addrs: Vec = (0..3) + .map(|_| Address::from_slice(&rand::thread_rng().gen::<[u8; 20]>()).to_string()) .collect(); - setup_local_ciphernode(bus.clone(), rng.clone(), true, eth_addrs[0]).await; - setup_local_ciphernode(bus.clone(), rng.clone(), true, eth_addrs[1]).await; - setup_local_ciphernode(bus.clone(), rng.clone(), true, eth_addrs[2]).await; + setup_local_ciphernode(bus.clone(), rng.clone(), true, ð_addrs[0]).await; + setup_local_ciphernode(bus.clone(), rng.clone(), true, ð_addrs[1]).await; + setup_local_ciphernode(bus.clone(), rng.clone(), true, ð_addrs[2]).await; let e3_id = E3id::new("1234"); @@ -153,7 +150,7 @@ mod tests { ); let regevt_1 = EnclaveEvent::from(CiphernodeAdded { - address: eth_addrs[0], + address: eth_addrs[0].clone(), index: 0, num_nodes: 1, }); @@ -161,7 +158,7 @@ mod tests { bus.send(regevt_1.clone()).await?; let regevt_2 = EnclaveEvent::from(CiphernodeAdded { - address: eth_addrs[1], + address: eth_addrs[1].clone(), index: 1, num_nodes: 2, }); @@ -169,7 +166,7 @@ mod tests { bus.send(regevt_2.clone()).await?; let regevt_3 = EnclaveEvent::from(CiphernodeAdded { - address: eth_addrs[2], + address: eth_addrs[2].clone(), index: 2, num_nodes: 3, }); @@ -231,17 +228,17 @@ mod tests { EnclaveEvent::from(KeyshareCreated { pubkey: p1.clone(), e3_id: e3_id.clone(), - node: eth_addrs[0] + node: eth_addrs[0].clone() }), EnclaveEvent::from(KeyshareCreated { pubkey: p2.clone(), e3_id: e3_id.clone(), - node: eth_addrs[1] + node: eth_addrs[1].clone() }), EnclaveEvent::from(KeyshareCreated { pubkey: p3.clone(), e3_id: e3_id.clone(), - node: eth_addrs[2] + node: eth_addrs[2].clone() }), EnclaveEvent::from(PublicKeyAggregated { pubkey: pubkey.to_bytes(), @@ -302,17 +299,17 @@ mod tests { EnclaveEvent::from(DecryptionshareCreated { decryption_share: ds1.clone(), e3_id: e3_id.clone(), - node: eth_addrs[0] + node: eth_addrs[0].clone() }), EnclaveEvent::from(DecryptionshareCreated { decryption_share: ds2.clone(), e3_id: e3_id.clone(), - node: eth_addrs[1] + node: eth_addrs[1].clone() }), EnclaveEvent::from(DecryptionshareCreated { decryption_share: ds3.clone(), e3_id: e3_id.clone(), - node: eth_addrs[2] + node: eth_addrs[2].clone() }), EnclaveEvent::from(PlaintextAggregated { e3_id: e3_id.clone(), diff --git a/packages/ciphernode/core/src/logger.rs b/packages/ciphernode/core/src/logger.rs index d9840ccc..5733743c 100644 --- a/packages/ciphernode/core/src/logger.rs +++ b/packages/ciphernode/core/src/logger.rs @@ -47,7 +47,7 @@ impl Handler for SimpleLogger { println!("[{}]: {}", self.name, msg); } EnclaveEvent::CiphernodeAdded { data, .. } => { - println!("[{}]: CiphernodeAdded({})", self.name, Address::from(data.address)); + println!("[{}]: CiphernodeAdded({})", self.name, data.address); } _ => println!("[{}]: {}", self.name, msg), } diff --git a/packages/ciphernode/core/src/main_ciphernode.rs b/packages/ciphernode/core/src/main_ciphernode.rs index 4d0cd569..5f22e388 100644 --- a/packages/ciphernode/core/src/main_ciphernode.rs +++ b/packages/ciphernode/core/src/main_ciphernode.rs @@ -1,9 +1,7 @@ use std::sync::{Arc, Mutex}; use crate::{ - CiphernodeFactory, CiphernodeSelector, CommitteeMetaFactory, Data, E3RequestManager, EventBus, - FheFactory, P2p, PlaintextAggregatorFactory, PublicKeyAggregatorFactory, SimpleLogger, - Sortition, + CiphernodeFactory, CiphernodeSelector, CommitteeMetaFactory, Data, E3RequestManager, EventBus, FheFactory, P2p, SimpleLogger, Sortition }; use actix::{Actor, Addr, Context}; use alloy_primitives::Address; @@ -56,7 +54,8 @@ impl MainCiphernode { let bus = EventBus::new(true).start(); let data = Data::new(true).start(); // TODO: Use a sled backed Data Actor let sortition = Sortition::attach(bus.clone()); - let selector = CiphernodeSelector::attach(bus.clone(), sortition.clone(), address.into_array()); + let selector = + CiphernodeSelector::attach(bus.clone(), sortition.clone(), &address.to_string()); let e3_manager = E3RequestManager::builder(bus.clone()) .add_hook(CommitteeMetaFactory::create()) @@ -64,7 +63,7 @@ impl MainCiphernode { .add_hook(CiphernodeFactory::create( bus.clone(), data.clone(), - address.into_array(), + &address.to_string(), )) .build(); diff --git a/packages/ciphernode/core/src/sortition.rs b/packages/ciphernode/core/src/sortition.rs index c8e0bd6f..edbf942f 100644 --- a/packages/ciphernode/core/src/sortition.rs +++ b/packages/ciphernode/core/src/sortition.rs @@ -1,16 +1,15 @@ use std::collections::HashSet; use actix::prelude::*; -use alloy_primitives::Address; use sortition::DistanceSortition; -use crate::{CiphernodeAdded, CiphernodeRemoved, EnclaveEvent, EthAddr, EventBus, Subscribe}; +use crate::{CiphernodeAdded, CiphernodeRemoved, EnclaveEvent, EventBus, Subscribe}; #[derive(Message, Clone, Debug, PartialEq, Eq)] #[rtype(result = "bool")] pub struct GetHasNode { pub seed: u64, - pub address: [u8; 20], + pub address: String, pub size: usize, } @@ -21,7 +20,7 @@ pub trait SortitionList { } pub struct SortitionModule { - nodes: HashSet<[u8; 20]>, + nodes: HashSet, } impl SortitionModule { @@ -38,27 +37,27 @@ impl Default for SortitionModule { } } -impl SortitionList<[u8; 20]> for SortitionModule { - fn contains(&self, seed: u64, size: usize, address: [u8; 20]) -> bool { +impl SortitionList for SortitionModule { + fn contains(&self, seed: u64, size: usize, address: String) -> bool { DistanceSortition::new( seed, self.nodes .clone() .into_iter() - .map(|b| Address::from(b)) + .map(|b| b.parse().unwrap()) .collect(), size, ) .get_committee() .iter() - .any(|(_, addr)| *addr == address) + .any(|(_, addr)| addr.to_string() == address) } - fn add(&mut self, address: [u8; 20]) { + fn add(&mut self, address: String) { self.nodes.insert(address); } - fn remove(&mut self, address: [u8; 20]) { + fn remove(&mut self, address: String) { self.nodes.remove(&address); } } diff --git a/packages/ciphernode/enclave_node/src/bin/cmd.rs b/packages/ciphernode/enclave_node/src/bin/cmd.rs index eb2ff360..4ab57431 100644 --- a/packages/ciphernode/enclave_node/src/bin/cmd.rs +++ b/packages/ciphernode/enclave_node/src/bin/cmd.rs @@ -48,7 +48,7 @@ async fn main() -> Result<(), Box> { ["reg", "1"] => { println!("Registering Ciphernode {}", ADDRS[0]); bus.do_send(EnclaveEvent::from(CiphernodeAdded { - address: ADDRS[0].into_array(), + address: ADDRS[0].to_string(), index: 0, num_nodes: 1, })); @@ -56,7 +56,7 @@ async fn main() -> Result<(), Box> { ["reg", "2"] => { println!("Registering Ciphernode {}", ADDRS[1]); bus.do_send(EnclaveEvent::from(CiphernodeAdded { - address: ADDRS[1].into_array(), + address: ADDRS[1].to_string(), index: 1, num_nodes: 2, })) @@ -64,7 +64,7 @@ async fn main() -> Result<(), Box> { ["reg", "3"] => { println!("Registering Ciphernode {}", ADDRS[2]); bus.do_send(EnclaveEvent::from(CiphernodeAdded { - address: ADDRS[2].into_array(), + address: ADDRS[2].to_string(), index: 2, num_nodes: 3, })) @@ -72,7 +72,7 @@ async fn main() -> Result<(), Box> { ["reg", "4"] => { println!("Registering Ciphernode {}", ADDRS[3]); bus.do_send(EnclaveEvent::from(CiphernodeAdded { - address: ADDRS[3].into_array(), + address: ADDRS[3].to_string(), index: 3, num_nodes: 4, })) From 8a8ecad0e6edd0819d514d082193af157dd3808d Mon Sep 17 00:00:00 2001 From: ryardley Date: Mon, 23 Sep 2024 21:18:52 +1000 Subject: [PATCH 03/35] Setup evm events --- packages/ciphernode/core/src/e3_request.rs | 10 +----- .../ciphernode/core/src/enclave_contract.rs | 13 ------- packages/ciphernode/core/src/evm.rs | 36 +++++++++++++++---- packages/ciphernode/core/src/lib.rs | 1 - 4 files changed, 30 insertions(+), 30 deletions(-) delete mode 100644 packages/ciphernode/core/src/enclave_contract.rs diff --git a/packages/ciphernode/core/src/e3_request.rs b/packages/ciphernode/core/src/e3_request.rs index 32de3914..c59f3a16 100644 --- a/packages/ciphernode/core/src/e3_request.rs +++ b/packages/ciphernode/core/src/e3_request.rs @@ -16,19 +16,11 @@ pub struct E3RequestContext { pub publickey: Option>, pub meta: Option, } - +#[derive(Default)] struct EventBuffer { buffer: HashMap>, } -impl Default for EventBuffer { - fn default() -> Self { - Self { - buffer: HashMap::new(), - } - } -} - impl EventBuffer { pub fn add(&mut self, key: &str, event: EnclaveEvent) { self.buffer.entry(key.to_string()).or_default().push(event) diff --git a/packages/ciphernode/core/src/enclave_contract.rs b/packages/ciphernode/core/src/enclave_contract.rs deleted file mode 100644 index ef607190..00000000 --- a/packages/ciphernode/core/src/enclave_contract.rs +++ /dev/null @@ -1,13 +0,0 @@ -use actix::{Actor, Context}; - -/// Manage an internal web3 instance and express protocol specific behaviour through the events it -/// accepts and emits to the EventBus -/// Monitor contract events using `contract.events().create_filter()` and rebroadcast to eventbus by -/// creating `EnclaveEvent` events -/// Delegate signing to a separate actor responsible for managing Eth keys -/// Accept eventbus events and forward as appropriate contract calls as required -pub struct EnclaveContract; - -impl Actor for EnclaveContract { - type Context = Context; -} diff --git a/packages/ciphernode/core/src/evm.rs b/packages/ciphernode/core/src/evm.rs index 2984ac41..c8d92038 100644 --- a/packages/ciphernode/core/src/evm.rs +++ b/packages/ciphernode/core/src/evm.rs @@ -1,14 +1,27 @@ -use actix::{Actor, Addr, Context}; -use alloy::{primitives::Address, sol, sol_types::SolEvent}; -use rand::{thread_rng, RngCore}; - use crate::{ - evm_listener::{AddEventHandler, EvmEventListener, StartListening}, - evm_manager::{AddListener, EvmContractManager}, - E3id, EnclaveEvent, EventBus, SharedRng, + events, evm_listener::{AddEventHandler, ContractEvent, EvmEventListener, StartListening}, evm_manager::{AddListener, EvmContractManager}, EnclaveEvent, EventBus }; +use actix::{Actor, Addr, Context}; +use alloy::{primitives::Address, sol, sol_types::SolEvent}; +use anyhow::Result; sol! { + #[derive(Debug)] + struct E3 { + uint256 seed; + uint32[2] threshold; + uint256[2] startWindow; + uint256 duration; + uint256 expiration; + address e3Program; + bytes e3ProgramParams; + address inputValidator; + address decryptionVerifier; + bytes committeePublicKey; + bytes ciphertextOutput; + bytes plaintextOutput; + } + #[derive(Debug)] event CommitteeRequested( uint256 indexed e3Id, @@ -37,9 +50,18 @@ sol! { uint256 indexed e3Id, bytes ciphertextOutput ); + + #[derive(Debug)] + event E3Requested( + uint256 e3Id, + E3 e3, + address filter, + address indexed e3Program + ); } struct Evm { + // holding refs to evm contracts for management evm_manager: Addr, evm_listener: Addr, } diff --git a/packages/ciphernode/core/src/lib.rs b/packages/ciphernode/core/src/lib.rs index b1ef51cd..9faf14b7 100644 --- a/packages/ciphernode/core/src/lib.rs +++ b/packages/ciphernode/core/src/lib.rs @@ -7,7 +7,6 @@ mod ciphernode_selector; mod committee_meta; mod data; mod e3_request; -mod enclave_contract; mod eventbus; pub mod events; mod evm; From e9d0d7aaf0b94b57ef808ce9018e49da6d191e48 Mon Sep 17 00:00:00 2001 From: ryardley Date: Mon, 23 Sep 2024 21:21:04 +1000 Subject: [PATCH 04/35] Remove Committee Requested event --- packages/ciphernode/core/src/evm.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/ciphernode/core/src/evm.rs b/packages/ciphernode/core/src/evm.rs index c8d92038..4190403f 100644 --- a/packages/ciphernode/core/src/evm.rs +++ b/packages/ciphernode/core/src/evm.rs @@ -22,13 +22,6 @@ sol! { bytes plaintextOutput; } - #[derive(Debug)] - event CommitteeRequested( - uint256 indexed e3Id, - address filter, - uint32[2] threshold - ); - #[derive(Debug)] event CiphernodeAdded( address indexed node, @@ -79,7 +72,7 @@ impl Evm { .unwrap(); evm_listener - .send(AddEventHandler::::new()) + .send(AddEventHandler::::new()) .await .unwrap(); From 54d60ffcaba75766bedecb1f062b6907510d747d Mon Sep 17 00:00:00 2001 From: ryardley Date: Mon, 23 Sep 2024 21:58:37 +1000 Subject: [PATCH 05/35] Setup evm events E3Requested and CiphernodeAdded --- .../core/src/ciphernode_selector.rs | 10 ++-- .../ciphernode/core/src/committee_meta.rs | 14 +++--- packages/ciphernode/core/src/events.rs | 28 ++++++----- packages/ciphernode/core/src/evm.rs | 49 ++++++++++++++++++- packages/ciphernode/core/src/fhe.rs | 6 +-- packages/ciphernode/core/src/lib.rs | 36 +++++++------- .../core/src/plaintext_aggregator.rs | 18 ++++--- .../core/src/publickey_aggregator.rs | 20 ++++---- .../ciphernode/enclave_node/src/bin/cmd.rs | 8 +-- 9 files changed, 122 insertions(+), 67 deletions(-) diff --git a/packages/ciphernode/core/src/ciphernode_selector.rs b/packages/ciphernode/core/src/ciphernode_selector.rs index 5589cefd..975b2019 100644 --- a/packages/ciphernode/core/src/ciphernode_selector.rs +++ b/packages/ciphernode/core/src/ciphernode_selector.rs @@ -27,7 +27,7 @@ impl CiphernodeSelector { let addr = CiphernodeSelector::new(bus.clone(), sortition, address).start(); bus.do_send(Subscribe::new( - "CommitteeRequested", + "E3Requested", addr.clone().recipient(), )); @@ -44,12 +44,12 @@ impl Handler for CiphernodeSelector { let bus = self.bus.clone(); Box::pin(async move { - let EnclaveEvent::CommitteeRequested { data, .. } = event else { + let EnclaveEvent::E3Requested { data, .. } = event else { return; }; - let seed = data.sortition_seed; - let size = data.nodecount; + let seed = data.seed; + let size = data.threshold_m as usize; if let Ok(is_selected) = sortition .send(GetHasNode { @@ -65,7 +65,7 @@ impl Handler for CiphernodeSelector { bus.do_send(EnclaveEvent::from(CiphernodeSelected { e3_id: data.e3_id, - nodecount: data.nodecount, + threshold_m: data.threshold_m, })); } }) diff --git a/packages/ciphernode/core/src/committee_meta.rs b/packages/ciphernode/core/src/committee_meta.rs index 78be9141..b910118e 100644 --- a/packages/ciphernode/core/src/committee_meta.rs +++ b/packages/ciphernode/core/src/committee_meta.rs @@ -1,8 +1,8 @@ -use crate::{ActorFactory, CommitteeRequested, EnclaveEvent}; +use crate::{ActorFactory, E3Requested, EnclaveEvent}; #[derive(Clone, Debug, PartialEq, Eq)] pub struct CommitteeMeta { - pub nodecount: usize, + pub threshold_m: u32, pub seed: u64, } @@ -11,16 +11,16 @@ pub struct CommitteeMetaFactory; impl CommitteeMetaFactory { pub fn create() -> ActorFactory { Box::new(move |ctx, evt| { - let EnclaveEvent::CommitteeRequested { data, .. }: crate::EnclaveEvent = evt else { + let EnclaveEvent::E3Requested { data, .. }: crate::EnclaveEvent = evt else { return; }; - let CommitteeRequested { - nodecount, - sortition_seed: seed, + let E3Requested { + threshold_m, + seed: seed, .. } = data; - ctx.meta = Some(CommitteeMeta { nodecount, seed }); + ctx.meta = Some(CommitteeMeta { threshold_m, seed }); }) } } diff --git a/packages/ciphernode/core/src/events.rs b/packages/ciphernode/core/src/events.rs index 586feae3..73c498df 100644 --- a/packages/ciphernode/core/src/events.rs +++ b/packages/ciphernode/core/src/events.rs @@ -26,6 +26,12 @@ impl From for E3id { } } +impl From for E3id { + fn from(value: String) -> Self { + E3id::new(value) + } +} + #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct EventId(pub [u8; 32]); @@ -54,9 +60,9 @@ pub enum EnclaveEvent { id: EventId, data: KeyshareCreated, }, - CommitteeRequested { + E3Requested { id: EventId, - data: CommitteeRequested, + data: E3Requested, }, PublicKeyAggregated { id: EventId, @@ -118,7 +124,7 @@ impl From for EventId { fn from(value: EnclaveEvent) -> Self { match value { EnclaveEvent::KeyshareCreated { id, .. } => id, - EnclaveEvent::CommitteeRequested { id, .. } => id, + EnclaveEvent::E3Requested { id, .. } => id, EnclaveEvent::PublicKeyAggregated { id, .. } => id, EnclaveEvent::CiphertextOutputPublished { id, .. } => id, EnclaveEvent::DecryptionshareCreated { id, .. } => id, @@ -134,7 +140,7 @@ impl EnclaveEvent { pub fn get_e3_id(&self) -> Option { match self.clone() { EnclaveEvent::KeyshareCreated { data, .. } => Some(data.e3_id), - EnclaveEvent::CommitteeRequested { data, .. } => Some(data.e3_id), + EnclaveEvent::E3Requested { data, .. } => Some(data.e3_id), EnclaveEvent::PublicKeyAggregated { data, .. } => Some(data.e3_id), EnclaveEvent::CiphertextOutputPublished { data, .. } => Some(data.e3_id), EnclaveEvent::DecryptionshareCreated { data, .. } => Some(data.e3_id), @@ -154,9 +160,9 @@ impl From for EnclaveEvent { } } -impl From for EnclaveEvent { - fn from(data: CommitteeRequested) -> Self { - EnclaveEvent::CommitteeRequested { +impl From for EnclaveEvent { + fn from(data: E3Requested) -> Self { + EnclaveEvent::E3Requested { id: EventId::from(data.clone()), data: data.clone(), } @@ -256,10 +262,10 @@ pub struct PublicKeyAggregated { #[derive(Message, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[rtype(result = "()")] -pub struct CommitteeRequested { +pub struct E3Requested { pub e3_id: E3id, - pub nodecount: usize, - pub sortition_seed: u64, // Should actually be much larger eg [u8;32] + pub threshold_m: u32, + pub seed: u64, // Should actually be much larger eg [u8;32] // fhe params pub moduli: Vec, @@ -277,7 +283,7 @@ pub struct CommitteeRequested { #[rtype(result = "()")] pub struct CiphernodeSelected { pub e3_id: E3id, - pub nodecount: usize, + pub threshold_m: u32, } #[derive(Message, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] diff --git a/packages/ciphernode/core/src/evm.rs b/packages/ciphernode/core/src/evm.rs index 4190403f..c5cfec36 100644 --- a/packages/ciphernode/core/src/evm.rs +++ b/packages/ciphernode/core/src/evm.rs @@ -1,9 +1,16 @@ +use std::sync::Arc; + use crate::{ - events, evm_listener::{AddEventHandler, ContractEvent, EvmEventListener, StartListening}, evm_manager::{AddListener, EvmContractManager}, EnclaveEvent, EventBus + events, + evm_listener::{AddEventHandler, ContractEvent, EvmEventListener, StartListening}, + evm_manager::{AddListener, EvmContractManager}, + setup_crp_params, EnclaveEvent, EventBus, ParamsWithCrp, }; use actix::{Actor, Addr, Context}; use alloy::{primitives::Address, sol, sol_types::SolEvent}; use anyhow::Result; +use rand::SeedableRng; +use rand_chacha::ChaCha20Rng; sol! { #[derive(Debug)] @@ -53,6 +60,46 @@ sol! { ); } +impl From for events::E3Requested { + fn from(value: E3Requested) -> Self { + let _params_bytes = value.e3.e3ProgramParams; + // TODO: decode params bytes + // HACK: temp supply canned params: + // this is temporary parse this from params_bytes above + // We will parse the ABI encoded bytes and extract params + let ParamsWithCrp { + moduli, + degree, + plaintext_modulus, + crp_bytes, + params, + } = setup_crp_params( + &[0x3FFFFFFF000001], + 2048, + 1032193, + Arc::new(std::sync::Mutex::new(ChaCha20Rng::seed_from_u64(42))), + ); + events::E3Requested { + moduli, + plaintext_modulus, + degree, + threshold_m: value.e3.threshold[0], + crp: crp_bytes, + // HACK: Following should be [u8;32] and not converted to u64 + seed: value.e3.seed.as_limbs()[1], // converting to u64 + e3_id: value.e3Id.to_string().into(), + } + } +} +// impl From for events::CiphernodeAdded { +// fn from(value: CiphernodeAdded) -> Self { +// events::CiphernodeAdded { +// address: value.node.to_string(), +// index: value.index.as_limbs()[1] as usize, +// num_nodes: value.numNodes.as_limbs()[1] as usize, +// } +// } +// } struct Evm { // holding refs to evm contracts for management evm_manager: Addr, diff --git a/packages/ciphernode/core/src/fhe.rs b/packages/ciphernode/core/src/fhe.rs index f3394c18..7085f7a1 100644 --- a/packages/ciphernode/core/src/fhe.rs +++ b/packages/ciphernode/core/src/fhe.rs @@ -4,7 +4,7 @@ use crate::{ CiphertextSerializer, DecryptionShareSerializer, PublicKeySerializer, PublicKeyShareSerializer, SecretKeySerializer, }, - ActorFactory, CommitteeRequested, EnclaveEvent, + ActorFactory, E3Requested, EnclaveEvent, }; use actix::{Actor, Context, Handler, Message}; use anyhow::*; @@ -190,10 +190,10 @@ impl FheFactory { pub fn create(rng: Arc>) -> ActorFactory { Box::new(move |ctx, evt| { // Saving the fhe on Committee Requested - let EnclaveEvent::CommitteeRequested { data, .. } = evt else { + let EnclaveEvent::E3Requested { data, .. } = evt else { return; }; - let CommitteeRequested { + let E3Requested { degree, moduli, plaintext_modulus, diff --git a/packages/ciphernode/core/src/lib.rs b/packages/ciphernode/core/src/lib.rs index 9faf14b7..9c834579 100644 --- a/packages/ciphernode/core/src/lib.rs +++ b/packages/ciphernode/core/src/lib.rs @@ -51,7 +51,7 @@ mod tests { ciphernode_selector::CiphernodeSelector, data::Data, eventbus::{EventBus, GetHistory}, - events::{CommitteeRequested, E3id, EnclaveEvent, KeyshareCreated, PublicKeyAggregated}, + events::{E3Requested, E3id, EnclaveEvent, KeyshareCreated, PublicKeyAggregated}, p2p::P2p, serializers::{CiphertextSerializer, DecryptionShareSerializer, PublicKeyShareSerializer}, utils::{setup_crp_params, ParamsWithCrp}, @@ -172,10 +172,10 @@ mod tests { bus.send(regevt_3.clone()).await?; - let event = EnclaveEvent::from(CommitteeRequested { + let event = EnclaveEvent::from(E3Requested { e3_id: e3_id.clone(), - nodecount: 3, - sortition_seed: 123, + threshold_m: 3, + seed: 123, moduli: moduli.clone(), degree, plaintext_modulus, @@ -211,10 +211,10 @@ mod tests { regevt_1, regevt_2, regevt_3, - EnclaveEvent::from(CommitteeRequested { + EnclaveEvent::from(E3Requested { e3_id: e3_id.clone(), - nodecount: 3, - sortition_seed: 123, + threshold_m: 3, + seed: 123, moduli, degree, plaintext_modulus, @@ -222,7 +222,7 @@ mod tests { }), EnclaveEvent::from(CiphernodeSelected { e3_id: e3_id.clone(), - nodecount: 3, + threshold_m: 3, }), EnclaveEvent::from(KeyshareCreated { pubkey: p1.clone(), @@ -342,20 +342,20 @@ mod tests { } }); - let evt_1 = EnclaveEvent::from(CommitteeRequested { + let evt_1 = EnclaveEvent::from(E3Requested { e3_id: E3id::new("1234"), - nodecount: 3, - sortition_seed: 123, + threshold_m: 3, + seed: 123, moduli: vec![0x3FFFFFFF000001], degree: 2048, plaintext_modulus: 1032193, crp: vec![1, 2, 3, 4], }); - let evt_2 = EnclaveEvent::from(CommitteeRequested { + let evt_2 = EnclaveEvent::from(E3Requested { e3_id: E3id::new("1235"), - nodecount: 3, - sortition_seed: 123, + threshold_m: 3, + seed: 123, moduli: vec![0x3FFFFFFF000001], degree: 2048, plaintext_modulus: 1032193, @@ -364,7 +364,7 @@ mod tests { let local_evt_3 = EnclaveEvent::from(CiphernodeSelected { e3_id: E3id::new("1235"), - nodecount: 3, + threshold_m: 3, }); bus.do_send(evt_1.clone()); @@ -401,10 +401,10 @@ mod tests { P2p::spawn_and_listen(bus.clone(), tx.clone(), rx); // Capture messages from output on msgs vec - let event = EnclaveEvent::from(CommitteeRequested { + let event = EnclaveEvent::from(E3Requested { e3_id: E3id::new("1235"), - nodecount: 3, - sortition_seed: 123, + threshold_m: 3, + seed: 123, moduli: vec![0x3FFFFFFF000001], degree: 2048, plaintext_modulus: 1032193, diff --git a/packages/ciphernode/core/src/plaintext_aggregator.rs b/packages/ciphernode/core/src/plaintext_aggregator.rs index 618e2088..cb868ce4 100644 --- a/packages/ciphernode/core/src/plaintext_aggregator.rs +++ b/packages/ciphernode/core/src/plaintext_aggregator.rs @@ -8,7 +8,7 @@ use anyhow::{anyhow, Result}; #[derive(Debug, Clone)] pub enum PlaintextAggregatorState { Collecting { - nodecount: usize, + threshold_m: u32, shares: OrderedSet>, seed: u64, }, @@ -41,7 +41,7 @@ impl PlaintextAggregator { bus: Addr, sortition: Addr, e3_id: E3id, - nodecount: usize, + threshold_m: u32, seed: u64, ) -> Self { PlaintextAggregator { @@ -50,7 +50,7 @@ impl PlaintextAggregator { sortition, e3_id, state: PlaintextAggregatorState::Collecting { - nodecount, + threshold_m, shares: OrderedSet::new(), seed, }, @@ -59,14 +59,16 @@ impl PlaintextAggregator { pub fn add_share(&mut self, share: Vec) -> Result { let PlaintextAggregatorState::Collecting { - nodecount, shares, .. + threshold_m, + shares, + .. } = &mut self.state else { return Err(anyhow::anyhow!("Can only add share in Collecting state")); }; shares.insert(share); - if shares.len() == *nodecount { + if shares.len() == *threshold_m as usize { return Ok(PlaintextAggregatorState::Computing { shares: shares.clone(), }); @@ -104,14 +106,14 @@ impl Handler for PlaintextAggregator { fn handle(&mut self, event: DecryptionshareCreated, _: &mut Self::Context) -> Self::Result { let PlaintextAggregatorState::Collecting { - nodecount, seed, .. + threshold_m, seed, .. } = self.state else { println!("Aggregator has been closed for collecting."); return Box::pin(fut::ready(Ok(()))); }; - let size = nodecount; + let size = threshold_m as usize; let address = event.node; let e3_id = event.e3_id.clone(); let decryption_share = event.decryption_share.clone(); @@ -199,7 +201,7 @@ impl PlaintextAggregatorFactory { bus.clone(), sortition.clone(), data.e3_id, - meta.nodecount, + meta.threshold_m, meta.seed, ) .start(), diff --git a/packages/ciphernode/core/src/publickey_aggregator.rs b/packages/ciphernode/core/src/publickey_aggregator.rs index 2b09ae85..b98dd847 100644 --- a/packages/ciphernode/core/src/publickey_aggregator.rs +++ b/packages/ciphernode/core/src/publickey_aggregator.rs @@ -11,7 +11,7 @@ use anyhow::Result; #[derive(Debug, Clone)] pub enum PublicKeyAggregatorState { Collecting { - nodecount: usize, + threshold_m: u32, keyshares: OrderedSet>, seed: u64, }, @@ -50,7 +50,7 @@ impl PublicKeyAggregator { bus: Addr, sortition: Addr, e3_id: E3id, - nodecount: usize, + threshold_m: u32, seed: u64, ) -> Self { PublicKeyAggregator { @@ -59,7 +59,7 @@ impl PublicKeyAggregator { e3_id, sortition, state: PublicKeyAggregatorState::Collecting { - nodecount, + threshold_m, keyshares: OrderedSet::new(), seed, }, @@ -68,7 +68,7 @@ impl PublicKeyAggregator { pub fn add_keyshare(&mut self, keyshare: Vec) -> Result { let PublicKeyAggregatorState::Collecting { - nodecount, + threshold_m, keyshares, .. } = &mut self.state @@ -77,7 +77,7 @@ impl PublicKeyAggregator { }; keyshares.insert(keyshare); - if keyshares.len() == *nodecount { + if keyshares.len() == *threshold_m as usize { return Ok(PublicKeyAggregatorState::Computing { keyshares: keyshares.clone(), }); @@ -118,7 +118,7 @@ impl Handler for PublicKeyAggregator { fn handle(&mut self, event: KeyshareCreated, _: &mut Self::Context) -> Self::Result { let PublicKeyAggregatorState::Collecting { - nodecount, seed, .. + threshold_m, seed, .. } = self.state.clone() else { println!("Aggregator has been closed for collecting keyshares."); // TODO: log properly @@ -126,7 +126,7 @@ impl Handler for PublicKeyAggregator { return Box::pin(fut::ready(Ok(()))); }; - let size = nodecount; + let size = threshold_m as usize; let address = event.node; let e3_id = event.e3_id.clone(); let pubkey = event.pubkey.clone(); @@ -212,8 +212,8 @@ pub struct PublicKeyAggregatorFactory; impl PublicKeyAggregatorFactory { pub fn create(bus: Addr, sortition: Addr) -> ActorFactory { Box::new(move |ctx, evt| { - // Saving the publickey aggregator with deps on CommitteeRequested - let EnclaveEvent::CommitteeRequested { data, .. } = evt else { + // Saving the publickey aggregator with deps on E3Requested + let EnclaveEvent::E3Requested { data, .. } = evt else { return; }; @@ -230,7 +230,7 @@ impl PublicKeyAggregatorFactory { bus.clone(), sortition.clone(), data.e3_id, - meta.nodecount, + meta.threshold_m, meta.seed, ) .start(), diff --git a/packages/ciphernode/enclave_node/src/bin/cmd.rs b/packages/ciphernode/enclave_node/src/bin/cmd.rs index 4ab57431..d940afb9 100644 --- a/packages/ciphernode/enclave_node/src/bin/cmd.rs +++ b/packages/ciphernode/enclave_node/src/bin/cmd.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use alloy_primitives::{address, Address}; use base64::{engine::general_purpose, Engine as _}; use enclave_core::{ - setup_crp_params, Actor, CommitteeRequested, E3id, EnclaveEvent, EventBus, P2p, ParamsWithCrp, + setup_crp_params, Actor, E3Requested, E3id, EnclaveEvent, EventBus, P2p, ParamsWithCrp, SimpleLogger, }; use enclave_core::{CiphernodeAdded, CiphertextOutputPublished}; @@ -81,10 +81,10 @@ async fn main() -> Result<(), Box> { ["com"] => { id += 1; println!("Requesting comittee: {}", id); - bus.do_send(EnclaveEvent::from(CommitteeRequested { + bus.do_send(EnclaveEvent::from(E3Requested { e3_id: E3id::from(id), - nodecount: 3, - sortition_seed: thread_rng().next_u64(), + threshold_m: 3, + seed: thread_rng().next_u64(), moduli: moduli.clone(), plaintext_modulus, degree, From 2475c63e96534327278864d80dee06cf05e66c97 Mon Sep 17 00:00:00 2001 From: ryardley Date: Mon, 23 Sep 2024 22:13:57 +1000 Subject: [PATCH 06/35] Supply events to listen with --- packages/ciphernode/core/src/evm.rs | 77 +++++++++++++++++--- packages/ciphernode/core/src/evm_listener.rs | 16 +--- 2 files changed, 67 insertions(+), 26 deletions(-) diff --git a/packages/ciphernode/core/src/evm.rs b/packages/ciphernode/core/src/evm.rs index c5cfec36..d673aa42 100644 --- a/packages/ciphernode/core/src/evm.rs +++ b/packages/ciphernode/core/src/evm.rs @@ -7,7 +7,7 @@ use crate::{ setup_crp_params, EnclaveEvent, EventBus, ParamsWithCrp, }; use actix::{Actor, Addr, Context}; -use alloy::{primitives::Address, sol, sol_types::SolEvent}; +use alloy::{primitives::Address, sol}; use anyhow::Result; use rand::SeedableRng; use rand_chacha::ChaCha20Rng; @@ -72,7 +72,7 @@ impl From for events::E3Requested { degree, plaintext_modulus, crp_bytes, - params, + .. } = setup_crp_params( &[0x3FFFFFFF000001], 2048, @@ -86,20 +86,73 @@ impl From for events::E3Requested { threshold_m: value.e3.threshold[0], crp: crp_bytes, // HACK: Following should be [u8;32] and not converted to u64 - seed: value.e3.seed.as_limbs()[1], // converting to u64 + seed: value.e3.seed.as_limbs()[0], // converting to u64 e3_id: value.e3Id.to_string().into(), } } } -// impl From for events::CiphernodeAdded { -// fn from(value: CiphernodeAdded) -> Self { -// events::CiphernodeAdded { -// address: value.node.to_string(), -// index: value.index.as_limbs()[1] as usize, -// num_nodes: value.numNodes.as_limbs()[1] as usize, -// } -// } -// } + +impl From for events::CiphernodeAdded { + fn from(value: CiphernodeAdded) -> Self { + events::CiphernodeAdded { + address: value.node.to_string(), + index: value.index.as_limbs()[0] as usize, + num_nodes: value.numNodes.as_limbs()[0] as usize, + } + } +} + +impl From for events::CiphernodeRemoved { + fn from(value: CiphernodeRemoved) -> Self { + events::CiphernodeRemoved { + address: value.node.to_string(), + index: value.index.as_limbs()[0] as usize, + num_nodes: value.numNodes.as_limbs()[0] as usize, + } + } +} + +impl From for events::CiphertextOutputPublished { + fn from(value: CiphertextOutputPublished) -> Self { + events::CiphertextOutputPublished { + e3_id: value.e3Id.to_string().into(), + ciphertext_output: value.ciphertextOutput.to_vec(), + } + } +} + +impl ContractEvent for CiphernodeAdded { + fn process(&self, bus: Addr) -> Result<()> { + let data: events::CiphernodeAdded = self.clone().into(); + bus.do_send(EnclaveEvent::from(data)); + Ok(()) + } +} + +impl ContractEvent for E3Requested { + fn process(&self, bus: Addr) -> Result<()> { + let data: events::E3Requested = self.clone().into(); + bus.do_send(EnclaveEvent::from(data)); + Ok(()) + } +} + +impl ContractEvent for CiphernodeRemoved { + fn process(&self, bus: Addr) -> Result<()> { + let data: events::CiphernodeRemoved = self.clone().into(); + bus.do_send(EnclaveEvent::from(data)); + Ok(()) + } +} + +impl ContractEvent for CiphertextOutputPublished { + fn process(&self, bus: Addr) -> Result<()> { + let data: events::CiphertextOutputPublished = self.clone().into(); + bus.do_send(EnclaveEvent::from(data)); + Ok(()) + } +} + struct Evm { // holding refs to evm contracts for management evm_manager: Addr, diff --git a/packages/ciphernode/core/src/evm_listener.rs b/packages/ciphernode/core/src/evm_listener.rs index 042c6a1c..7fd8cef1 100644 --- a/packages/ciphernode/core/src/evm_listener.rs +++ b/packages/ciphernode/core/src/evm_listener.rs @@ -9,27 +9,15 @@ use alloy::{ use anyhow::Result; use futures_util::stream::StreamExt; use std::collections::HashMap; -use std::fmt::Debug; -use std::sync::Arc; use std::marker::PhantomData; +use std::sync::Arc; -use crate::{EnclaveEvent, EventBus}; +use crate::EventBus; pub trait ContractEvent: Send + Sync + 'static { fn process(&self, bus: Addr) -> Result<()>; } -impl ContractEvent for T -where - T: SolEvent + Debug + Send + Sync + 'static, -{ - fn process(&self, bus: Addr) -> Result<()> { - println!("Processing event: {:?}", self); - // bus.do_send(EnclaveEvent::from(self)); - Ok(()) - } -} - pub struct EvmEventListener { provider: Arc>, filter: Filter, From 6e0874f697efe6e77e10203663068870fc48e338 Mon Sep 17 00:00:00 2001 From: ryardley Date: Mon, 23 Sep 2024 22:15:37 +1000 Subject: [PATCH 07/35] Use shortcut --- packages/ciphernode/core/src/committee_meta.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ciphernode/core/src/committee_meta.rs b/packages/ciphernode/core/src/committee_meta.rs index b910118e..7748bb48 100644 --- a/packages/ciphernode/core/src/committee_meta.rs +++ b/packages/ciphernode/core/src/committee_meta.rs @@ -16,7 +16,7 @@ impl CommitteeMetaFactory { }; let E3Requested { threshold_m, - seed: seed, + seed, .. } = data; From abe4c7dc2f2ba9fca82f32668819ccf096739528 Mon Sep 17 00:00:00 2001 From: ryardley Date: Tue, 24 Sep 2024 15:46:38 +1000 Subject: [PATCH 08/35] Update for e2e test --- TEST_CASE.md | 54 ++++++++ package.json | 5 + packages/ciphernode/Cargo.lock | 2 +- ...node_selector.rs => cipernode_selector.rs} | 0 .../core/src/evm_ciphernode_registry.rs | 90 ++++++++++++ .../core/src/{evm.rs => evm_enclave.rs} | 128 ++++-------------- packages/ciphernode/core/src/evm_listener.rs | 1 + packages/ciphernode/core/src/lib.rs | 9 +- .../ciphernode/core/src/main_aggregator.rs | 10 +- .../ciphernode/core/src/main_ciphernode.rs | 12 +- packages/ciphernode/enclave_node/Cargo.toml | 2 +- .../enclave_node/src/bin/aggregator.rs | 13 +- .../ciphernode/enclave_node/src/bin/node.rs | 17 ++- packages/ciphernode/scripts/aggregator.sh | 3 + packages/ciphernode/scripts/launch.sh | 3 + scripts/ciphernode_launch.sh | 4 + 16 files changed, 227 insertions(+), 126 deletions(-) create mode 100644 TEST_CASE.md rename packages/ciphernode/core/src/{ciphernode_selector.rs => cipernode_selector.rs} (100%) create mode 100644 packages/ciphernode/core/src/evm_ciphernode_registry.rs rename packages/ciphernode/core/src/{evm.rs => evm_enclave.rs} (50%) create mode 100755 packages/ciphernode/scripts/aggregator.sh create mode 100755 packages/ciphernode/scripts/launch.sh create mode 100755 scripts/ciphernode_launch.sh diff --git a/TEST_CASE.md b/TEST_CASE.md new file mode 100644 index 00000000..599c5f6a --- /dev/null +++ b/TEST_CASE.md @@ -0,0 +1,54 @@ + +1. Launch evm node + +``` +yarn evm:node +``` + +2. Launch 3 ciphernodes + +``` +yarn ciphernode:launch --address 0x2546BcD3c84621e976D8185a91A922aE77ECEc30 --rpc "ws://localhost:8545" --enclave-contract 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0 --registry-contract 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 +``` + +``` +yarn ciphernode:launch --address 0xbDA5747bFD65F08deb54cb465eB87D40e51B197E --rpc "ws://localhost:8545" --enclave-contract 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0 --registry-contract 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 +``` + +``` +yarn ciphernode:launch --address 0xdD2FD4581271e230360230F9337D5c0430Bf44C0 --rpc "ws://localhost:8545" --enclave-contract 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0 --registry-contract 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 +``` + +``` +yarn ciphernode:launch --address 0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199 --rpc "ws://localhost:8545" --enclave-contract 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0 --registry-contract 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 +``` + +3. Launch an Aggregator + +``` +yarn ciphernode:aggregator --rpc "ws://localhost:8545" --registry-contract 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 +``` + +4. Register nodes + +``` +yarn ciphernode:add --ciphernode-address 0x2546BcD3c84621e976D8185a91A922aE77ECEc30 --network localhost +``` + +``` +yarn ciphernode:add --ciphernode-address 0xbDA5747bFD65F08deb54cb465eB87D40e51B197E --network localhost +``` + +``` +yarn ciphernode:add --ciphernode-address 0xdD2FD4581271e230360230F9337D5c0430Bf44C0 --network localhost +``` + +``` +yarn ciphernode:add --ciphernode-address 0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199 --network localhost +``` + +5. Request Computation (WIP) + +``` + +``` diff --git a/package.json b/package.json index 69448f37..507eb06a 100644 --- a/package.json +++ b/package.json @@ -14,9 +14,14 @@ "typechain": "yarn evm:typechain", "test": "yarn evm:test && yarn ciphernode:test", "coverage": "yarn evm:coverage", + "ciphernode:launch": "cd packages/ciphernode && ./scripts/launch.sh", + "ciphernode:add": "cd packages/evm && yarn ciphernode:add", + "ciphernode:remove": "cd packages/evm && yarn ciphernode:remove", + "ciphernode:aggregator": "cd packages/ciphernode && ./scripts/aggregator.sh", "ciphernode:test": "cd packages/ciphernode && cargo test", "ciphernode:build": "cd packages/ciphernode && cargo build --release", "evm:install": "cd packages/evm && yarn install", + "evm:node": "cd packages/evm && yarn hardhat node", "evm:compile": "cd packages/evm && yarn compile", "evm:lint": "cd packages/evm && yarn lint", "evm:typechain": "cd packages/evm && yarn typechain", diff --git a/packages/ciphernode/Cargo.lock b/packages/ciphernode/Cargo.lock index ded3b907..a8129f0a 100644 --- a/packages/ciphernode/Cargo.lock +++ b/packages/ciphernode/Cargo.lock @@ -2571,7 +2571,7 @@ name = "enclave_node" version = "0.1.0" dependencies = [ "actix-rt", - "alloy 0.2.1", + "alloy 0.3.3", "alloy-primitives 0.6.4", "async-std", "base64 0.22.1", diff --git a/packages/ciphernode/core/src/ciphernode_selector.rs b/packages/ciphernode/core/src/cipernode_selector.rs similarity index 100% rename from packages/ciphernode/core/src/ciphernode_selector.rs rename to packages/ciphernode/core/src/cipernode_selector.rs diff --git a/packages/ciphernode/core/src/evm_ciphernode_registry.rs b/packages/ciphernode/core/src/evm_ciphernode_registry.rs new file mode 100644 index 00000000..ea14bd55 --- /dev/null +++ b/packages/ciphernode/core/src/evm_ciphernode_registry.rs @@ -0,0 +1,90 @@ +use crate::{ + events, + evm_listener::{AddEventHandler, ContractEvent, StartListening}, + evm_manager::{AddListener, EvmContractManager}, + EnclaveEvent, EventBus, +}; +use actix::Addr; +use alloy::{primitives::Address, sol}; +use anyhow::Result; + +sol! { + #[derive(Debug)] + event CiphernodeAdded( + address indexed node, + uint256 index, + uint256 numNodes, + uint256 size + ); + + #[derive(Debug)] + event CiphernodeRemoved( + address indexed node, + uint256 index, + uint256 numNodes, + uint256 size + ); +} + +impl From for events::CiphernodeAdded { + fn from(value: CiphernodeAdded) -> Self { + events::CiphernodeAdded { + address: value.node.to_string(), + index: value.index.as_limbs()[0] as usize, + num_nodes: value.numNodes.as_limbs()[0] as usize, + } + } +} + +impl From for events::CiphernodeRemoved { + fn from(value: CiphernodeRemoved) -> Self { + events::CiphernodeRemoved { + address: value.node.to_string(), + index: value.index.as_limbs()[0] as usize, + num_nodes: value.numNodes.as_limbs()[0] as usize, + } + } +} + +impl ContractEvent for CiphernodeAdded { + fn process(&self, bus: Addr) -> Result<()> { + println!("Ciphernode Added: {:?}", self); + let data: events::CiphernodeAdded = self.clone().into(); + bus.do_send(EnclaveEvent::from(data)); + Ok(()) + } +} + +impl ContractEvent for CiphernodeRemoved { + fn process(&self, bus: Addr) -> Result<()> { + let data: events::CiphernodeRemoved = self.clone().into(); + bus.do_send(EnclaveEvent::from(data)); + Ok(()) + } +} + +pub async fn connect_evm_ciphernode_registry( + bus: Addr, + rpc_url: &str, + contract_address: Address, +) { + let evm_manager = EvmContractManager::attach(bus.clone(), rpc_url).await; + let evm_listener = evm_manager + .send(AddListener { contract_address }) + .await + .unwrap(); + + evm_listener + .send(AddEventHandler::::new()) + .await + .unwrap(); + + evm_listener + .send(AddEventHandler::::new()) + .await + .unwrap(); + + evm_listener.do_send(StartListening); + + println!("Evm is listening......."); +} diff --git a/packages/ciphernode/core/src/evm.rs b/packages/ciphernode/core/src/evm_enclave.rs similarity index 50% rename from packages/ciphernode/core/src/evm.rs rename to packages/ciphernode/core/src/evm_enclave.rs index d673aa42..4f95967a 100644 --- a/packages/ciphernode/core/src/evm.rs +++ b/packages/ciphernode/core/src/evm_enclave.rs @@ -2,11 +2,11 @@ use std::sync::Arc; use crate::{ events, - evm_listener::{AddEventHandler, ContractEvent, EvmEventListener, StartListening}, + evm_listener::{AddEventHandler, ContractEvent, StartListening}, evm_manager::{AddListener, EvmContractManager}, setup_crp_params, EnclaveEvent, EventBus, ParamsWithCrp, }; -use actix::{Actor, Addr, Context}; +use actix::Addr; use alloy::{primitives::Address, sol}; use anyhow::Result; use rand::SeedableRng; @@ -29,22 +29,6 @@ sol! { bytes plaintextOutput; } - #[derive(Debug)] - event CiphernodeAdded( - address indexed node, - uint256 index, - uint256 numNodes, - uint256 size - ); - - #[derive(Debug)] - event CiphernodeRemoved( - address indexed node, - uint256 index, - uint256 numNodes, - uint256 size - ); - #[derive(Debug)] event CiphertextOutputPublished( uint256 indexed e3Id, @@ -92,26 +76,6 @@ impl From for events::E3Requested { } } -impl From for events::CiphernodeAdded { - fn from(value: CiphernodeAdded) -> Self { - events::CiphernodeAdded { - address: value.node.to_string(), - index: value.index.as_limbs()[0] as usize, - num_nodes: value.numNodes.as_limbs()[0] as usize, - } - } -} - -impl From for events::CiphernodeRemoved { - fn from(value: CiphernodeRemoved) -> Self { - events::CiphernodeRemoved { - address: value.node.to_string(), - index: value.index.as_limbs()[0] as usize, - num_nodes: value.numNodes.as_limbs()[0] as usize, - } - } -} - impl From for events::CiphertextOutputPublished { fn from(value: CiphertextOutputPublished) -> Self { events::CiphertextOutputPublished { @@ -121,14 +85,6 @@ impl From for events::CiphertextOutputPublished { } } -impl ContractEvent for CiphernodeAdded { - fn process(&self, bus: Addr) -> Result<()> { - let data: events::CiphernodeAdded = self.clone().into(); - bus.do_send(EnclaveEvent::from(data)); - Ok(()) - } -} - impl ContractEvent for E3Requested { fn process(&self, bus: Addr) -> Result<()> { let data: events::E3Requested = self.clone().into(); @@ -137,14 +93,6 @@ impl ContractEvent for E3Requested { } } -impl ContractEvent for CiphernodeRemoved { - fn process(&self, bus: Addr) -> Result<()> { - let data: events::CiphernodeRemoved = self.clone().into(); - bus.do_send(EnclaveEvent::from(data)); - Ok(()) - } -} - impl ContractEvent for CiphertextOutputPublished { fn process(&self, bus: Addr) -> Result<()> { let data: events::CiphertextOutputPublished = self.clone().into(); @@ -153,53 +101,27 @@ impl ContractEvent for CiphertextOutputPublished { } } -struct Evm { - // holding refs to evm contracts for management - evm_manager: Addr, - evm_listener: Addr, -} - -impl Evm { - pub async fn attach( - bus: Addr, - rpc_url: &str, - contract_address: Address, - ) -> Addr { - let evm_manager = EvmContractManager::attach(bus.clone(), rpc_url).await; - let evm_listener = evm_manager - .send(AddListener { contract_address }) - .await - .unwrap(); - - evm_listener - .send(AddEventHandler::::new()) - .await - .unwrap(); - - evm_listener - .send(AddEventHandler::::new()) - .await - .unwrap(); - - evm_listener - .send(AddEventHandler::::new()) - .await - .unwrap(); - - evm_listener - .send(AddEventHandler::::new()) - .await - .unwrap(); - evm_listener.do_send(StartListening); - - Evm { - evm_listener, - evm_manager, - } - .start() - } -} - -impl Actor for Evm { - type Context = Context; +pub async fn connect_evm_enclave( + bus: Addr, + rpc_url: &str, + contract_address: Address, +) { + let evm_manager = EvmContractManager::attach(bus.clone(), rpc_url).await; + let evm_listener = evm_manager + .send(AddListener { contract_address }) + .await + .unwrap(); + + evm_listener + .send(AddEventHandler::::new()) + .await + .unwrap(); + + evm_listener + .send(AddEventHandler::::new()) + .await + .unwrap(); + evm_listener.do_send(StartListening); + + println!("Evm is listening......."); } diff --git a/packages/ciphernode/core/src/evm_listener.rs b/packages/ciphernode/core/src/evm_listener.rs index 7fd8cef1..e0795326 100644 --- a/packages/ciphernode/core/src/evm_listener.rs +++ b/packages/ciphernode/core/src/evm_listener.rs @@ -59,6 +59,7 @@ impl EvmEventListener { .await? .into_stream(); while let Some(log) = stream.next().await { + println!("received log!"); if let Some(topic0) = log.topic0() { if let Some(decoder) = self.handlers.get(topic0) { if let Ok(event) = decoder(log.clone()) { diff --git a/packages/ciphernode/core/src/lib.rs b/packages/ciphernode/core/src/lib.rs index 9c834579..81610e31 100644 --- a/packages/ciphernode/core/src/lib.rs +++ b/packages/ciphernode/core/src/lib.rs @@ -3,13 +3,13 @@ // #![warn(missing_docs, unused_imports)] mod ciphernode; -mod ciphernode_selector; +mod cipernode_selector; mod committee_meta; mod data; mod e3_request; mod eventbus; pub mod events; -mod evm; +mod evm_ciphernode_registry; mod evm_listener; mod evm_manager; mod fhe; @@ -23,11 +23,12 @@ mod publickey_aggregator; mod serializers; mod sortition; mod utils; +mod evm_enclave; // TODO: this is too permissive pub use actix::prelude::*; pub use ciphernode::*; -pub use ciphernode_selector::*; +pub use cipernode_selector::*; pub use committee_meta::*; pub use data::*; pub use e3_request::*; @@ -48,7 +49,7 @@ pub use utils::*; #[cfg(test)] mod tests { use crate::{ - ciphernode_selector::CiphernodeSelector, + cipernode_selector::CiphernodeSelector, data::Data, eventbus::{EventBus, GetHistory}, events::{E3Requested, E3id, EnclaveEvent, KeyshareCreated, PublicKeyAggregated}, diff --git a/packages/ciphernode/core/src/main_aggregator.rs b/packages/ciphernode/core/src/main_aggregator.rs index faf4ecb8..87da2ec7 100644 --- a/packages/ciphernode/core/src/main_aggregator.rs +++ b/packages/ciphernode/core/src/main_aggregator.rs @@ -1,10 +1,12 @@ use std::sync::{Arc, Mutex}; use crate::{ - committee_meta::CommitteeMetaFactory, E3RequestManager, EventBus, FheFactory, P2p, - PlaintextAggregatorFactory, PublicKeyAggregatorFactory, SimpleLogger, Sortition, + committee_meta::CommitteeMetaFactory, evm_ciphernode_registry::connect_evm_ciphernode_registry, + E3RequestManager, EventBus, FheFactory, P2p, PlaintextAggregatorFactory, + PublicKeyAggregatorFactory, SimpleLogger, Sortition, }; use actix::{Actor, Addr, Context}; +use alloy::primitives::Address; use rand::SeedableRng; use rand_chacha::rand_core::OsRng; use tokio::task::JoinHandle; @@ -34,13 +36,15 @@ impl MainAggregator { } } - pub async fn attach() -> (Addr, JoinHandle<()>) { + pub async fn attach(rpc_url: &str, contract_address: Address) -> (Addr, JoinHandle<()>) { let rng = Arc::new(Mutex::new( rand_chacha::ChaCha20Rng::from_rng(OsRng).expect("Failed to create RNG"), )); let bus = EventBus::new(true).start(); let sortition = Sortition::attach(bus.clone()); + connect_evm_ciphernode_registry(bus.clone(), rpc_url, contract_address).await; + let e3_manager = E3RequestManager::builder(bus.clone()) .add_hook(CommitteeMetaFactory::create()) .add_hook(FheFactory::create(rng.clone())) diff --git a/packages/ciphernode/core/src/main_ciphernode.rs b/packages/ciphernode/core/src/main_ciphernode.rs index 5f22e388..9a14074d 100644 --- a/packages/ciphernode/core/src/main_ciphernode.rs +++ b/packages/ciphernode/core/src/main_ciphernode.rs @@ -1,10 +1,10 @@ use std::sync::{Arc, Mutex}; use crate::{ - CiphernodeFactory, CiphernodeSelector, CommitteeMetaFactory, Data, E3RequestManager, EventBus, FheFactory, P2p, SimpleLogger, Sortition + evm_ciphernode_registry::connect_evm_ciphernode_registry, evm_enclave::connect_evm_enclave, CiphernodeFactory, CiphernodeSelector, CommitteeMetaFactory, Data, E3RequestManager, EventBus, FheFactory, P2p, SimpleLogger, Sortition }; use actix::{Actor, Addr, Context}; -use alloy_primitives::Address; +use alloy::primitives::Address; use rand::SeedableRng; use rand_chacha::rand_core::OsRng; use tokio::task::JoinHandle; @@ -45,8 +45,9 @@ impl MainCiphernode { pub async fn attach( address: Address, - // rpc_url: String, - // contract_address: Address, + rpc_url: &str, + enclave_contract: Address, + registry_contract: Address ) -> (Addr, JoinHandle<()>) { let rng = Arc::new(Mutex::new( rand_chacha::ChaCha20Rng::from_rng(OsRng).expect("Failed to create RNG"), @@ -57,6 +58,9 @@ impl MainCiphernode { let selector = CiphernodeSelector::attach(bus.clone(), sortition.clone(), &address.to_string()); + connect_evm_enclave(bus.clone(), rpc_url, enclave_contract).await; + connect_evm_ciphernode_registry(bus.clone(), rpc_url, registry_contract).await; + let e3_manager = E3RequestManager::builder(bus.clone()) .add_hook(CommitteeMetaFactory::create()) .add_hook(FheFactory::create(rng.clone())) diff --git a/packages/ciphernode/enclave_node/Cargo.toml b/packages/ciphernode/enclave_node/Cargo.toml index 7841aa31..4fabfe41 100644 --- a/packages/ciphernode/enclave_node/Cargo.toml +++ b/packages/ciphernode/enclave_node/Cargo.toml @@ -20,7 +20,7 @@ tokio = { version = "1.38", features = ["full"] } actix-rt = "2.10.0" alloy-primitives = { version = "0.6", default-features = false, features = ["rlp", "serde", "std"] } -alloy = { version = "0.2.1", features = ["full"] } +alloy = { version = "0.3.3", features = ["full"] } clap = { version = "4.5.17", features = ["derive"] } rand_chacha = "0.3.1" rand = "0.8.5" diff --git a/packages/ciphernode/enclave_node/src/bin/aggregator.rs b/packages/ciphernode/enclave_node/src/bin/aggregator.rs index 8ae7e2a5..43874cba 100644 --- a/packages/ciphernode/enclave_node/src/bin/aggregator.rs +++ b/packages/ciphernode/enclave_node/src/bin/aggregator.rs @@ -1,16 +1,23 @@ +use alloy::primitives::Address; use clap::Parser; use enclave_core::MainAggregator; #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] struct Args { - #[arg(short, long)] - address: String, + #[arg(short='n', long)] + rpc: String, + #[arg(short, long="registry-contract")] + registry_contract: String } #[actix_rt::main] async fn main() -> Result<(), Box> { - let (_, handle) = MainAggregator::attach().await; + let args = Args::parse(); + println!("LAUNCHING AGGREGATOR"); + let registry_contract = + Address::parse_checksummed(&args.registry_contract, None).expect("Invalid address"); + let (_, handle) = MainAggregator::attach(&args.rpc, registry_contract).await; let _ = tokio::join!(handle); Ok(()) } diff --git a/packages/ciphernode/enclave_node/src/bin/node.rs b/packages/ciphernode/enclave_node/src/bin/node.rs index 67908f96..ceddcf85 100644 --- a/packages/ciphernode/enclave_node/src/bin/node.rs +++ b/packages/ciphernode/enclave_node/src/bin/node.rs @@ -1,4 +1,4 @@ -use alloy_primitives::Address; +use alloy::primitives::Address; use clap::Parser; use enclave_core::MainCiphernode; @@ -7,10 +7,12 @@ use enclave_core::MainCiphernode; struct Args { #[arg(short, long)] address: String, - // #[arg(short, long)] - // rpc: String, - // #[arg(short, long)] - // contract_address: String, + #[arg(short='n', long)] + rpc: String, + #[arg(short, long="enclave-contract")] + enclave_contract: String, + #[arg(short, long="registry-contract")] + registry_contract: String } #[actix_rt::main] @@ -18,8 +20,9 @@ async fn main() -> Result<(), Box> { let args = Args::parse(); let address = Address::parse_checksummed(&args.address, None).expect("Invalid address"); println!("LAUNCHING CIPHERNODE: ({})", address); - // let contract_address = Address::parse_checksummed(&args.contract_address, None).expect("Invalid address"); - let (_, handle) = MainCiphernode::attach(address /*args.rpc, contract_address*/).await; + let registry_contract = Address::parse_checksummed(&args.registry_contract, None).expect("Invalid address"); + let enclave_contract = Address::parse_checksummed(&args.enclave_contract, None).expect("Invalid address"); + let (_, handle) = MainCiphernode::attach(address, &args.rpc, enclave_contract, registry_contract).await; let _ = tokio::join!(handle); Ok(()) } diff --git a/packages/ciphernode/scripts/aggregator.sh b/packages/ciphernode/scripts/aggregator.sh new file mode 100755 index 00000000..f839bf27 --- /dev/null +++ b/packages/ciphernode/scripts/aggregator.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +RUSTFLAGS="-A warnings" cargo run --bin aggregator -- $@ diff --git a/packages/ciphernode/scripts/launch.sh b/packages/ciphernode/scripts/launch.sh new file mode 100755 index 00000000..51adac41 --- /dev/null +++ b/packages/ciphernode/scripts/launch.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +RUSTFLAGS="-A warnings" cargo run --bin node -- $@ diff --git a/scripts/ciphernode_launch.sh b/scripts/ciphernode_launch.sh new file mode 100755 index 00000000..2b963f77 --- /dev/null +++ b/scripts/ciphernode_launch.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +pushd packages/ciphernode && yarn ciphernode:add --ciphernode-address $1 +pushd packages/evm && ./scripts/launch.sh --address $1 From 1af271a18f5cdc7d277b57f44b04421eb3ff3b31 Mon Sep 17 00:00:00 2001 From: ryardley Date: Tue, 24 Sep 2024 22:39:21 +1000 Subject: [PATCH 09/35] e2e test sharing keys and saving --- TEST_CASE.md | 54 ------------------- packages/ciphernode/core/src/ciphernode.rs | 2 - packages/ciphernode/core/src/events.rs | 3 ++ .../core/src/evm_ciphernode_registry.rs | 2 +- packages/ciphernode/core/src/evm_enclave.rs | 20 +++---- packages/ciphernode/core/src/evm_listener.rs | 2 - packages/ciphernode/core/src/lib.rs | 39 ++++++-------- packages/ciphernode/core/src/logger.rs | 9 ++-- .../ciphernode/core/src/main_aggregator.rs | 26 ++++++--- .../ciphernode/core/src/main_ciphernode.rs | 9 ++-- .../ciphernode/core/src/public_key_writer.rs | 46 ++++++++++++++++ .../core/src/publickey_aggregator.rs | 3 +- packages/ciphernode/core/src/sortition.rs | 1 + .../enclave_node/src/bin/aggregator.rs | 20 +++++-- packages/evm/contracts/Enclave.sol | 5 +- packages/evm/deploy/mocks.ts | 25 ++++++++- scripts/ciphernode_launch.sh | 4 -- scripts/test.sh | 52 ++++++++++++++++++ 18 files changed, 206 insertions(+), 116 deletions(-) delete mode 100644 TEST_CASE.md create mode 100644 packages/ciphernode/core/src/public_key_writer.rs delete mode 100755 scripts/ciphernode_launch.sh create mode 100755 scripts/test.sh diff --git a/TEST_CASE.md b/TEST_CASE.md deleted file mode 100644 index 599c5f6a..00000000 --- a/TEST_CASE.md +++ /dev/null @@ -1,54 +0,0 @@ - -1. Launch evm node - -``` -yarn evm:node -``` - -2. Launch 3 ciphernodes - -``` -yarn ciphernode:launch --address 0x2546BcD3c84621e976D8185a91A922aE77ECEc30 --rpc "ws://localhost:8545" --enclave-contract 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0 --registry-contract 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 -``` - -``` -yarn ciphernode:launch --address 0xbDA5747bFD65F08deb54cb465eB87D40e51B197E --rpc "ws://localhost:8545" --enclave-contract 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0 --registry-contract 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 -``` - -``` -yarn ciphernode:launch --address 0xdD2FD4581271e230360230F9337D5c0430Bf44C0 --rpc "ws://localhost:8545" --enclave-contract 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0 --registry-contract 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 -``` - -``` -yarn ciphernode:launch --address 0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199 --rpc "ws://localhost:8545" --enclave-contract 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0 --registry-contract 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 -``` - -3. Launch an Aggregator - -``` -yarn ciphernode:aggregator --rpc "ws://localhost:8545" --registry-contract 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 -``` - -4. Register nodes - -``` -yarn ciphernode:add --ciphernode-address 0x2546BcD3c84621e976D8185a91A922aE77ECEc30 --network localhost -``` - -``` -yarn ciphernode:add --ciphernode-address 0xbDA5747bFD65F08deb54cb465eB87D40e51B197E --network localhost -``` - -``` -yarn ciphernode:add --ciphernode-address 0xdD2FD4581271e230360230F9337D5c0430Bf44C0 --network localhost -``` - -``` -yarn ciphernode:add --ciphernode-address 0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199 --network localhost -``` - -5. Request Computation (WIP) - -``` - -``` diff --git a/packages/ciphernode/core/src/ciphernode.rs b/packages/ciphernode/core/src/ciphernode.rs index fa92ef0f..002bb3df 100644 --- a/packages/ciphernode/core/src/ciphernode.rs +++ b/packages/ciphernode/core/src/ciphernode.rs @@ -85,8 +85,6 @@ async fn on_ciphernode_selected( ) -> Result<()> { let CiphernodeSelected { e3_id, .. } = event; - println!("\n\nGENERATING KEY!\n\n"); - // generate keyshare let (sk, pubkey) = fhe.send(GenerateKeyshare {}).await??; diff --git a/packages/ciphernode/core/src/events.rs b/packages/ciphernode/core/src/events.rs index 73c498df..7edc206b 100644 --- a/packages/ciphernode/core/src/events.rs +++ b/packages/ciphernode/core/src/events.rs @@ -115,6 +115,9 @@ impl EnclaveEvent { // Add a list of local events match self { EnclaveEvent::CiphernodeSelected { .. } => true, + EnclaveEvent::E3Requested { .. } => true, + EnclaveEvent::CiphernodeAdded { .. } => true, + EnclaveEvent::CiphernodeRemoved { .. } => true, _ => false, } } diff --git a/packages/ciphernode/core/src/evm_ciphernode_registry.rs b/packages/ciphernode/core/src/evm_ciphernode_registry.rs index ea14bd55..a1484d33 100644 --- a/packages/ciphernode/core/src/evm_ciphernode_registry.rs +++ b/packages/ciphernode/core/src/evm_ciphernode_registry.rs @@ -86,5 +86,5 @@ pub async fn connect_evm_ciphernode_registry( evm_listener.do_send(StartListening); - println!("Evm is listening......."); + println!("Evm is listening to {}", contract_address); } diff --git a/packages/ciphernode/core/src/evm_enclave.rs b/packages/ciphernode/core/src/evm_enclave.rs index 4f95967a..e032ab0d 100644 --- a/packages/ciphernode/core/src/evm_enclave.rs +++ b/packages/ciphernode/core/src/evm_enclave.rs @@ -7,7 +7,7 @@ use crate::{ setup_crp_params, EnclaveEvent, EventBus, ParamsWithCrp, }; use actix::Addr; -use alloy::{primitives::Address, sol}; +use alloy::{primitives::Address, sol, sol_types::SolEvent}; use anyhow::Result; use rand::SeedableRng; use rand_chacha::ChaCha20Rng; @@ -20,13 +20,14 @@ sol! { uint256[2] startWindow; uint256 duration; uint256 expiration; + bytes32 encryptionSchemeId; address e3Program; bytes e3ProgramParams; address inputValidator; address decryptionVerifier; bytes committeePublicKey; - bytes ciphertextOutput; - bytes plaintextOutput; + bytes32 ciphertextOutput; + bytes32 plaintextOutput; } #[derive(Debug)] @@ -46,6 +47,11 @@ sol! { impl From for events::E3Requested { fn from(value: E3Requested) -> Self { + println!( + "===========================\n\nE3Request\n\n===============\n{:?}", + value + ); + let _params_bytes = value.e3.e3ProgramParams; // TODO: decode params bytes // HACK: temp supply canned params: @@ -101,11 +107,7 @@ impl ContractEvent for CiphertextOutputPublished { } } -pub async fn connect_evm_enclave( - bus: Addr, - rpc_url: &str, - contract_address: Address, -) { +pub async fn connect_evm_enclave(bus: Addr, rpc_url: &str, contract_address: Address) { let evm_manager = EvmContractManager::attach(bus.clone(), rpc_url).await; let evm_listener = evm_manager .send(AddListener { contract_address }) @@ -123,5 +125,5 @@ pub async fn connect_evm_enclave( .unwrap(); evm_listener.do_send(StartListening); - println!("Evm is listening......."); + println!("Evm is listening to {}", contract_address); } diff --git a/packages/ciphernode/core/src/evm_listener.rs b/packages/ciphernode/core/src/evm_listener.rs index e0795326..7a631ebc 100644 --- a/packages/ciphernode/core/src/evm_listener.rs +++ b/packages/ciphernode/core/src/evm_listener.rs @@ -48,7 +48,6 @@ impl EvmEventListener { let event = log.log_decode::()?.inner.data; Ok(Box::new(event)) }); - self.handlers.insert(signature, handler); } @@ -59,7 +58,6 @@ impl EvmEventListener { .await? .into_stream(); while let Some(log) = stream.next().await { - println!("received log!"); if let Some(topic0) = log.topic0() { if let Some(decoder) = self.handlers.get(topic0) { if let Ok(event) = decoder(log.clone()) { diff --git a/packages/ciphernode/core/src/lib.rs b/packages/ciphernode/core/src/lib.rs index 81610e31..13ca3322 100644 --- a/packages/ciphernode/core/src/lib.rs +++ b/packages/ciphernode/core/src/lib.rs @@ -2,14 +2,15 @@ #![crate_type = "lib"] // #![warn(missing_docs, unused_imports)] -mod ciphernode; mod cipernode_selector; +mod ciphernode; mod committee_meta; mod data; mod e3_request; mod eventbus; pub mod events; mod evm_ciphernode_registry; +mod evm_enclave; mod evm_listener; mod evm_manager; mod fhe; @@ -23,12 +24,12 @@ mod publickey_aggregator; mod serializers; mod sortition; mod utils; -mod evm_enclave; +mod public_key_writer; // TODO: this is too permissive pub use actix::prelude::*; -pub use ciphernode::*; pub use cipernode_selector::*; +pub use ciphernode::*; pub use committee_meta::*; pub use data::*; pub use e3_request::*; @@ -41,6 +42,7 @@ pub use main_ciphernode::*; pub use p2p::*; pub use plaintext_aggregator::*; pub use publickey_aggregator::*; +pub use public_key_writer::*; pub use serializers::*; pub use sortition::*; pub use utils::*; @@ -336,31 +338,22 @@ mod tests { tokio::spawn(async move { while let Some(msg) = output.recv().await { msgs_loop.lock().await.push(msg.clone()); - let _ = input.send(msg).await; // loopback to simulate a rebroadcast message - // if this manages to broadcast an event to the - // event bus we will expect to see an extra event on - // the bus + let _ = input.send(msg).await; + // loopback to simulate a rebroadcast message + // if this manages to broadcast an event to the + // event bus we will expect to see an extra event on + // the bus } }); - let evt_1 = EnclaveEvent::from(E3Requested { - e3_id: E3id::new("1234"), - threshold_m: 3, - seed: 123, - moduli: vec![0x3FFFFFFF000001], - degree: 2048, - plaintext_modulus: 1032193, - crp: vec![1, 2, 3, 4], + let evt_1 = EnclaveEvent::from(PlaintextAggregated { + e3_id: E3id::new("1235"), + decrypted_output: vec![1, 2, 3, 4], }); - let evt_2 = EnclaveEvent::from(E3Requested { - e3_id: E3id::new("1235"), - threshold_m: 3, - seed: 123, - moduli: vec![0x3FFFFFFF000001], - degree: 2048, - plaintext_modulus: 1032193, - crp: vec![1, 2, 3, 4], + let evt_2 = EnclaveEvent::from(PlaintextAggregated { + e3_id: E3id::new("1236"), + decrypted_output: vec![1, 2, 3, 4], }); let local_evt_3 = EnclaveEvent::from(CiphernodeSelected { diff --git a/packages/ciphernode/core/src/logger.rs b/packages/ciphernode/core/src/logger.rs index 5733743c..22d4f545 100644 --- a/packages/ciphernode/core/src/logger.rs +++ b/packages/ciphernode/core/src/logger.rs @@ -34,20 +34,23 @@ impl Handler for SimpleLogger { EnclaveEvent::PublicKeyAggregated { data, .. } => { let pubkey_str = BASE64_STANDARD.encode(&data.pubkey); println!( - "\n\nPUBKEY:\n{}...{}\n\nSaved to scripts/pubkey.b64\n\n", + "\n[{}]: PUBKEY: {}...{}\n", + self.name, &pubkey_str[..20], &pubkey_str[pubkey_str.len() - 20..] ); - fs::write("scripts/pubkey.b64", &pubkey_str).unwrap(); println!("[{}]: {}", self.name, msg); } EnclaveEvent::PlaintextAggregated { data, .. } => { let output: Vec = bincode::deserialize(&data.decrypted_output).unwrap(); - println!("\n\nDECRYPTED:\n{:?}\n\n", output); + println!("[{}]: DECRYPTED: \n{:?}\n\n", self.name,output); println!("[{}]: {}", self.name, msg); } EnclaveEvent::CiphernodeAdded { data, .. } => { println!("[{}]: CiphernodeAdded({})", self.name, data.address); + }, + EnclaveEvent::E3Requested { data,.. } => { + println!("[{}]: E3Requested(e3_id: {}, threshold_m: {} , seed: {})", self.name, data.e3_id, data.threshold_m, data.seed) } _ => println!("[{}]: {}", self.name, msg), } diff --git a/packages/ciphernode/core/src/main_aggregator.rs b/packages/ciphernode/core/src/main_aggregator.rs index 87da2ec7..4e41ee64 100644 --- a/packages/ciphernode/core/src/main_aggregator.rs +++ b/packages/ciphernode/core/src/main_aggregator.rs @@ -1,9 +1,13 @@ -use std::sync::{Arc, Mutex}; +use std::{ + env, + sync::{Arc, Mutex}, +}; use crate::{ committee_meta::CommitteeMetaFactory, evm_ciphernode_registry::connect_evm_ciphernode_registry, - E3RequestManager, EventBus, FheFactory, P2p, PlaintextAggregatorFactory, - PublicKeyAggregatorFactory, SimpleLogger, Sortition, + evm_enclave::connect_evm_enclave, public_key_writer::PublicKeyWriter, E3RequestManager, + EventBus, FheFactory, P2p, PlaintextAggregatorFactory, PublicKeyAggregatorFactory, + SimpleLogger, Sortition, }; use actix::{Actor, Addr, Context}; use alloy::primitives::Address; @@ -36,14 +40,20 @@ impl MainAggregator { } } - pub async fn attach(rpc_url: &str, contract_address: Address) -> (Addr, JoinHandle<()>) { + pub async fn attach( + rpc_url: &str, + enclave_contract: Address, + registry_contract: Address, + pubkey_write_path: Option<&str>, + ) -> (Addr, JoinHandle<()>) { let rng = Arc::new(Mutex::new( rand_chacha::ChaCha20Rng::from_rng(OsRng).expect("Failed to create RNG"), )); let bus = EventBus::new(true).start(); let sortition = Sortition::attach(bus.clone()); - connect_evm_ciphernode_registry(bus.clone(), rpc_url, contract_address).await; + connect_evm_enclave(bus.clone(), rpc_url, enclave_contract).await; + connect_evm_ciphernode_registry(bus.clone(), rpc_url, registry_contract).await; let e3_manager = E3RequestManager::builder(bus.clone()) .add_hook(CommitteeMetaFactory::create()) @@ -61,7 +71,11 @@ impl MainAggregator { let (p2p_addr, join_handle) = P2p::spawn_libp2p(bus.clone()).expect("Failed to setup libp2p"); - SimpleLogger::attach("AGGREGATOR", bus.clone()); + if let Some(path) = pubkey_write_path { + PublicKeyWriter::attach(path, bus.clone()); + } + + SimpleLogger::attach("AGG", bus.clone()); let main_addr = MainAggregator::new(bus, sortition, p2p_addr, e3_manager).start(); (main_addr, join_handle) diff --git a/packages/ciphernode/core/src/main_ciphernode.rs b/packages/ciphernode/core/src/main_ciphernode.rs index 9a14074d..b6c0e8ec 100644 --- a/packages/ciphernode/core/src/main_ciphernode.rs +++ b/packages/ciphernode/core/src/main_ciphernode.rs @@ -1,7 +1,9 @@ use std::sync::{Arc, Mutex}; use crate::{ - evm_ciphernode_registry::connect_evm_ciphernode_registry, evm_enclave::connect_evm_enclave, CiphernodeFactory, CiphernodeSelector, CommitteeMetaFactory, Data, E3RequestManager, EventBus, FheFactory, P2p, SimpleLogger, Sortition + evm_ciphernode_registry::connect_evm_ciphernode_registry, evm_enclave::connect_evm_enclave, + CiphernodeFactory, CiphernodeSelector, CommitteeMetaFactory, Data, E3RequestManager, EventBus, + FheFactory, P2p, SimpleLogger, Sortition, }; use actix::{Actor, Addr, Context}; use alloy::primitives::Address; @@ -47,7 +49,7 @@ impl MainCiphernode { address: Address, rpc_url: &str, enclave_contract: Address, - registry_contract: Address + registry_contract: Address, ) -> (Addr, JoinHandle<()>) { let rng = Arc::new(Mutex::new( rand_chacha::ChaCha20Rng::from_rng(OsRng).expect("Failed to create RNG"), @@ -74,7 +76,8 @@ impl MainCiphernode { let (p2p_addr, join_handle) = P2p::spawn_libp2p(bus.clone()).expect("Failed to setup libp2p"); - SimpleLogger::attach("CIPHERNODE", bus.clone()); + let nm = format!("CIPHER({})", &address.to_string()[0..5]); + SimpleLogger::attach(&nm, bus.clone()); let main_addr = MainCiphernode::new( address, bus, data, sortition, selector, p2p_addr, e3_manager, ) diff --git a/packages/ciphernode/core/src/public_key_writer.rs b/packages/ciphernode/core/src/public_key_writer.rs new file mode 100644 index 00000000..9dad8cbd --- /dev/null +++ b/packages/ciphernode/core/src/public_key_writer.rs @@ -0,0 +1,46 @@ +use crate::{EnclaveEvent, EventBus, Subscribe}; +use actix::{Actor, Addr, Context, Handler}; +use alloy::primitives::Address; +use base64::prelude::*; +use std::{env, fs, path::PathBuf}; + +pub struct PublicKeyWriter { + path: String, +} + +impl PublicKeyWriter { + pub fn attach(path: &str, bus: Addr) -> Addr { + let addr = Self { + path: path.to_owned(), + } + .start(); + bus.do_send(Subscribe { + listener: addr.clone().recipient(), + event_type: "*".to_string(), + }); + addr + } +} + +impl Actor for PublicKeyWriter { + type Context = Context; +} + +impl Handler for PublicKeyWriter { + type Result = (); + fn handle(&mut self, msg: EnclaveEvent, _: &mut Self::Context) -> Self::Result { + if let EnclaveEvent::PublicKeyAggregated { data, .. } = msg.clone() { + let pubkey_str = BASE64_STANDARD.encode(&data.pubkey); + + if let Some(path) = append_relative_path(&self.path) { + fs::write(path, &pubkey_str).unwrap(); + } + } + } +} + +fn append_relative_path(relative_path: &str) -> Option { + let mut path = env::current_dir().ok()?; + path.push(relative_path); + Some(path.canonicalize().ok()?) +} diff --git a/packages/ciphernode/core/src/publickey_aggregator.rs b/packages/ciphernode/core/src/publickey_aggregator.rs index b98dd847..7c184370 100644 --- a/packages/ciphernode/core/src/publickey_aggregator.rs +++ b/packages/ciphernode/core/src/publickey_aggregator.rs @@ -75,7 +75,6 @@ impl PublicKeyAggregator { else { return Err(anyhow::anyhow!("Can only add keyshare in Collecting state")); }; - keyshares.insert(keyshare); if keyshares.len() == *threshold_m as usize { return Ok(PublicKeyAggregatorState::Computing { @@ -218,9 +217,11 @@ impl PublicKeyAggregatorFactory { }; let Some(ref fhe) = ctx.fhe else { + println!("fhe was not on ctx"); return; }; let Some(ref meta) = ctx.meta else { + println!("meta was not on ctx"); return; }; diff --git a/packages/ciphernode/core/src/sortition.rs b/packages/ciphernode/core/src/sortition.rs index edbf942f..b6995ce8 100644 --- a/packages/ciphernode/core/src/sortition.rs +++ b/packages/ciphernode/core/src/sortition.rs @@ -104,6 +104,7 @@ impl Handler for Sortition { impl Handler for Sortition { type Result = (); fn handle(&mut self, msg: CiphernodeAdded, _ctx: &mut Self::Context) -> Self::Result { + println!("$$$$$$\nCIPHERNODE ADDED\n$$$$$$\n\n{}", msg.address); self.list.add(msg.address); } } diff --git a/packages/ciphernode/enclave_node/src/bin/aggregator.rs b/packages/ciphernode/enclave_node/src/bin/aggregator.rs index 43874cba..0b87aede 100644 --- a/packages/ciphernode/enclave_node/src/bin/aggregator.rs +++ b/packages/ciphernode/enclave_node/src/bin/aggregator.rs @@ -5,10 +5,14 @@ use enclave_core::MainAggregator; #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] struct Args { - #[arg(short='n', long)] + #[arg(short = 'n', long)] rpc: String, - #[arg(short, long="registry-contract")] - registry_contract: String + #[arg(short, long = "enclave-contract")] + enclave_contract: String, + #[arg(short, long = "registry-contract")] + registry_contract: String, + #[arg(short, long = "pubkey-write-path")] + pubkey_write_path: Option, } #[actix_rt::main] @@ -17,7 +21,15 @@ async fn main() -> Result<(), Box> { println!("LAUNCHING AGGREGATOR"); let registry_contract = Address::parse_checksummed(&args.registry_contract, None).expect("Invalid address"); - let (_, handle) = MainAggregator::attach(&args.rpc, registry_contract).await; + let enclave_contract = + Address::parse_checksummed(&args.enclave_contract, None).expect("Invalid address"); + let (_, handle) = MainAggregator::attach( + &args.rpc, + enclave_contract, + registry_contract, + args.pubkey_write_path.as_deref(), + ) + .await; let _ = tokio::join!(handle); Ok(()) } diff --git a/packages/evm/contracts/Enclave.sol b/packages/evm/contracts/Enclave.sol index 4d5bdebb..8768098f 100644 --- a/packages/evm/contracts/Enclave.sol +++ b/packages/evm/contracts/Enclave.sol @@ -13,7 +13,7 @@ import { LeanIMTData, PoseidonT3 } from "@zk-kit/lean-imt.sol/InternalLeanIMT.sol"; - +import "hardhat/console.sol"; contract Enclave is IEnclave, OwnableUpgradeable { using InternalLeanIMT for LeanIMTData; @@ -178,7 +178,8 @@ contract Enclave is IEnclave, OwnableUpgradeable { ciphernodeRegistry.requestCommittee(e3Id, filter, threshold), CommitteeSelectionFailed() ); - + console.log("Event signature:"); + console.logBytes32(E3Requested.selector); emit E3Requested(e3Id, e3, filter, e3Program); } diff --git a/packages/evm/deploy/mocks.ts b/packages/evm/deploy/mocks.ts index 623ebaf7..f9f2b4e0 100644 --- a/packages/evm/deploy/mocks.ts +++ b/packages/evm/deploy/mocks.ts @@ -1,7 +1,7 @@ import { DeployFunction } from "hardhat-deploy/types"; import { HardhatRuntimeEnvironment } from "hardhat/types"; -const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { +const func: DeployFunction = async function(hre: HardhatRuntimeEnvironment) { const { deployer } = await hre.getNamedAccounts(); const { deploy } = hre.deployments; @@ -17,7 +17,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { log: true, }); - await deploy("MockDecryptionVerifier", { + const mockDecryptionVerifier = await deploy("MockDecryptionVerifier", { from: deployer, args: [], log: true, @@ -28,6 +28,27 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { args: [], log: true, }); + + // Set up MockDecryptionVerifier in Enclave contract + const enclaveDeployment = await hre.deployments.get("Enclave"); + const enclaveContract = await hre.ethers.getContractAt( + "Enclave", + enclaveDeployment.address, + ); + + const encryptionSchemeId = + "0x0000000000000000000000000000000000000000000000000000000000000001"; + + try { + const tx = await enclaveContract.setDecryptionVerifier( + encryptionSchemeId, + mockDecryptionVerifier.address, + ); + await tx.wait(); + console.log(`Successfully set MockDecryptionVerifier in Enclave contract`); + } catch (error) { + console.error("Error setting MockDecryptionVerifier:", error); + } }; export default func; func.tags = ["mocks"]; diff --git a/scripts/ciphernode_launch.sh b/scripts/ciphernode_launch.sh deleted file mode 100755 index 2b963f77..00000000 --- a/scripts/ciphernode_launch.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -pushd packages/ciphernode && yarn ciphernode:add --ciphernode-address $1 -pushd packages/evm && ./scripts/launch.sh --address $1 diff --git a/scripts/test.sh b/scripts/test.sh new file mode 100755 index 00000000..035fdf4d --- /dev/null +++ b/scripts/test.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +# Environment variables +export RPC_URL="ws://localhost:8545" +export ENCLAVE_CONTRACT="0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" +export REGISTRY_CONTRACT="0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9" +export CIPHERNODE_ADDRESS_1="0x2546BcD3c84621e976D8185a91A922aE77ECEc30" +export CIPHERNODE_ADDRESS_2="0xbDA5747bFD65F08deb54cb465eB87D40e51B197E" +export CIPHERNODE_ADDRESS_3="0xdD2FD4581271e230360230F9337D5c0430Bf44C0" +export CIPHERNODE_ADDRESS_4="0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199" + +# Function to clean up background processes +cleanup() { + echo "Cleaning up processes..." + kill $(jobs -p) + exit +} + +# Set up trap to catch Ctrl+C +trap cleanup SIGINT + +# pushd packages/ciphernode && \ +# cargo build --bin node && \ +# cargo build --bin aggregator && \ +# popd + +# Start the EVM node +yarn evm:node & +sleep 2 + + + +# Launch ciphernodes in parallel +yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_1 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & +yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_2 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & +yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_3 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & +yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_4 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & +yarn ciphernode:aggregator --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT --pubkey-write-path "tests/fixtures/pubkey.b64" & +sleep 2 + +# Run ciphernode:add commands sequentially +yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_1 --network localhost +sleep 2 +yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_2 --network localhost +sleep 2 +yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_3 --network localhost +sleep 2 +yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_4 --network localhost + +# Wait for Ctrl+C +echo "All processes are running. Press Ctrl+C to stop and clean up." +wait From 54de815fe9bf0bfd845246808ec333eb8c26fcb0 Mon Sep 17 00:00:00 2001 From: ryardley Date: Tue, 24 Sep 2024 22:52:46 +1000 Subject: [PATCH 10/35] Update formatting --- packages/ciphernode/core/src/public_key_writer.rs | 8 +++++++- packages/ciphernode/core/src/sortition.rs | 1 - packages/evm/deploy/mocks.ts | 2 +- scripts/test.sh | 3 ++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/ciphernode/core/src/public_key_writer.rs b/packages/ciphernode/core/src/public_key_writer.rs index 9dad8cbd..7629d22d 100644 --- a/packages/ciphernode/core/src/public_key_writer.rs +++ b/packages/ciphernode/core/src/public_key_writer.rs @@ -1,6 +1,5 @@ use crate::{EnclaveEvent, EventBus, Subscribe}; use actix::{Actor, Addr, Context, Handler}; -use alloy::primitives::Address; use base64::prelude::*; use std::{env, fs, path::PathBuf}; @@ -18,6 +17,8 @@ impl PublicKeyWriter { listener: addr.clone().recipient(), event_type: "*".to_string(), }); + + println!("PublicKeyWriter attached to path {}", path); addr } } @@ -32,7 +33,12 @@ impl Handler for PublicKeyWriter { if let EnclaveEvent::PublicKeyAggregated { data, .. } = msg.clone() { let pubkey_str = BASE64_STANDARD.encode(&data.pubkey); + println!("Write pubkey to {}", &self.path); if let Some(path) = append_relative_path(&self.path) { + let Some(path_str) = path.to_str() else { + return; + }; + println!("Write pubkey to {}", &path_str); fs::write(path, &pubkey_str).unwrap(); } } diff --git a/packages/ciphernode/core/src/sortition.rs b/packages/ciphernode/core/src/sortition.rs index b6995ce8..edbf942f 100644 --- a/packages/ciphernode/core/src/sortition.rs +++ b/packages/ciphernode/core/src/sortition.rs @@ -104,7 +104,6 @@ impl Handler for Sortition { impl Handler for Sortition { type Result = (); fn handle(&mut self, msg: CiphernodeAdded, _ctx: &mut Self::Context) -> Self::Result { - println!("$$$$$$\nCIPHERNODE ADDED\n$$$$$$\n\n{}", msg.address); self.list.add(msg.address); } } diff --git a/packages/evm/deploy/mocks.ts b/packages/evm/deploy/mocks.ts index f9f2b4e0..58dae802 100644 --- a/packages/evm/deploy/mocks.ts +++ b/packages/evm/deploy/mocks.ts @@ -1,7 +1,7 @@ import { DeployFunction } from "hardhat-deploy/types"; import { HardhatRuntimeEnvironment } from "hardhat/types"; -const func: DeployFunction = async function(hre: HardhatRuntimeEnvironment) { +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployer } = await hre.getNamedAccounts(); const { deploy } = hre.deployments; diff --git a/scripts/test.sh b/scripts/test.sh index 035fdf4d..59f827d2 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -35,7 +35,8 @@ yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_1 --rpc "$RPC_URL" --enclav yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_2 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_3 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_4 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & -yarn ciphernode:aggregator --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT --pubkey-write-path "tests/fixtures/pubkey.b64" & +yarn ciphernode:aggregator --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT --pubkey-write-path "../../pubkey.b64" & + sleep 2 # Run ciphernode:add commands sequentially From 4699adce66ee7d2dd027ca8b379d4e221aa47c50 Mon Sep 17 00:00:00 2001 From: ryardley Date: Tue, 24 Sep 2024 23:09:50 +1000 Subject: [PATCH 11/35] Public Key Writer Working --- .../ciphernode/core/src/public_key_writer.rs | 33 ++++++++++++------- scripts/test.sh | 2 +- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/packages/ciphernode/core/src/public_key_writer.rs b/packages/ciphernode/core/src/public_key_writer.rs index 7629d22d..e2032bd6 100644 --- a/packages/ciphernode/core/src/public_key_writer.rs +++ b/packages/ciphernode/core/src/public_key_writer.rs @@ -1,7 +1,8 @@ use crate::{EnclaveEvent, EventBus, Subscribe}; use actix::{Actor, Addr, Context, Handler}; use base64::prelude::*; -use std::{env, fs, path::PathBuf}; +use std::fs; +use std::io::Write; pub struct PublicKeyWriter { path: String, @@ -34,19 +35,27 @@ impl Handler for PublicKeyWriter { let pubkey_str = BASE64_STANDARD.encode(&data.pubkey); println!("Write pubkey to {}", &self.path); - if let Some(path) = append_relative_path(&self.path) { - let Some(path_str) = path.to_str() else { - return; - }; - println!("Write pubkey to {}", &path_str); - fs::write(path, &pubkey_str).unwrap(); - } + write_file_with_dirs(&self.path, &pubkey_str).unwrap(); } } } -fn append_relative_path(relative_path: &str) -> Option { - let mut path = env::current_dir().ok()?; - path.push(relative_path); - Some(path.canonicalize().ok()?) +fn write_file_with_dirs(relative_path: &str, content: &str) -> std::io::Result<()> { + // Get the current working directory + let cwd = std::env::current_dir()?; + + // Create an absolute path by joining the cwd and the relative path + let abs_path = cwd.join(relative_path); + + // Ensure the directory structure exists + if let Some(parent) = abs_path.parent() { + fs::create_dir_all(parent)?; + } + + // Open the file (creates it if it doesn't exist) and write the content + let mut file = fs::File::create(&abs_path)?; + file.write_all(content.as_bytes())?; + + println!("File written successfully: {:?}", abs_path); + Ok(()) } diff --git a/scripts/test.sh b/scripts/test.sh index 59f827d2..3432125d 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -35,7 +35,7 @@ yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_1 --rpc "$RPC_URL" --enclav yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_2 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_3 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_4 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & -yarn ciphernode:aggregator --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT --pubkey-write-path "../../pubkey.b64" & +yarn ciphernode:aggregator --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT --pubkey-write-path "../../tests/output/pubkey.b64" & sleep 2 From 95091465bcffeb860f456464dd07312b60552937 Mon Sep 17 00:00:00 2001 From: ryardley Date: Tue, 24 Sep 2024 23:19:20 +1000 Subject: [PATCH 12/35] Write pubkey to screen and file --- package.json | 1 + packages/evm/package.json | 1 + scripts/test.sh | 7 +++++++ tests/output/.gitignore | 1 + 4 files changed, 10 insertions(+) create mode 100644 tests/output/.gitignore diff --git a/package.json b/package.json index 507eb06a..03a5163b 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "evm:typechain": "cd packages/evm && yarn typechain", "evm:test": "cd packages/evm && yarn test", "evm:coverage": "cd packages/evm && yarn coverage", + "evm:committee:new": "cd packages/evm && yarn committee:new", "preinstall": "yarn evm:install", "evm:release": "cd packages/evm && yarn release" }, diff --git a/packages/evm/package.json b/packages/evm/package.json index f62e920e..e63a8488 100644 --- a/packages/evm/package.json +++ b/packages/evm/package.json @@ -76,6 +76,7 @@ "deploy:mocks": "hardhat deploy --tags enclave,mocks", "ciphernode:add": "hardhat ciphernode:add", "ciphernode:remove": "hardhat ciphernode:remove", + "committee:new": "hardhat committee:new", "lint": "yarn lint:sol && yarn lint:ts && yarn prettier:check", "lint:sol": "solhint --max-warnings 0 \"contracts/**/*.sol\"", "lint:ts": "eslint --ignore-path ./.eslintignore --ext .js,.ts .", diff --git a/scripts/test.sh b/scripts/test.sh index 3432125d..92515f4d 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -47,7 +47,14 @@ sleep 2 yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_3 --network localhost sleep 2 yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_4 --network localhost +sleep 2 +yarn evm:committee:new --network localhost +sleep 2 + +cat ./tests/output/pubkey.b64 # Wait for Ctrl+C +echo "" +echo "" echo "All processes are running. Press Ctrl+C to stop and clean up." wait diff --git a/tests/output/.gitignore b/tests/output/.gitignore new file mode 100644 index 00000000..ee048bd1 --- /dev/null +++ b/tests/output/.gitignore @@ -0,0 +1 @@ +pubkey.b64 From 082c3a4f25f08267701e7a3557bbdfb6952781f7 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 25 Sep 2024 00:17:00 +1000 Subject: [PATCH 13/35] attempt to load pubkey --- package.json | 1 + .../enclave_node/src/bin/encrypt.rs | 33 ++++++++++++------- scripts/test.sh | 11 +++---- tests/output/.gitignore | 4 ++- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index 03a5163b..82f15649 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "ciphernode:aggregator": "cd packages/ciphernode && ./scripts/aggregator.sh", "ciphernode:test": "cd packages/ciphernode && cargo test", "ciphernode:build": "cd packages/ciphernode && cargo build --release", + "ciphernode:encrypt": "cd packages/ciphernode && RUSTFLAGS=\"-A warnings\" cargo run --bin encrypt -- ", "evm:install": "cd packages/evm && yarn install", "evm:node": "cd packages/evm && yarn hardhat node", "evm:compile": "cd packages/evm && yarn compile", diff --git a/packages/ciphernode/enclave_node/src/bin/encrypt.rs b/packages/ciphernode/enclave_node/src/bin/encrypt.rs index 8777991a..7b6c7475 100644 --- a/packages/ciphernode/enclave_node/src/bin/encrypt.rs +++ b/packages/ciphernode/enclave_node/src/bin/encrypt.rs @@ -1,15 +1,28 @@ use base64::{engine::general_purpose, Engine as _}; -use enclave_core::{setup_bfv_params, setup_crp_params, CiphertextSerializer, ParamsWithCrp}; +use clap::Parser; +use enclave_core::{setup_bfv_params, CiphertextSerializer}; use fhe::bfv::{Encoding, Plaintext, PublicKey}; use fhe_traits::{DeserializeParametrized, FheEncoder, FheEncrypter, Serialize}; use rand::SeedableRng; -use rand_chacha::{rand_core::OsRng, ChaCha20Rng}; -use std::{fs, sync::Arc}; +use rand_chacha::ChaCha20Rng; +use std::fs; + +#[derive(Parser, Debug)] +#[command(author, version, about, long_about = None)] +struct Args { + #[arg(short, long)] + input: String, + + #[arg(short, long)] + output: String, +} fn main() -> Result<(), Box> { - // Read the base64 encoded string from a file - println!("Loading public key from ./scripts/pubkey.b64"); - let encoded_string = fs::read_to_string("scripts/pubkey.b64")?; + let args = Args::parse(); + + // Read the base64 encoded string from the input file + println!("Loading public key from {}", args.input); + let encoded_string = fs::read_to_string(&args.input)?; // Decode the base64 string let decoded_bytes: Vec = general_purpose::STANDARD.decode(encoded_string.trim())?; @@ -18,17 +31,15 @@ fn main() -> Result<(), Box> { let yes = 1234u64; let no = 873827u64; - let raw_plaintext = vec![yes, no]; println!("Encrypting plaintext: {:?}", raw_plaintext); let pt = Plaintext::try_encode(&raw_plaintext, Encoding::poly(), ¶ms)?; - let ciphertext = pubkey.try_encrypt(&pt, &mut ChaCha20Rng::seed_from_u64(42))?; let ciphertext_bytes = CiphertextSerializer::to_bytes(ciphertext.clone(), params.clone())?; + + fs::write(&args.output, &ciphertext_bytes)?; + println!("Created {}", args.output); - let encrypted = general_purpose::STANDARD.encode(ciphertext_bytes); - fs::write("scripts/encrypted.b64", &encrypted).unwrap(); - println!("Created ./scripts/encrypted.b64"); Ok(()) } diff --git a/scripts/test.sh b/scripts/test.sh index 92515f4d..ab9cc4dd 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -19,17 +19,12 @@ cleanup() { # Set up trap to catch Ctrl+C trap cleanup SIGINT -# pushd packages/ciphernode && \ -# cargo build --bin node && \ -# cargo build --bin aggregator && \ -# popd +pushd packages/ciphernode; RUSTFLAGS="-A warnings" cargo build --frozen --bin encrypt --bin node --bin aggregator; popd # Start the EVM node yarn evm:node & sleep 2 - - # Launch ciphernodes in parallel yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_1 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_2 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & @@ -53,6 +48,10 @@ sleep 2 cat ./tests/output/pubkey.b64 +yarn ciphernode:encrypt --input "../../tests/output/pubkey.b64" --output "../../tests/output/output.bin" + +cd packages/evm; yarn hardhat e3:publishCiphertext --e3-id 0 --network localhost --data "0x$(xxd -p -c 0 ../../tests/output/output.bin)"; popd + # Wait for Ctrl+C echo "" echo "" diff --git a/tests/output/.gitignore b/tests/output/.gitignore index ee048bd1..8b54c082 100644 --- a/tests/output/.gitignore +++ b/tests/output/.gitignore @@ -1 +1,3 @@ -pubkey.b64 +*.b64 +*.bin + From dbfa41becba8fa9681d4fcc801519282ea786ca4 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 25 Sep 2024 00:40:13 +1000 Subject: [PATCH 14/35] Update script --- scripts/test.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/scripts/test.sh b/scripts/test.sh index ab9cc4dd..a5d84431 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -50,7 +50,19 @@ cat ./tests/output/pubkey.b64 yarn ciphernode:encrypt --input "../../tests/output/pubkey.b64" --output "../../tests/output/output.bin" -cd packages/evm; yarn hardhat e3:publishCiphertext --e3-id 0 --network localhost --data "0x$(xxd -p -c 0 ../../tests/output/output.bin)"; popd +cd packages/evm; yarn hardhat committee:publish --e3-id 0 --nodes $CIPHERNODE_ADDRESS_1,$CIPHERNODE_ADDRESS_2,$CIPHERNODE_ADDRESS_3,$CIPHERNODE_ADDRESS_4 --public-key 0x12345678 --network localhost; popd + +sleep 2 + +cd packages/evm; yarn hardhat e3:activate --e3-id 0 --network localhost; popd + +sleep 2 + +cd packages/evm; hardhat --network localhost e3:publishInput --e3-id 0 --data 0x12345678; popd + +sleep 2 + +cd packages/evm; yarn hardhat e3:publishCiphertext --e3-id 0 --network localhost --data "0x$(xxd -p -c 0 ../../tests/output/output.bin)" --proof 0x12345678; popd # Wait for Ctrl+C echo "" From 15513239b968812e51e1623552fa0a89264e89db Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 25 Sep 2024 00:45:14 +1000 Subject: [PATCH 15/35] tworks --- scripts/test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/test.sh b/scripts/test.sh index a5d84431..eb4174ec 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -43,7 +43,7 @@ yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_3 --network localho sleep 2 yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_4 --network localhost sleep 2 -yarn evm:committee:new --network localhost +yarn evm:committee:new --network localhost --duration 6 sleep 2 cat ./tests/output/pubkey.b64 @@ -60,7 +60,7 @@ sleep 2 cd packages/evm; hardhat --network localhost e3:publishInput --e3-id 0 --data 0x12345678; popd -sleep 2 +sleep 4 cd packages/evm; yarn hardhat e3:publishCiphertext --e3-id 0 --network localhost --data "0x$(xxd -p -c 0 ../../tests/output/output.bin)" --proof 0x12345678; popd From b4524def7fab720fe6dc94108305785e3177916b Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 25 Sep 2024 00:47:33 +1000 Subject: [PATCH 16/35] Remove console --- packages/evm/contracts/Enclave.sol | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/evm/contracts/Enclave.sol b/packages/evm/contracts/Enclave.sol index 8768098f..4d5bdebb 100644 --- a/packages/evm/contracts/Enclave.sol +++ b/packages/evm/contracts/Enclave.sol @@ -13,7 +13,7 @@ import { LeanIMTData, PoseidonT3 } from "@zk-kit/lean-imt.sol/InternalLeanIMT.sol"; -import "hardhat/console.sol"; + contract Enclave is IEnclave, OwnableUpgradeable { using InternalLeanIMT for LeanIMTData; @@ -178,8 +178,7 @@ contract Enclave is IEnclave, OwnableUpgradeable { ciphernodeRegistry.requestCommittee(e3Id, filter, threshold), CommitteeSelectionFailed() ); - console.log("Event signature:"); - console.logBytes32(E3Requested.selector); + emit E3Requested(e3Id, e3, filter, e3Program); } From 21efe3ff427959658f3b7dd621643d5506dc8b5a Mon Sep 17 00:00:00 2001 From: samepant Date: Tue, 24 Sep 2024 14:05:41 -0400 Subject: [PATCH 17/35] script tweaks, deploy tweak for testing --- packages/evm/tasks/enclave.ts | 26 +++++++++++++------------- scripts/test.sh | 14 +++++++------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/evm/tasks/enclave.ts b/packages/evm/tasks/enclave.ts index 7d92f5fd..e7f77125 100644 --- a/packages/evm/tasks/enclave.ts +++ b/packages/evm/tasks/enclave.ts @@ -113,19 +113,19 @@ task( ); // since we are using mock, we need to set the decryption verifier to the mock encryption scheme id - try { - const setDecryptionVerifier = - await enclaveContract.setDecryptionVerifier( - "0x0000000000000000000000000000000000000000000000000000000000000001", - MockDecryptionVerifier.address, - ); - await setDecryptionVerifier.wait(); - } catch (e) { - console.log( - "Setting decryption verifier for encryption scheme id failed: ", - e, - ); - } + // try { + // const setDecryptionVerifier = + // await enclaveContract.setDecryptionVerifier( + // "0x0000000000000000000000000000000000000000000000000000000000000001", + // MockDecryptionVerifier.address, + // ); + // await setDecryptionVerifier.wait(); + // } catch (e) { + // console.log( + // "Setting decryption verifier for encryption scheme id failed: ", + // e, + // ); + // } } try { diff --git a/scripts/test.sh b/scripts/test.sh index eb4174ec..d2b6df7f 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -2,8 +2,8 @@ # Environment variables export RPC_URL="ws://localhost:8545" -export ENCLAVE_CONTRACT="0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" -export REGISTRY_CONTRACT="0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9" +export ENCLAVE_CONTRACT="0x404Af1c0780A9269e4D3308a0812fB87BF5fC490" +export REGISTRY_CONTRACT="0x04DaE625b71c7094Fc5216061E3b97077420c13e" export CIPHERNODE_ADDRESS_1="0x2546BcD3c84621e976D8185a91A922aE77ECEc30" export CIPHERNODE_ADDRESS_2="0xbDA5747bFD65F08deb54cb465eB87D40e51B197E" export CIPHERNODE_ADDRESS_3="0xdD2FD4581271e230360230F9337D5c0430Bf44C0" @@ -19,7 +19,7 @@ cleanup() { # Set up trap to catch Ctrl+C trap cleanup SIGINT -pushd packages/ciphernode; RUSTFLAGS="-A warnings" cargo build --frozen --bin encrypt --bin node --bin aggregator; popd +cd packages/ciphernode; RUSTFLAGS="-A warnings" cargo build --frozen --bin encrypt --bin node --bin aggregator; cd ../.. # Start the EVM node yarn evm:node & @@ -50,19 +50,19 @@ cat ./tests/output/pubkey.b64 yarn ciphernode:encrypt --input "../../tests/output/pubkey.b64" --output "../../tests/output/output.bin" -cd packages/evm; yarn hardhat committee:publish --e3-id 0 --nodes $CIPHERNODE_ADDRESS_1,$CIPHERNODE_ADDRESS_2,$CIPHERNODE_ADDRESS_3,$CIPHERNODE_ADDRESS_4 --public-key 0x12345678 --network localhost; popd +cd packages/evm; yarn hardhat committee:publish --e3-id 0 --nodes $CIPHERNODE_ADDRESS_1,$CIPHERNODE_ADDRESS_2,$CIPHERNODE_ADDRESS_3,$CIPHERNODE_ADDRESS_4 --public-key 0x12345678 --network localhost; cd ../.. sleep 2 -cd packages/evm; yarn hardhat e3:activate --e3-id 0 --network localhost; popd +cd packages/evm; yarn hardhat e3:activate --e3-id 0 --network localhost; cd ../.. sleep 2 -cd packages/evm; hardhat --network localhost e3:publishInput --e3-id 0 --data 0x12345678; popd +cd packages/evm; yarn hardhat --network localhost e3:publishInput --e3-id 0 --data 0x12345678; cd ../.. sleep 4 -cd packages/evm; yarn hardhat e3:publishCiphertext --e3-id 0 --network localhost --data "0x$(xxd -p -c 0 ../../tests/output/output.bin)" --proof 0x12345678; popd +cd packages/evm; yarn hardhat e3:publishCiphertext --e3-id 0 --network localhost --data "0x$(xxd -p -c 0 ../../tests/output/output.bin)" --proof 0x12345678; cd ../.. # Wait for Ctrl+C echo "" From d76a882fe32ddb98189f4a3a3a6e21b16e63eabb Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 25 Sep 2024 14:43:18 +1000 Subject: [PATCH 18/35] Tidy up test script --- package.json | 7 +- .../core/src/evm_ciphernode_registry.rs | 1 - packages/ciphernode/core/src/evm_enclave.rs | 5 - packages/ciphernode/core/src/lib.rs | 2 + .../ciphernode/core/src/main_aggregator.rs | 10 +- .../ciphernode/core/src/plaintext_writer.rs | 38 +++++ .../ciphernode/core/src/public_key_writer.rs | 33 +---- packages/ciphernode/core/src/utils.rs | 29 +++- .../enclave_node/scripts/.gitignore | 1 - .../ciphernode/enclave_node/scripts/ag.sh | 3 - .../ciphernode/enclave_node/scripts/cmd.sh | 4 - .../enclave_node/scripts/encrypt.sh | 4 - .../ciphernode/enclave_node/scripts/node1.sh | 4 - .../ciphernode/enclave_node/scripts/node2.sh | 4 - .../ciphernode/enclave_node/scripts/node3.sh | 4 - .../ciphernode/enclave_node/scripts/node4.sh | 4 - .../enclave_node/src/bin/aggregator.rs | 3 + .../ciphernode/enclave_node/src/bin/cmd.rs | 114 --------------- .../src/bin/{encrypt.rs => test_encryptor.rs} | 18 +-- packages/ciphernode/scripts/aggregator.sh | 2 +- packages/ciphernode/scripts/launch.sh | 2 +- packages/ciphernode/scripts/test_encryptor.sh | 3 + scripts/test.sh | 71 --------- tests/basic_integration/lib/fake_encrypt.sh | 3 + tests/basic_integration/lib/prebuild.sh | 3 + tests/basic_integration/output/.gitignore | 2 + tests/basic_integration/run.sh | 137 ++++++++++++++++++ tests/output/.gitignore | 3 - 28 files changed, 243 insertions(+), 271 deletions(-) create mode 100644 packages/ciphernode/core/src/plaintext_writer.rs delete mode 100644 packages/ciphernode/enclave_node/scripts/.gitignore delete mode 100755 packages/ciphernode/enclave_node/scripts/ag.sh delete mode 100755 packages/ciphernode/enclave_node/scripts/cmd.sh delete mode 100755 packages/ciphernode/enclave_node/scripts/encrypt.sh delete mode 100755 packages/ciphernode/enclave_node/scripts/node1.sh delete mode 100755 packages/ciphernode/enclave_node/scripts/node2.sh delete mode 100755 packages/ciphernode/enclave_node/scripts/node3.sh delete mode 100755 packages/ciphernode/enclave_node/scripts/node4.sh delete mode 100644 packages/ciphernode/enclave_node/src/bin/cmd.rs rename packages/ciphernode/enclave_node/src/bin/{encrypt.rs => test_encryptor.rs} (75%) create mode 100644 packages/ciphernode/scripts/test_encryptor.sh delete mode 100755 scripts/test.sh create mode 100755 tests/basic_integration/lib/fake_encrypt.sh create mode 100755 tests/basic_integration/lib/prebuild.sh create mode 100644 tests/basic_integration/output/.gitignore create mode 100755 tests/basic_integration/run.sh delete mode 100644 tests/output/.gitignore diff --git a/package.json b/package.json index 82f15649..233d3862 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "lint": "yarn evm:lint", "typechain": "yarn evm:typechain", "test": "yarn evm:test && yarn ciphernode:test", + "test:e2e": "./tests/basic_integration/run.sh", "coverage": "yarn evm:coverage", "ciphernode:launch": "cd packages/ciphernode && ./scripts/launch.sh", "ciphernode:add": "cd packages/evm && yarn ciphernode:add", @@ -20,7 +21,10 @@ "ciphernode:aggregator": "cd packages/ciphernode && ./scripts/aggregator.sh", "ciphernode:test": "cd packages/ciphernode && cargo test", "ciphernode:build": "cd packages/ciphernode && cargo build --release", - "ciphernode:encrypt": "cd packages/ciphernode && RUSTFLAGS=\"-A warnings\" cargo run --bin encrypt -- ", + "committee:new": "cd packages/evm && yarn committee:new", + "e3:activate": "cd packages/evm && yarn hardhat e3:activate", + "e3:publishInput": "cd packages/evm && yarn hardhat e3:publishInput", + "e3:publishCiphertext": "cd packages/evm && yarn hardhat e3:publishCiphertext", "evm:install": "cd packages/evm && yarn install", "evm:node": "cd packages/evm && yarn hardhat node", "evm:compile": "cd packages/evm && yarn compile", @@ -28,7 +32,6 @@ "evm:typechain": "cd packages/evm && yarn typechain", "evm:test": "cd packages/evm && yarn test", "evm:coverage": "cd packages/evm && yarn coverage", - "evm:committee:new": "cd packages/evm && yarn committee:new", "preinstall": "yarn evm:install", "evm:release": "cd packages/evm && yarn release" }, diff --git a/packages/ciphernode/core/src/evm_ciphernode_registry.rs b/packages/ciphernode/core/src/evm_ciphernode_registry.rs index a1484d33..9023929d 100644 --- a/packages/ciphernode/core/src/evm_ciphernode_registry.rs +++ b/packages/ciphernode/core/src/evm_ciphernode_registry.rs @@ -48,7 +48,6 @@ impl From for events::CiphernodeRemoved { impl ContractEvent for CiphernodeAdded { fn process(&self, bus: Addr) -> Result<()> { - println!("Ciphernode Added: {:?}", self); let data: events::CiphernodeAdded = self.clone().into(); bus.do_send(EnclaveEvent::from(data)); Ok(()) diff --git a/packages/ciphernode/core/src/evm_enclave.rs b/packages/ciphernode/core/src/evm_enclave.rs index e032ab0d..c7c858da 100644 --- a/packages/ciphernode/core/src/evm_enclave.rs +++ b/packages/ciphernode/core/src/evm_enclave.rs @@ -47,11 +47,6 @@ sol! { impl From for events::E3Requested { fn from(value: E3Requested) -> Self { - println!( - "===========================\n\nE3Request\n\n===============\n{:?}", - value - ); - let _params_bytes = value.e3.e3ProgramParams; // TODO: decode params bytes // HACK: temp supply canned params: diff --git a/packages/ciphernode/core/src/lib.rs b/packages/ciphernode/core/src/lib.rs index 13ca3322..5d9635c9 100644 --- a/packages/ciphernode/core/src/lib.rs +++ b/packages/ciphernode/core/src/lib.rs @@ -25,6 +25,7 @@ mod serializers; mod sortition; mod utils; mod public_key_writer; +mod plaintext_writer; // TODO: this is too permissive pub use actix::prelude::*; @@ -43,6 +44,7 @@ pub use p2p::*; pub use plaintext_aggregator::*; pub use publickey_aggregator::*; pub use public_key_writer::*; +pub use plaintext_writer::*; pub use serializers::*; pub use sortition::*; pub use utils::*; diff --git a/packages/ciphernode/core/src/main_aggregator.rs b/packages/ciphernode/core/src/main_aggregator.rs index 4e41ee64..5a17f9fc 100644 --- a/packages/ciphernode/core/src/main_aggregator.rs +++ b/packages/ciphernode/core/src/main_aggregator.rs @@ -4,10 +4,7 @@ use std::{ }; use crate::{ - committee_meta::CommitteeMetaFactory, evm_ciphernode_registry::connect_evm_ciphernode_registry, - evm_enclave::connect_evm_enclave, public_key_writer::PublicKeyWriter, E3RequestManager, - EventBus, FheFactory, P2p, PlaintextAggregatorFactory, PublicKeyAggregatorFactory, - SimpleLogger, Sortition, + committee_meta::CommitteeMetaFactory, evm_ciphernode_registry::connect_evm_ciphernode_registry, evm_enclave::connect_evm_enclave, public_key_writer::PublicKeyWriter, E3RequestManager, EventBus, FheFactory, P2p, PlaintextAggregatorFactory, PlaintextWriter, PublicKeyAggregatorFactory, SimpleLogger, Sortition }; use actix::{Actor, Addr, Context}; use alloy::primitives::Address; @@ -45,6 +42,7 @@ impl MainAggregator { enclave_contract: Address, registry_contract: Address, pubkey_write_path: Option<&str>, + plaintext_write_path: Option<&str> ) -> (Addr, JoinHandle<()>) { let rng = Arc::new(Mutex::new( rand_chacha::ChaCha20Rng::from_rng(OsRng).expect("Failed to create RNG"), @@ -75,6 +73,10 @@ impl MainAggregator { PublicKeyWriter::attach(path, bus.clone()); } + if let Some(path) = plaintext_write_path { + PlaintextWriter::attach(path, bus.clone()); + } + SimpleLogger::attach("AGG", bus.clone()); let main_addr = MainAggregator::new(bus, sortition, p2p_addr, e3_manager).start(); diff --git a/packages/ciphernode/core/src/plaintext_writer.rs b/packages/ciphernode/core/src/plaintext_writer.rs new file mode 100644 index 00000000..73810578 --- /dev/null +++ b/packages/ciphernode/core/src/plaintext_writer.rs @@ -0,0 +1,38 @@ +use crate::{write_file_with_dirs, EnclaveEvent, EventBus, Subscribe}; +use actix::{Actor, Addr, Context, Handler}; + +pub struct PlaintextWriter { + path: String, +} + +impl PlaintextWriter { + pub fn attach(path: &str, bus: Addr) -> Addr { + let addr = Self { + path: path.to_owned(), + } + .start(); + bus.do_send(Subscribe { + listener: addr.clone().recipient(), + event_type: "PlaintextAggregated".to_string(), + }); + addr + } +} + +impl Actor for PlaintextWriter { + type Context = Context; +} + +impl Handler for PlaintextWriter { + type Result = (); + fn handle(&mut self, msg: EnclaveEvent, _: &mut Self::Context) -> Self::Result { + if let EnclaveEvent::PlaintextAggregated { data, .. } = msg.clone() { + let output: Vec = bincode::deserialize(&data.decrypted_output).unwrap(); + + println!("Write plaintext to {}", &self.path); + let contents: Vec = output.iter().map(|&num| num.to_string()).collect(); + write_file_with_dirs(&self.path, format!("{}", contents.join(",")).as_bytes()) + .unwrap(); + } + } +} diff --git a/packages/ciphernode/core/src/public_key_writer.rs b/packages/ciphernode/core/src/public_key_writer.rs index e2032bd6..55a72541 100644 --- a/packages/ciphernode/core/src/public_key_writer.rs +++ b/packages/ciphernode/core/src/public_key_writer.rs @@ -1,8 +1,5 @@ -use crate::{EnclaveEvent, EventBus, Subscribe}; +use crate::{write_file_with_dirs, EnclaveEvent, EventBus, Subscribe}; use actix::{Actor, Addr, Context, Handler}; -use base64::prelude::*; -use std::fs; -use std::io::Write; pub struct PublicKeyWriter { path: String, @@ -16,10 +13,8 @@ impl PublicKeyWriter { .start(); bus.do_send(Subscribe { listener: addr.clone().recipient(), - event_type: "*".to_string(), + event_type: "PublicKeyAggregated".to_string(), }); - - println!("PublicKeyWriter attached to path {}", path); addr } } @@ -32,30 +27,8 @@ impl Handler for PublicKeyWriter { type Result = (); fn handle(&mut self, msg: EnclaveEvent, _: &mut Self::Context) -> Self::Result { if let EnclaveEvent::PublicKeyAggregated { data, .. } = msg.clone() { - let pubkey_str = BASE64_STANDARD.encode(&data.pubkey); - println!("Write pubkey to {}", &self.path); - write_file_with_dirs(&self.path, &pubkey_str).unwrap(); + write_file_with_dirs(&self.path, &data.pubkey).unwrap(); } } } - -fn write_file_with_dirs(relative_path: &str, content: &str) -> std::io::Result<()> { - // Get the current working directory - let cwd = std::env::current_dir()?; - - // Create an absolute path by joining the cwd and the relative path - let abs_path = cwd.join(relative_path); - - // Ensure the directory structure exists - if let Some(parent) = abs_path.parent() { - fs::create_dir_all(parent)?; - } - - // Open the file (creates it if it doesn't exist) and write the content - let mut file = fs::File::create(&abs_path)?; - file.write_all(content.as_bytes())?; - - println!("File written successfully: {:?}", abs_path); - Ok(()) -} diff --git a/packages/ciphernode/core/src/utils.rs b/packages/ciphernode/core/src/utils.rs index 1a51e8db..d56c1362 100644 --- a/packages/ciphernode/core/src/utils.rs +++ b/packages/ciphernode/core/src/utils.rs @@ -4,7 +4,7 @@ use fhe::{ mbfv::CommonRandomPoly, }; use fhe_traits::Serialize; -use std::sync::Arc; +use std::{fs, io::Write, path::Path, sync::Arc}; pub struct ParamsWithCrp { pub moduli: Vec, @@ -31,7 +31,11 @@ pub fn setup_crp_params( } } -pub fn setup_bfv_params(moduli: &[u64], degree: usize, plaintext_modulus: u64) -> Arc { +pub fn setup_bfv_params( + moduli: &[u64], + degree: usize, + plaintext_modulus: u64, +) -> Arc { BfvParametersBuilder::new() .set_degree(degree) .set_plaintext_modulus(plaintext_modulus) @@ -43,3 +47,24 @@ pub fn setup_bfv_params(moduli: &[u64], degree: usize, plaintext_modulus: u64) - pub fn set_up_crp(params: Arc, rng: SharedRng) -> CommonRandomPoly { CommonRandomPoly::new(¶ms, &mut *rng.lock().unwrap()).unwrap() } + +pub fn write_file_with_dirs(path: &str, content: &[u8]) -> std::io::Result<()> { + let abs_path = if Path::new(path).is_absolute() { + Path::new(path).to_path_buf() + } else { + let cwd = std::env::current_dir()?; + cwd.join(path) + }; + + // Ensure the directory structure exists + if let Some(parent) = abs_path.parent() { + fs::create_dir_all(parent)?; + } + + // Open the file (creates it if it doesn't exist) and write the content + let mut file = fs::File::create(&abs_path)?; + file.write_all(content)?; + + println!("File written successfully: {:?}", abs_path); + Ok(()) +} diff --git a/packages/ciphernode/enclave_node/scripts/.gitignore b/packages/ciphernode/enclave_node/scripts/.gitignore deleted file mode 100644 index 3ba8733c..00000000 --- a/packages/ciphernode/enclave_node/scripts/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.b64 diff --git a/packages/ciphernode/enclave_node/scripts/ag.sh b/packages/ciphernode/enclave_node/scripts/ag.sh deleted file mode 100755 index d6e22791..00000000 --- a/packages/ciphernode/enclave_node/scripts/ag.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -echo "loading..." -RUSTFLAGS="-A warnings" cargo run --quiet --bin aggregator diff --git a/packages/ciphernode/enclave_node/scripts/cmd.sh b/packages/ciphernode/enclave_node/scripts/cmd.sh deleted file mode 100755 index 86e2106c..00000000 --- a/packages/ciphernode/enclave_node/scripts/cmd.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -echo "loading..." -RUSTFLAGS="-A warnings" cargo run --quiet --bin cmd diff --git a/packages/ciphernode/enclave_node/scripts/encrypt.sh b/packages/ciphernode/enclave_node/scripts/encrypt.sh deleted file mode 100755 index 45d3d6f8..00000000 --- a/packages/ciphernode/enclave_node/scripts/encrypt.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -echo "loading..." -RUSTFLAGS="-A warnings" cargo run --quiet --bin encrypt diff --git a/packages/ciphernode/enclave_node/scripts/node1.sh b/packages/ciphernode/enclave_node/scripts/node1.sh deleted file mode 100755 index 97474c90..00000000 --- a/packages/ciphernode/enclave_node/scripts/node1.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -echo "loading..." -RUSTFLAGS="-A warnings" cargo run --quiet --bin node -- --address 0xCc6c693FDB68f0DB58172639CDEa33FF488cf0a5 diff --git a/packages/ciphernode/enclave_node/scripts/node2.sh b/packages/ciphernode/enclave_node/scripts/node2.sh deleted file mode 100755 index 7568191c..00000000 --- a/packages/ciphernode/enclave_node/scripts/node2.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -echo "loading..." -RUSTFLAGS="-A warnings" cargo run --quiet --bin node -- --address 0x75437e59cAC691C0624e089554834619dc49B944 diff --git a/packages/ciphernode/enclave_node/scripts/node3.sh b/packages/ciphernode/enclave_node/scripts/node3.sh deleted file mode 100755 index af6ca05c..00000000 --- a/packages/ciphernode/enclave_node/scripts/node3.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -echo "loading..." -RUSTFLAGS="-A warnings" cargo run --quiet --bin node -- --address 0xe3092f4A2B59234a557aa2dE5D97314D4E969764 diff --git a/packages/ciphernode/enclave_node/scripts/node4.sh b/packages/ciphernode/enclave_node/scripts/node4.sh deleted file mode 100755 index 0569550e..00000000 --- a/packages/ciphernode/enclave_node/scripts/node4.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -echo "loading..." -RUSTFLAGS="-A warnings" cargo run --quiet --bin node -- --address 0x25c693E1188b9E4455E07DC4f6a49142eFbF2C61 diff --git a/packages/ciphernode/enclave_node/src/bin/aggregator.rs b/packages/ciphernode/enclave_node/src/bin/aggregator.rs index 0b87aede..e46327e6 100644 --- a/packages/ciphernode/enclave_node/src/bin/aggregator.rs +++ b/packages/ciphernode/enclave_node/src/bin/aggregator.rs @@ -13,6 +13,8 @@ struct Args { registry_contract: String, #[arg(short, long = "pubkey-write-path")] pubkey_write_path: Option, + #[arg(short = 't', long = "plaintext-write-path")] + plaintext_write_path: Option, } #[actix_rt::main] @@ -28,6 +30,7 @@ async fn main() -> Result<(), Box> { enclave_contract, registry_contract, args.pubkey_write_path.as_deref(), + args.plaintext_write_path.as_deref() ) .await; let _ = tokio::join!(handle); diff --git a/packages/ciphernode/enclave_node/src/bin/cmd.rs b/packages/ciphernode/enclave_node/src/bin/cmd.rs deleted file mode 100644 index d940afb9..00000000 --- a/packages/ciphernode/enclave_node/src/bin/cmd.rs +++ /dev/null @@ -1,114 +0,0 @@ -use std::sync::Arc; - -use alloy_primitives::{address, Address}; -use base64::{engine::general_purpose, Engine as _}; -use enclave_core::{ - setup_crp_params, Actor, E3Requested, E3id, EnclaveEvent, EventBus, P2p, ParamsWithCrp, - SimpleLogger, -}; -use enclave_core::{CiphernodeAdded, CiphertextOutputPublished}; -use rand::{thread_rng, RngCore, SeedableRng}; -use rand_chacha::rand_core::OsRng; -use std::fs; -use tokio::{ - self, - io::{self, AsyncBufReadExt, BufReader}, -}; - -const ADDRS: [Address; 4] = [ - address!("Cc6c693FDB68f0DB58172639CDEa33FF488cf0a5"), - address!("75437e59cAC691C0624e089554834619dc49B944"), - address!("e3092f4A2B59234a557aa2dE5D97314D4E969764"), - address!("25c693E1188b9E4455E07DC4f6a49142eFbF2C61"), -]; - -#[actix_rt::main] -async fn main() -> Result<(), Box> { - let rng = Arc::new(std::sync::Mutex::new( - rand_chacha::ChaCha20Rng::from_rng(OsRng).expect("Failed to create RNG"), - )); - - let bus = EventBus::new(true).start(); - - SimpleLogger::attach("CMD", bus.clone()); - let (_, t1) = P2p::spawn_libp2p(bus.clone())?; - let mut stdin = BufReader::new(io::stdin()).lines(); - let ParamsWithCrp { - moduli, - degree, - plaintext_modulus, - crp_bytes, - .. - } = setup_crp_params(&[0x3FFFFFFF000001], 2048, 1032193, rng.clone()); - let t2 = tokio::spawn(async move { - let mut id: u32 = 1000; - while let Ok(Some(line)) = stdin.next_line().await { - let parts: Vec<&str> = line.split_whitespace().collect(); - match parts.as_slice() { - ["reg", "1"] => { - println!("Registering Ciphernode {}", ADDRS[0]); - bus.do_send(EnclaveEvent::from(CiphernodeAdded { - address: ADDRS[0].to_string(), - index: 0, - num_nodes: 1, - })); - } - ["reg", "2"] => { - println!("Registering Ciphernode {}", ADDRS[1]); - bus.do_send(EnclaveEvent::from(CiphernodeAdded { - address: ADDRS[1].to_string(), - index: 1, - num_nodes: 2, - })) - } - ["reg", "3"] => { - println!("Registering Ciphernode {}", ADDRS[2]); - bus.do_send(EnclaveEvent::from(CiphernodeAdded { - address: ADDRS[2].to_string(), - index: 2, - num_nodes: 3, - })) - } - ["reg", "4"] => { - println!("Registering Ciphernode {}", ADDRS[3]); - bus.do_send(EnclaveEvent::from(CiphernodeAdded { - address: ADDRS[3].to_string(), - index: 3, - num_nodes: 4, - })) - } - - ["com"] => { - id += 1; - println!("Requesting comittee: {}", id); - bus.do_send(EnclaveEvent::from(E3Requested { - e3_id: E3id::from(id), - threshold_m: 3, - seed: thread_rng().next_u64(), - moduli: moduli.clone(), - plaintext_modulus, - degree, - crp: crp_bytes.clone(), - })); - } - ["load"] => { - println!("Loading from ./scripts/encrypted.b64..."); - let encoded_string = fs::read_to_string("scripts/encrypted.b64").unwrap(); - - let decoded_bytes: Vec = general_purpose::STANDARD - .decode(encoded_string.trim()) - .unwrap(); - - bus.do_send(EnclaveEvent::from(CiphertextOutputPublished { - e3_id: E3id::from(id), - ciphertext_output: decoded_bytes, - })) - } - _ => println!("Unknown command"), - } - } - }); - - let _ = tokio::join!(t1, t2); - Ok(()) -} diff --git a/packages/ciphernode/enclave_node/src/bin/encrypt.rs b/packages/ciphernode/enclave_node/src/bin/test_encryptor.rs similarity index 75% rename from packages/ciphernode/enclave_node/src/bin/encrypt.rs rename to packages/ciphernode/enclave_node/src/bin/test_encryptor.rs index 7b6c7475..4cc74a08 100644 --- a/packages/ciphernode/enclave_node/src/bin/encrypt.rs +++ b/packages/ciphernode/enclave_node/src/bin/test_encryptor.rs @@ -1,8 +1,8 @@ -use base64::{engine::general_purpose, Engine as _}; +// This is a test script designed to encrypt some fixed data to a fhe public key use clap::Parser; use enclave_core::{setup_bfv_params, CiphertextSerializer}; use fhe::bfv::{Encoding, Plaintext, PublicKey}; -use fhe_traits::{DeserializeParametrized, FheEncoder, FheEncrypter, Serialize}; +use fhe_traits::{DeserializeParametrized, FheEncoder, FheEncrypter}; use rand::SeedableRng; use rand_chacha::ChaCha20Rng; use std::fs; @@ -15,6 +15,9 @@ struct Args { #[arg(short, long)] output: String, + + #[arg(short, long, value_delimiter = ',')] + plaintext: Vec, } fn main() -> Result<(), Box> { @@ -22,22 +25,19 @@ fn main() -> Result<(), Box> { // Read the base64 encoded string from the input file println!("Loading public key from {}", args.input); - let encoded_string = fs::read_to_string(&args.input)?; + let bytes = fs::read(&args.input)?; // Decode the base64 string - let decoded_bytes: Vec = general_purpose::STANDARD.decode(encoded_string.trim())?; let params = setup_bfv_params(&[0x3FFFFFFF000001], 2048, 1032193); - let pubkey = PublicKey::from_bytes(&decoded_bytes, ¶ms)?; + let pubkey = PublicKey::from_bytes(&bytes, ¶ms)?; - let yes = 1234u64; - let no = 873827u64; - let raw_plaintext = vec![yes, no]; + let raw_plaintext = args.plaintext; println!("Encrypting plaintext: {:?}", raw_plaintext); let pt = Plaintext::try_encode(&raw_plaintext, Encoding::poly(), ¶ms)?; let ciphertext = pubkey.try_encrypt(&pt, &mut ChaCha20Rng::seed_from_u64(42))?; let ciphertext_bytes = CiphertextSerializer::to_bytes(ciphertext.clone(), params.clone())?; - + fs::write(&args.output, &ciphertext_bytes)?; println!("Created {}", args.output); diff --git a/packages/ciphernode/scripts/aggregator.sh b/packages/ciphernode/scripts/aggregator.sh index f839bf27..78ca9ad7 100755 --- a/packages/ciphernode/scripts/aggregator.sh +++ b/packages/ciphernode/scripts/aggregator.sh @@ -1,3 +1,3 @@ -#!/bin/sh +#!/usr/bin/env sh RUSTFLAGS="-A warnings" cargo run --bin aggregator -- $@ diff --git a/packages/ciphernode/scripts/launch.sh b/packages/ciphernode/scripts/launch.sh index 51adac41..7f1f3844 100755 --- a/packages/ciphernode/scripts/launch.sh +++ b/packages/ciphernode/scripts/launch.sh @@ -1,3 +1,3 @@ -#!/bin/sh +#!/usr/bin/env sh RUSTFLAGS="-A warnings" cargo run --bin node -- $@ diff --git a/packages/ciphernode/scripts/test_encryptor.sh b/packages/ciphernode/scripts/test_encryptor.sh new file mode 100644 index 00000000..cbe41ff2 --- /dev/null +++ b/packages/ciphernode/scripts/test_encryptor.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +RUSTFLAGS="-A warnings" cargo run --bin test_encryptor -- $@ diff --git a/scripts/test.sh b/scripts/test.sh deleted file mode 100755 index d2b6df7f..00000000 --- a/scripts/test.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/sh - -# Environment variables -export RPC_URL="ws://localhost:8545" -export ENCLAVE_CONTRACT="0x404Af1c0780A9269e4D3308a0812fB87BF5fC490" -export REGISTRY_CONTRACT="0x04DaE625b71c7094Fc5216061E3b97077420c13e" -export CIPHERNODE_ADDRESS_1="0x2546BcD3c84621e976D8185a91A922aE77ECEc30" -export CIPHERNODE_ADDRESS_2="0xbDA5747bFD65F08deb54cb465eB87D40e51B197E" -export CIPHERNODE_ADDRESS_3="0xdD2FD4581271e230360230F9337D5c0430Bf44C0" -export CIPHERNODE_ADDRESS_4="0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199" - -# Function to clean up background processes -cleanup() { - echo "Cleaning up processes..." - kill $(jobs -p) - exit -} - -# Set up trap to catch Ctrl+C -trap cleanup SIGINT - -cd packages/ciphernode; RUSTFLAGS="-A warnings" cargo build --frozen --bin encrypt --bin node --bin aggregator; cd ../.. - -# Start the EVM node -yarn evm:node & -sleep 2 - -# Launch ciphernodes in parallel -yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_1 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & -yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_2 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & -yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_3 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & -yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_4 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & -yarn ciphernode:aggregator --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT --pubkey-write-path "../../tests/output/pubkey.b64" & - -sleep 2 - -# Run ciphernode:add commands sequentially -yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_1 --network localhost -sleep 2 -yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_2 --network localhost -sleep 2 -yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_3 --network localhost -sleep 2 -yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_4 --network localhost -sleep 2 -yarn evm:committee:new --network localhost --duration 6 -sleep 2 - -cat ./tests/output/pubkey.b64 - -yarn ciphernode:encrypt --input "../../tests/output/pubkey.b64" --output "../../tests/output/output.bin" - -cd packages/evm; yarn hardhat committee:publish --e3-id 0 --nodes $CIPHERNODE_ADDRESS_1,$CIPHERNODE_ADDRESS_2,$CIPHERNODE_ADDRESS_3,$CIPHERNODE_ADDRESS_4 --public-key 0x12345678 --network localhost; cd ../.. - -sleep 2 - -cd packages/evm; yarn hardhat e3:activate --e3-id 0 --network localhost; cd ../.. - -sleep 2 - -cd packages/evm; yarn hardhat --network localhost e3:publishInput --e3-id 0 --data 0x12345678; cd ../.. - -sleep 4 - -cd packages/evm; yarn hardhat e3:publishCiphertext --e3-id 0 --network localhost --data "0x$(xxd -p -c 0 ../../tests/output/output.bin)" --proof 0x12345678; cd ../.. - -# Wait for Ctrl+C -echo "" -echo "" -echo "All processes are running. Press Ctrl+C to stop and clean up." -wait diff --git a/tests/basic_integration/lib/fake_encrypt.sh b/tests/basic_integration/lib/fake_encrypt.sh new file mode 100755 index 00000000..a7b456d2 --- /dev/null +++ b/tests/basic_integration/lib/fake_encrypt.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +cd packages/ciphernode && RUSTFLAGS="-A warnings" cargo run --bin test_encryptor -- $@ diff --git a/tests/basic_integration/lib/prebuild.sh b/tests/basic_integration/lib/prebuild.sh new file mode 100755 index 00000000..df759402 --- /dev/null +++ b/tests/basic_integration/lib/prebuild.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +cd packages/ciphernode && RUSTFLAGS="-A warnings" cargo build --frozen --bin test_encryptor --bin node --bin aggregator; diff --git a/tests/basic_integration/output/.gitignore b/tests/basic_integration/output/.gitignore new file mode 100644 index 00000000..1d5b85f9 --- /dev/null +++ b/tests/basic_integration/output/.gitignore @@ -0,0 +1,2 @@ +*.bin +plaintext.txt diff --git a/tests/basic_integration/run.sh b/tests/basic_integration/run.sh new file mode 100755 index 00000000..6d3cd01c --- /dev/null +++ b/tests/basic_integration/run.sh @@ -0,0 +1,137 @@ +#!/usr/bin/env sh + +set -e # Exit immediately if a command exits with a non-zero status +# +# Get the script's location +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)" +PLAINTEXT="1234,567890" + +if [[ "$ROOT_DIR" != "$(pwd)" ]]; then + echo "This script must be run from the root" +fi + +# Environment variables +export RPC_URL="ws://localhost:8545" +# These contracts are based on the deterministic order of hardhat deploy +export ENCLAVE_CONTRACT="0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" +export REGISTRY_CONTRACT="0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9" +# These are random addresses for now +export CIPHERNODE_ADDRESS_1="0x2546BcD3c84621e976D8185a91A922aE77ECEc30" +export CIPHERNODE_ADDRESS_2="0xbDA5747bFD65F08deb54cb465eB87D40e51B197E" +export CIPHERNODE_ADDRESS_3="0xdD2FD4581271e230360230F9337D5c0430Bf44C0" +export CIPHERNODE_ADDRESS_4="0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199" + +# Function to clean up background processes +cleanup() { + echo "Cleaning up processes..." >&2 + kill $(jobs -p) 2>/dev/null + sleep 4 + exit ${1:-1} +} + +heading() { + echo "" + echo "" + echo "--------------------------------------------------------------" + echo " $1 " + echo "--------------------------------------------------------------" + echo "" +} + +pkill -9 -f "target/debug/node" || true +pkill -9 -f "hardhat node" || true +pkill -9 -f "target/debug/aggregator" || true + +# Set up trap to catch errors and interrupts +trap 'cleanup $?' ERR INT TERM + +# Delete output artifacts +rm -rf $ROOT_DIR/tests/basic_integration/output/* + +$SCRIPT_DIR/lib/prebuild.sh + +heading "Start the EVM node" + +yarn evm:node & + +sleep 2 + +heading "Launch ciphernode $CIPHERNODE_ADDRESS_1" +yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_1 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & + +heading "Launch ciphernode $CIPHERNODE_ADDRESS_2" +yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_2 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & + +heading "Launch ciphernode $CIPHERNODE_ADDRESS_3" +yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_3 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & + +heading "Launch ciphernode $CIPHERNODE_ADDRESS_4" +yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_4 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & + +yarn ciphernode:aggregator --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT --pubkey-write-path "$SCRIPT_DIR/output/pubkey.bin" --plaintext-write-path "$SCRIPT_DIR/output/plaintext.txt" & + +sleep 2 + +heading "Add ciphernode $CIPHERNODE_ADDRESS_1" +yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_1 --network localhost + +sleep 2 + +heading "Add ciphernode $CIPHERNODE_ADDRESS_2" +yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_2 --network localhost + +sleep 2 + +heading "Add ciphernode $CIPHERNODE_ADDRESS_3" +yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_3 --network localhost + +sleep 2 + +heading "Add ciphernode $CIPHERNODE_ADDRESS_4" +yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_4 --network localhost + +sleep 2 + +heading "Request Committee" + +yarn committee:new --network localhost --duration 6 + +sleep 2 + +heading "Mock encrypted plaintext" + +$SCRIPT_DIR/lib/fake_encrypt.sh --input "$SCRIPT_DIR/output/pubkey.bin" --output "$SCRIPT_DIR/output/output.bin" --plaintext $PLAINTEXT + +heading "Mock publish committee key" + +cd packages/evm; yarn hardhat committee:publish --e3-id 0 --nodes $CIPHERNODE_ADDRESS_1,$CIPHERNODE_ADDRESS_2,$CIPHERNODE_ADDRESS_3,$CIPHERNODE_ADDRESS_4 --public-key 0x12345678 --network localhost; cd ../.. + +sleep 2 + +heading "Mock activate e3-id" + +yarn e3:activate --e3-id 0 --network localhost + +sleep 2 + +heading "Mock publish input e3-id" +yarn e3:publishInput --network localhost --e3-id 0 --data 0x12345678 + +sleep 2 + +heading "Publish ciphertext to EVM" + +yarn e3:publishCiphertext --e3-id 0 --network localhost --data "0x$(xxd -p -c 0 $SCRIPT_DIR/output/output.bin)" --proof 0x12345678 + +sleep 10 + +ACTUAL=$(cat $SCRIPT_DIR/output/plaintext.txt) + +if [[ "$ACTUAL" != "$PLAINTEXT" ]]; then + echo "Invalid plaintext decrypted: actual='$ACTUAL' expected='$PLAINTEXT'" + exit 1 +fi + +cleanup 0 + diff --git a/tests/output/.gitignore b/tests/output/.gitignore deleted file mode 100644 index 8b54c082..00000000 --- a/tests/output/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.b64 -*.bin - From f9662b172e71497515f92d5dc465c38813ebe6c4 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 25 Sep 2024 14:49:12 +1000 Subject: [PATCH 19/35] Add to CI --- .github/workflows/integration.yml | 69 +++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/integration.yml diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml new file mode 100644 index 00000000..38dd1c49 --- /dev/null +++ b/.github/workflows/integration.yml @@ -0,0 +1,69 @@ +name: "INTEGRATION" + +env: + HARDHAT_VAR_MNEMONIC: "test test test test test test test test test test test junk" + HARDHAT_VAR_INFURA_API_KEY: "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" + # Uncomment the following lines to set your configuration variables using + # GitHub secrets (https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions) + # + # HARDHAT_VAR_MNEMONIC: ${{ secrets.Mnemonic }} + # HARDHAT_VAR_INFURA_API_KEY: ${{ secrets.InfuraApiKey }} + # HARDHAT_VAR_ARBISCAN_API_KEY: ${{ secrets.ArbiscanApiKey }} + # HARDHAT_VAR_BSCSCAN_API_KEY: ${{ secrets.BscscanApiKey }} + # HARDHAT_VAR_ETHERSCAN_API_KEY: ${{ secrets.EtherscanApiKey }} + # HARDHAT_VAR_OPTIMISM_API_KEY: ${{ secrets.OptimismApiKey }} + # HARDHAT_VAR_POLYGONSCAN_API_KEY: ${{ secrets.PolygonscanApiKey }} + # HARDHAT_VAR_SNOWTRACE_API_KEY: ${{ secrets.SnowtraceApiKey }} + +on: + workflow_dispatch: + pull_request: + push: + branches: + - main + +jobs: + ci: + runs-on: "ubuntu-latest" + steps: + - name: "Check out the repo" + uses: "actions/checkout@v4" + + - name: "Setup node" + uses: actions/setup-node@v2 + with: + node-version: 20 + + - name: Install latest stable Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + + - name: Cache node modules + uses: actions/cache@v2 + with: + path: "**/node_modules" + key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} + + - name: "Install the dependencies" + run: "yarn install" + + - name: "Lint the code" + run: "yarn lint" + + - name: "Add lint summary" + run: | + echo "## Lint results" >> $GITHUB_STEP_SUMMARY + echo "✅ Passed" >> $GITHUB_STEP_SUMMARY + + - name: "Compile the contracts and generate the TypeChain bindings" + run: "yarn typechain" + + - name: "Test the contracts and generate the coverage report" + run: "yarn test:integration" + + - name: "Add test summary" + run: | + echo "## Test results" >> $GITHUB_STEP_SUMMARY + echo "✅ Passed" >> $GITHUB_STEP_SUMMARY diff --git a/package.json b/package.json index 233d3862..7f4af963 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "lint": "yarn evm:lint", "typechain": "yarn evm:typechain", "test": "yarn evm:test && yarn ciphernode:test", - "test:e2e": "./tests/basic_integration/run.sh", + "test:integration": "./tests/basic_integration/run.sh", "coverage": "yarn evm:coverage", "ciphernode:launch": "cd packages/ciphernode && ./scripts/launch.sh", "ciphernode:add": "cd packages/evm && yarn ciphernode:add", From b07b1b9eb5be8bf2ddd1a116e0646e774c185ce6 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 25 Sep 2024 14:52:08 +1000 Subject: [PATCH 20/35] Use rust 1.81 --- .github/workflows/integration.yml | 4 ++-- .github/workflows/rust-ci.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 38dd1c49..1a667c1f 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -34,10 +34,10 @@ jobs: with: node-version: 20 - - name: Install latest stable Rust + - name: Install Rust 1.81.0 uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: 1.81.0 override: true - name: Cache node modules diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index b53b3fb3..3e9d2f46 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -14,10 +14,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Install latest stable Rust + - name: Install Rust 1.81.0 uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: 1.81.0 override: true - name: Run tests From ae0da9c924b0817f7f8cc11ca842750cb50c4e23 Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 25 Sep 2024 14:58:36 +1000 Subject: [PATCH 21/35] Ensure bash --- tests/basic_integration/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/basic_integration/run.sh b/tests/basic_integration/run.sh index 6d3cd01c..80271b6f 100755 --- a/tests/basic_integration/run.sh +++ b/tests/basic_integration/run.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash set -e # Exit immediately if a command exits with a non-zero status # From 30d1b3742295fac3cbc605c2e642a2e66157de2d Mon Sep 17 00:00:00 2001 From: ryardley Date: Wed, 25 Sep 2024 15:10:07 +1000 Subject: [PATCH 22/35] Remove frozen --- tests/basic_integration/lib/prebuild.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/basic_integration/lib/prebuild.sh b/tests/basic_integration/lib/prebuild.sh index df759402..26bd3b77 100755 --- a/tests/basic_integration/lib/prebuild.sh +++ b/tests/basic_integration/lib/prebuild.sh @@ -1,3 +1,3 @@ #!/usr/bin/env sh -cd packages/ciphernode && RUSTFLAGS="-A warnings" cargo build --frozen --bin test_encryptor --bin node --bin aggregator; +cd packages/ciphernode && RUSTFLAGS="-A warnings" cargo build --bin test_encryptor --bin node --bin aggregator; From 896f187f9c3771fb077180001cf58a4e4a3dbab6 Mon Sep 17 00:00:00 2001 From: ryardley Date: Thu, 26 Sep 2024 10:38:04 +1000 Subject: [PATCH 23/35] Use --data-file over --data --- packages/evm/tasks/enclave.ts | 29 +++++---------------- tests/basic_integration/{run.sh => test.sh} | 2 +- 2 files changed, 8 insertions(+), 23 deletions(-) rename tests/basic_integration/{run.sh => test.sh} (97%) diff --git a/packages/evm/tasks/enclave.ts b/packages/evm/tasks/enclave.ts index e7f77125..9cb2229a 100644 --- a/packages/evm/tasks/enclave.ts +++ b/packages/evm/tasks/enclave.ts @@ -60,7 +60,7 @@ task( undefined, types.string, ) - .setAction(async function (taskArguments: TaskArguments, hre) { + .setAction(async function(taskArguments: TaskArguments, hre) { const enclave = await hre.deployments.get("Enclave"); const enclaveContract = await hre.ethers.getContractAt( @@ -111,21 +111,6 @@ task( MockDecryptionVerifier.address, 32, ); - - // since we are using mock, we need to set the decryption verifier to the mock encryption scheme id - // try { - // const setDecryptionVerifier = - // await enclaveContract.setDecryptionVerifier( - // "0x0000000000000000000000000000000000000000000000000000000000000001", - // MockDecryptionVerifier.address, - // ); - // await setDecryptionVerifier.wait(); - // } catch (e) { - // console.log( - // "Setting decryption verifier for encryption scheme id failed: ", - // e, - // ); - // } } try { @@ -166,7 +151,7 @@ task("committee:publish", "Publish the publickey of the committee") types.string, ) .addParam("publicKey", "public key of the committee", undefined, types.string) - .setAction(async function (taskArguments: TaskArguments, hre) { + .setAction(async function(taskArguments: TaskArguments, hre) { let filterAddress = taskArguments.filter; if (!taskArguments.filter) { filterAddress = (await hre.deployments.get("NaiveRegistryFilter")) @@ -203,7 +188,7 @@ task("committee:publish", "Publish the publickey of the committee") task("e3:activate", "Activate an E3 program") .addParam("e3Id", "Id of the E3 program") - .setAction(async function (taskArguments: TaskArguments, hre) { + .setAction(async function(taskArguments: TaskArguments, hre) { const enclave = await hre.deployments.get("Enclave"); const enclaveContract = await hre.ethers.getContractAt( @@ -223,7 +208,7 @@ task("e3:publishInput", "Publish input for an E3 program") .addParam("e3Id", "Id of the E3 program") .addOptionalParam("data", "data to publish") .addOptionalParam("dataFile", "file containing data to publish") - .setAction(async function (taskArguments: TaskArguments, hre) { + .setAction(async function(taskArguments: TaskArguments, hre) { const enclave = await hre.deployments.get("Enclave"); const enclaveContract = await hre.ethers.getContractAt( @@ -251,7 +236,7 @@ task("e3:publishCiphertext", "Publish ciphertext output for an E3 program") .addOptionalParam("data", "data to publish") .addOptionalParam("dataFile", "file containing data to publish") .addParam("proof", "proof to publish") - .setAction(async function (taskArguments: TaskArguments, hre) { + .setAction(async function(taskArguments: TaskArguments, hre) { const enclave = await hre.deployments.get("Enclave"); const enclaveContract = await hre.ethers.getContractAt( @@ -263,7 +248,7 @@ task("e3:publishCiphertext", "Publish ciphertext output for an E3 program") if (taskArguments.dataFile) { const file = fs.readFileSync(taskArguments.dataFile); - data = file.toString(); + data = "0x" + file.toString("hex"); } const tx = await enclaveContract.publishCiphertextOutput( @@ -283,7 +268,7 @@ task("e3:publishPlaintext", "Publish plaintext output for an E3 program") .addOptionalParam("data", "data to publish") .addOptionalParam("dataFile", "file containing data to publish") .addParam("proof", "proof to publish") - .setAction(async function (taskArguments: TaskArguments, hre) { + .setAction(async function(taskArguments: TaskArguments, hre) { const enclave = await hre.deployments.get("Enclave"); const enclaveContract = await hre.ethers.getContractAt( diff --git a/tests/basic_integration/run.sh b/tests/basic_integration/test.sh similarity index 97% rename from tests/basic_integration/run.sh rename to tests/basic_integration/test.sh index 80271b6f..fd9f88e9 100755 --- a/tests/basic_integration/run.sh +++ b/tests/basic_integration/test.sh @@ -122,7 +122,7 @@ sleep 2 heading "Publish ciphertext to EVM" -yarn e3:publishCiphertext --e3-id 0 --network localhost --data "0x$(xxd -p -c 0 $SCRIPT_DIR/output/output.bin)" --proof 0x12345678 +yarn e3:publishCiphertext --e3-id 0 --network localhost --data-file "$SCRIPT_DIR/output/output.bin" --proof 0x12345678 sleep 10 From 8845ded9257b0b22e49c7809ed8382affecc722c Mon Sep 17 00:00:00 2001 From: ryardley Date: Thu, 26 Sep 2024 10:41:26 +1000 Subject: [PATCH 24/35] formatting --- packages/evm/tasks/enclave.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/evm/tasks/enclave.ts b/packages/evm/tasks/enclave.ts index 2d1b11c6..c6f3d5c2 100644 --- a/packages/evm/tasks/enclave.ts +++ b/packages/evm/tasks/enclave.ts @@ -60,7 +60,7 @@ task( undefined, types.string, ) - .setAction(async function(taskArguments: TaskArguments, hre) { + .setAction(async function (taskArguments: TaskArguments, hre) { const enclave = await hre.deployments.get("Enclave"); const enclaveContract = await hre.ethers.getContractAt( @@ -151,7 +151,7 @@ task("committee:publish", "Publish the publickey of the committee") types.string, ) .addParam("publicKey", "public key of the committee", undefined, types.string) - .setAction(async function(taskArguments: TaskArguments, hre) { + .setAction(async function (taskArguments: TaskArguments, hre) { let filterAddress = taskArguments.filter; if (!taskArguments.filter) { filterAddress = (await hre.deployments.get("NaiveRegistryFilter")) @@ -188,7 +188,7 @@ task("committee:publish", "Publish the publickey of the committee") task("e3:activate", "Activate an E3 program") .addParam("e3Id", "Id of the E3 program") - .setAction(async function(taskArguments: TaskArguments, hre) { + .setAction(async function (taskArguments: TaskArguments, hre) { const enclave = await hre.deployments.get("Enclave"); const enclaveContract = await hre.ethers.getContractAt( @@ -208,7 +208,7 @@ task("e3:publishInput", "Publish input for an E3 program") .addParam("e3Id", "Id of the E3 program") .addOptionalParam("data", "data to publish") .addOptionalParam("dataFile", "file containing data to publish") - .setAction(async function(taskArguments: TaskArguments, hre) { + .setAction(async function (taskArguments: TaskArguments, hre) { const enclave = await hre.deployments.get("Enclave"); const enclaveContract = await hre.ethers.getContractAt( From 077049a1718b3e2940f1f98f943b5a88173b9cb6 Mon Sep 17 00:00:00 2001 From: ryardley Date: Thu, 26 Sep 2024 10:43:00 +1000 Subject: [PATCH 25/35] Rename file --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7f4af963..a32dc695 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "lint": "yarn evm:lint", "typechain": "yarn evm:typechain", "test": "yarn evm:test && yarn ciphernode:test", - "test:integration": "./tests/basic_integration/run.sh", + "test:integration": "./tests/basic_integration/test.sh", "coverage": "yarn evm:coverage", "ciphernode:launch": "cd packages/ciphernode && ./scripts/launch.sh", "ciphernode:add": "cd packages/evm && yarn ciphernode:add", From f94252ba18359510306628f23598b197b81ee04a Mon Sep 17 00:00:00 2001 From: ryardley Date: Thu, 26 Sep 2024 12:53:31 +1000 Subject: [PATCH 26/35] Apply code rabbit suggestions --- packages/ciphernode/Cargo.lock | 753 +++--------------- .../ciphernode/core/src/cipernode_selector.rs | 2 +- .../ciphernode/core/src/committee_meta.rs | 2 +- packages/ciphernode/core/src/events.rs | 10 +- .../core/src/evm_ciphernode_registry.rs | 33 +- packages/ciphernode/core/src/evm_enclave.rs | 8 +- packages/ciphernode/core/src/logger.rs | 2 - .../core/src/plaintext_aggregator.rs | 8 +- .../ciphernode/core/src/plaintext_writer.rs | 3 + .../core/src/publickey_aggregator.rs | 8 +- packages/ciphernode/enclave_node/src/main.rs | 11 +- packages/ciphernode/rust-toolchain.toml | 2 + packages/ciphernode/scripts/aggregator.sh | 4 +- packages/ciphernode/scripts/launch.sh | 4 +- packages/ciphernode/scripts/test_encryptor.sh | 4 +- packages/ciphernode/sortition/Cargo.toml | 2 +- packages/ciphernode/sortition/src/distance.rs | 34 +- packages/evm/deploy/mocks.ts | 1 + tests/basic_integration/lib/fake_encrypt.sh | 4 +- 19 files changed, 180 insertions(+), 715 deletions(-) create mode 100644 packages/ciphernode/rust-toolchain.toml diff --git a/packages/ciphernode/Cargo.lock b/packages/ciphernode/Cargo.lock index a8129f0a..028fdc22 100644 --- a/packages/ciphernode/Cargo.lock +++ b/packages/ciphernode/Cargo.lock @@ -136,54 +136,29 @@ version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" -[[package]] -name = "alloy" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f4a4aaae80afd4be443a6aecd92a6b255dcdd000f97996928efb33d8a71e100" -dependencies = [ - "alloy-consensus 0.2.1", - "alloy-contract 0.2.1", - "alloy-core 0.7.7", - "alloy-eips 0.2.1", - "alloy-genesis 0.2.1", - "alloy-network 0.2.1", - "alloy-provider 0.2.1", - "alloy-pubsub 0.2.1", - "alloy-rpc-client 0.2.1", - "alloy-rpc-types 0.2.1", - "alloy-serde 0.2.1", - "alloy-signer 0.2.1", - "alloy-signer-local 0.2.1", - "alloy-transport 0.2.1", - "alloy-transport-http 0.2.1", - "alloy-transport-ipc 0.2.1", - "alloy-transport-ws 0.2.1", -] - [[package]] name = "alloy" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c37d89f69cb43901949ba29307ada8b9e3b170f94057ad4c04d6fd169d24d65f" dependencies = [ - "alloy-consensus 0.3.3", - "alloy-contract 0.3.3", - "alloy-core 0.8.3", - "alloy-eips 0.3.3", - "alloy-genesis 0.3.3", - "alloy-network 0.3.3", - "alloy-provider 0.3.3", - "alloy-pubsub 0.3.5", - "alloy-rpc-client 0.3.3", - "alloy-rpc-types 0.3.5", - "alloy-serde 0.3.3", - "alloy-signer 0.3.3", - "alloy-signer-local 0.3.5", - "alloy-transport 0.3.3", - "alloy-transport-http 0.3.3", - "alloy-transport-ipc 0.3.5", - "alloy-transport-ws 0.3.5", + "alloy-consensus", + "alloy-contract", + "alloy-core", + "alloy-eips", + "alloy-genesis", + "alloy-network", + "alloy-provider", + "alloy-pubsub", + "alloy-rpc-client", + "alloy-rpc-types", + "alloy-serde", + "alloy-signer", + "alloy-signer-local", + "alloy-transport", + "alloy-transport-http", + "alloy-transport-ipc", + "alloy-transport-ws", ] [[package]] @@ -196,126 +171,62 @@ dependencies = [ "strum", ] -[[package]] -name = "alloy-consensus" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c309895995eaa4bfcc345f5515a39c7df9447798645cc8bf462b6c5bf1dc96" -dependencies = [ - "alloy-eips 0.2.1", - "alloy-primitives 0.7.7", - "alloy-rlp", - "alloy-serde 0.2.1", - "c-kzg", - "serde", -] - [[package]] name = "alloy-consensus" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1468e3128e07c7afe4ff13c17e8170c330d12c322f8924b8bf6986a27e0aad3d" dependencies = [ - "alloy-eips 0.3.3", + "alloy-eips", "alloy-primitives 0.8.3", "alloy-rlp", - "alloy-serde 0.3.3", + "alloy-serde", "c-kzg", "serde", ] -[[package]] -name = "alloy-contract" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f4e0ef72b0876ae3068b2ed7dfae9ae1779ce13cfaec2ee1f08f5bd0348dc57" -dependencies = [ - "alloy-dyn-abi 0.7.7", - "alloy-json-abi 0.7.7", - "alloy-network 0.2.1", - "alloy-network-primitives 0.2.1", - "alloy-primitives 0.7.7", - "alloy-provider 0.2.1", - "alloy-pubsub 0.2.1", - "alloy-rpc-types-eth 0.2.1", - "alloy-sol-types 0.7.7", - "alloy-transport 0.2.1", - "futures", - "futures-util", - "thiserror", -] - [[package]] name = "alloy-contract" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "335d62de1a887f1b780441f8a3037f39c9fb26839cc9acd891c9b80396145cd5" dependencies = [ - "alloy-dyn-abi 0.8.3", - "alloy-json-abi 0.8.3", - "alloy-network 0.3.3", - "alloy-network-primitives 0.3.3", + "alloy-dyn-abi", + "alloy-json-abi", + "alloy-network", + "alloy-network-primitives", "alloy-primitives 0.8.3", - "alloy-provider 0.3.3", - "alloy-pubsub 0.3.5", - "alloy-rpc-types-eth 0.3.3", + "alloy-provider", + "alloy-pubsub", + "alloy-rpc-types-eth", "alloy-sol-types 0.8.3", - "alloy-transport 0.3.3", + "alloy-transport", "futures", "futures-util", "thiserror", ] -[[package]] -name = "alloy-core" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "529fc6310dc1126c8de51c376cbc59c79c7f662bd742be7dc67055d5421a81b4" -dependencies = [ - "alloy-dyn-abi 0.7.7", - "alloy-json-abi 0.7.7", - "alloy-primitives 0.7.7", - "alloy-sol-types 0.7.7", -] - [[package]] name = "alloy-core" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88b095eb0533144b4497e84a9cc3e44a5c2e3754a3983c0376a55a2f9183a53e" dependencies = [ - "alloy-dyn-abi 0.8.3", - "alloy-json-abi 0.8.3", + "alloy-dyn-abi", + "alloy-json-abi", "alloy-primitives 0.8.3", "alloy-sol-types 0.8.3", ] -[[package]] -name = "alloy-dyn-abi" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413902aa18a97569e60f679c23f46a18db1656d87ab4d4e49d0e1e52042f66df" -dependencies = [ - "alloy-json-abi 0.7.7", - "alloy-primitives 0.7.7", - "alloy-sol-type-parser 0.7.7", - "alloy-sol-types 0.7.7", - "const-hex", - "itoa", - "serde", - "serde_json", - "winnow", -] - [[package]] name = "alloy-dyn-abi" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4004925bff5ba0a11739ae84dbb6601a981ea692f3bd45b626935ee90a6b8471" dependencies = [ - "alloy-json-abi 0.8.3", + "alloy-json-abi", "alloy-primitives 0.8.3", - "alloy-sol-type-parser 0.8.3", + "alloy-sol-type-parser", "alloy-sol-types 0.8.3", "const-hex", "itoa", @@ -347,23 +258,6 @@ dependencies = [ "serde", ] -[[package]] -name = "alloy-eips" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9431c99a3b3fe606ede4b3d4043bdfbcb780c45b8d8d226c3804e2b75cfbe68" -dependencies = [ - "alloy-primitives 0.7.7", - "alloy-rlp", - "alloy-serde 0.2.1", - "c-kzg", - "derive_more 0.99.18", - "k256", - "once_cell", - "serde", - "sha2", -] - [[package]] name = "alloy-eips" version = "0.3.3" @@ -374,7 +268,7 @@ dependencies = [ "alloy-eip7702", "alloy-primitives 0.8.3", "alloy-rlp", - "alloy-serde 0.3.3", + "alloy-serde", "c-kzg", "derive_more 1.0.0", "once_cell", @@ -382,17 +276,6 @@ dependencies = [ "sha2", ] -[[package]] -name = "alloy-genesis" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79614dfe86144328da11098edcc7bc1a3f25ad8d3134a9eb9e857e06f0d9840d" -dependencies = [ - "alloy-primitives 0.7.7", - "alloy-serde 0.2.1", - "serde", -] - [[package]] name = "alloy-genesis" version = "0.3.3" @@ -400,20 +283,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7210f9206c0fa2a83c824cf8cb6c962126bc9fdc4f41ade1932f14150ef5f6" dependencies = [ "alloy-primitives 0.8.3", - "alloy-serde 0.3.3", - "serde", -] - -[[package]] -name = "alloy-json-abi" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc05b04ac331a9f07e3a4036ef7926e49a8bf84a99a1ccfc7e2ab55a5fcbb372" -dependencies = [ - "alloy-primitives 0.7.7", - "alloy-sol-type-parser 0.7.7", + "alloy-serde", "serde", - "serde_json", ] [[package]] @@ -423,25 +294,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9996daf962fd0a90d3c93b388033228865953b92de7bb1959b891d78750a4091" dependencies = [ "alloy-primitives 0.8.3", - "alloy-sol-type-parser 0.8.3", + "alloy-sol-type-parser", "serde", "serde_json", ] -[[package]] -name = "alloy-json-rpc" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e2865c4c3bb4cdad3f0d9ec1ab5c0c657ba69a375651bd35e32fb6c180ccc2" -dependencies = [ - "alloy-primitives 0.7.7", - "alloy-sol-types 0.7.7", - "serde", - "serde_json", - "thiserror", - "tracing", -] - [[package]] name = "alloy-json-rpc" version = "0.3.3" @@ -456,41 +313,20 @@ dependencies = [ "tracing", ] -[[package]] -name = "alloy-network" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e701fc87ef9a3139154b0b4ccb935b565d27ffd9de020fe541bf2dec5ae4ede" -dependencies = [ - "alloy-consensus 0.2.1", - "alloy-eips 0.2.1", - "alloy-json-rpc 0.2.1", - "alloy-network-primitives 0.2.1", - "alloy-primitives 0.7.7", - "alloy-rpc-types-eth 0.2.1", - "alloy-serde 0.2.1", - "alloy-signer 0.2.1", - "alloy-sol-types 0.7.7", - "async-trait", - "auto_impl", - "futures-utils-wasm", - "thiserror", -] - [[package]] name = "alloy-network" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abe714e233f9eaf410de95a9af6bcd05d3a7f8c8de7a0817221e95a6b642a080" dependencies = [ - "alloy-consensus 0.3.3", - "alloy-eips 0.3.3", - "alloy-json-rpc 0.3.3", - "alloy-network-primitives 0.3.3", + "alloy-consensus", + "alloy-eips", + "alloy-json-rpc", + "alloy-network-primitives", "alloy-primitives 0.8.3", - "alloy-rpc-types-eth 0.3.3", - "alloy-serde 0.3.3", - "alloy-signer 0.3.3", + "alloy-rpc-types-eth", + "alloy-serde", + "alloy-signer", "alloy-sol-types 0.8.3", "async-trait", "auto_impl", @@ -498,26 +334,15 @@ dependencies = [ "thiserror", ] -[[package]] -name = "alloy-network-primitives" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec9d5a0f9170b10988b6774498a022845e13eda94318440d17709d50687f67f9" -dependencies = [ - "alloy-primitives 0.7.7", - "alloy-serde 0.2.1", - "serde", -] - [[package]] name = "alloy-network-primitives" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c5a38117974c5776a45e140226745a0b664f79736aa900995d8e4121558e064" dependencies = [ - "alloy-eips 0.3.3", + "alloy-eips", "alloy-primitives 0.8.3", - "alloy-serde 0.3.3", + "alloy-serde", "serde", ] @@ -543,28 +368,6 @@ dependencies = [ "tiny-keccak", ] -[[package]] -name = "alloy-primitives" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccb3ead547f4532bc8af961649942f0b9c16ee9226e26caa3f38420651cc0bf4" -dependencies = [ - "alloy-rlp", - "bytes", - "cfg-if", - "const-hex", - "derive_more 0.99.18", - "hex-literal", - "itoa", - "k256", - "keccak-asm", - "proptest", - "rand", - "ruint", - "serde", - "tiny-keccak", -] - [[package]] name = "alloy-primitives" version = "0.8.3" @@ -587,42 +390,6 @@ dependencies = [ "tiny-keccak", ] -[[package]] -name = "alloy-provider" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9c0ab10b93de601a6396fc7ff2ea10d3b28c46f079338fa562107ebf9857c8" -dependencies = [ - "alloy-chains", - "alloy-consensus 0.2.1", - "alloy-eips 0.2.1", - "alloy-json-rpc 0.2.1", - "alloy-network 0.2.1", - "alloy-network-primitives 0.2.1", - "alloy-primitives 0.7.7", - "alloy-pubsub 0.2.1", - "alloy-rpc-client 0.2.1", - "alloy-rpc-types-eth 0.2.1", - "alloy-transport 0.2.1", - "alloy-transport-http 0.2.1", - "alloy-transport-ipc 0.2.1", - "alloy-transport-ws 0.2.1", - "async-stream", - "async-trait", - "auto_impl", - "dashmap 5.5.3", - "futures", - "futures-utils-wasm", - "lru", - "pin-project", - "reqwest", - "serde", - "serde_json", - "tokio", - "tracing", - "url", -] - [[package]] name = "alloy-provider" version = "0.3.3" @@ -630,23 +397,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c65633d6ef83c3626913c004eaf166a6dd50406f724772ea8567135efd6dc5d3" dependencies = [ "alloy-chains", - "alloy-consensus 0.3.3", - "alloy-eips 0.3.3", - "alloy-json-rpc 0.3.3", - "alloy-network 0.3.3", - "alloy-network-primitives 0.3.3", + "alloy-consensus", + "alloy-eips", + "alloy-json-rpc", + "alloy-network", + "alloy-network-primitives", "alloy-primitives 0.8.3", - "alloy-pubsub 0.3.5", - "alloy-rpc-client 0.3.3", - "alloy-rpc-types-eth 0.3.3", - "alloy-transport 0.3.3", - "alloy-transport-http 0.3.3", - "alloy-transport-ipc 0.3.5", - "alloy-transport-ws 0.3.5", + "alloy-pubsub", + "alloy-rpc-client", + "alloy-rpc-types-eth", + "alloy-transport", + "alloy-transport-http", + "alloy-transport-ipc", + "alloy-transport-ws", "async-stream", "async-trait", "auto_impl", - "dashmap 6.1.0", + "dashmap", "futures", "futures-utils-wasm", "lru", @@ -660,34 +427,15 @@ dependencies = [ "url", ] -[[package]] -name = "alloy-pubsub" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f5da2c55cbaf229bad3c5f8b00b5ab66c74ef093e5f3a753d874cfecf7d2281" -dependencies = [ - "alloy-json-rpc 0.2.1", - "alloy-primitives 0.7.7", - "alloy-transport 0.2.1", - "bimap", - "futures", - "serde", - "serde_json", - "tokio", - "tokio-stream", - "tower 0.4.13", - "tracing", -] - [[package]] name = "alloy-pubsub" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34b9f5e85120aab30b8da23354592f7bd2b208d33d3204ffa1d44ac2e3dd5691" dependencies = [ - "alloy-json-rpc 0.3.3", + "alloy-json-rpc", "alloy-primitives 0.8.3", - "alloy-transport 0.3.3", + "alloy-transport", "bimap", "futures", "serde", @@ -720,44 +468,19 @@ dependencies = [ "syn 2.0.72", ] -[[package]] -name = "alloy-rpc-client" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b38e3ffdb285df5d9f60cb988d336d9b8e3505acb78750c3bc60336a7af41d3" -dependencies = [ - "alloy-json-rpc 0.2.1", - "alloy-primitives 0.7.7", - "alloy-pubsub 0.2.1", - "alloy-transport 0.2.1", - "alloy-transport-http 0.2.1", - "alloy-transport-ipc 0.2.1", - "alloy-transport-ws 0.2.1", - "futures", - "pin-project", - "reqwest", - "serde", - "serde_json", - "tokio", - "tokio-stream", - "tower 0.4.13", - "tracing", - "url", -] - [[package]] name = "alloy-rpc-client" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5fc328bb5d440599ba1b5aa44c0b9ab0625fbc3a403bb5ee94ed4a01ba23e07" dependencies = [ - "alloy-json-rpc 0.3.3", + "alloy-json-rpc", "alloy-primitives 0.8.3", - "alloy-pubsub 0.3.5", - "alloy-transport 0.3.3", - "alloy-transport-http 0.3.3", - "alloy-transport-ipc 0.3.5", - "alloy-transport-ws 0.3.5", + "alloy-pubsub", + "alloy-transport", + "alloy-transport-http", + "alloy-transport-ipc", + "alloy-transport-ws", "futures", "pin-project", "reqwest", @@ -770,46 +493,16 @@ dependencies = [ "url", ] -[[package]] -name = "alloy-rpc-types" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c31a3750b8f5a350d17354e46a52b0f2f19ec5f2006d816935af599dedc521" -dependencies = [ - "alloy-rpc-types-engine 0.2.1", - "alloy-rpc-types-eth 0.2.1", - "alloy-serde 0.2.1", - "serde", -] - [[package]] name = "alloy-rpc-types" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22045187a5ebf5b2af3f8b6831b66735b6556c5750ec5790aeeb45935260c1c2" dependencies = [ - "alloy-rpc-types-engine 0.3.5", - "alloy-rpc-types-eth 0.3.3", - "alloy-serde 0.3.3", - "serde", -] - -[[package]] -name = "alloy-rpc-types-engine" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff63f51b2fb2f547df5218527fd0653afb1947bf7fead5b3ce58c75d170b30f7" -dependencies = [ - "alloy-consensus 0.2.1", - "alloy-eips 0.2.1", - "alloy-primitives 0.7.7", - "alloy-rlp", - "alloy-rpc-types-eth 0.2.1", - "alloy-serde 0.2.1", - "jsonwebtoken", - "rand", + "alloy-rpc-types-engine", + "alloy-rpc-types-eth", + "alloy-serde", "serde", - "thiserror", ] [[package]] @@ -818,44 +511,25 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c031a91e94a39f928244bc837c953817be5b8cc61759e1a9123b3abd17560dd" dependencies = [ - "alloy-consensus 0.3.3", - "alloy-eips 0.3.3", + "alloy-consensus", + "alloy-eips", "alloy-primitives 0.8.3", "alloy-rlp", "derive_more 1.0.0", ] -[[package]] -name = "alloy-rpc-types-eth" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81e18424d962d7700a882fe423714bd5b9dde74c7a7589d4255ea64068773aef" -dependencies = [ - "alloy-consensus 0.2.1", - "alloy-eips 0.2.1", - "alloy-network-primitives 0.2.1", - "alloy-primitives 0.7.7", - "alloy-rlp", - "alloy-serde 0.2.1", - "alloy-sol-types 0.7.7", - "itertools 0.13.0", - "serde", - "serde_json", - "thiserror", -] - [[package]] name = "alloy-rpc-types-eth" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a59b1d7c86e0a653e7f3d29954f6de5a2878d8cfd1f010ff93be5c2c48cd3b1" dependencies = [ - "alloy-consensus 0.3.3", - "alloy-eips 0.3.3", - "alloy-network-primitives 0.3.3", + "alloy-consensus", + "alloy-eips", + "alloy-network-primitives", "alloy-primitives 0.8.3", "alloy-rlp", - "alloy-serde 0.3.3", + "alloy-serde", "alloy-sol-types 0.8.3", "itertools 0.13.0", "serde", @@ -863,17 +537,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "alloy-serde" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33feda6a53e6079895aed1d08dcb98a1377b000d80d16370fbbdb8155d547ef" -dependencies = [ - "alloy-primitives 0.7.7", - "serde", - "serde_json", -] - [[package]] name = "alloy-serde" version = "0.3.3" @@ -885,20 +548,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "alloy-signer" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740a25b92e849ed7b0fa013951fe2f64be9af1ad5abe805037b44fb7770c5c47" -dependencies = [ - "alloy-primitives 0.7.7", - "async-trait", - "auto_impl", - "elliptic-curve", - "k256", - "thiserror", -] - [[package]] name = "alloy-signer" version = "0.3.3" @@ -913,32 +562,16 @@ dependencies = [ "thiserror", ] -[[package]] -name = "alloy-signer-local" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b0707d4f63e4356a110b30ef3add8732ab6d181dd7be4607bf79b8777105cee" -dependencies = [ - "alloy-consensus 0.2.1", - "alloy-network 0.2.1", - "alloy-primitives 0.7.7", - "alloy-signer 0.2.1", - "async-trait", - "k256", - "rand", - "thiserror", -] - [[package]] name = "alloy-signer-local" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99e250010dce0e3caf6a6033e809718e5921391d937d1cbbcffe52653b37cc63" dependencies = [ - "alloy-consensus 0.3.3", - "alloy-network 0.3.3", + "alloy-consensus", + "alloy-network", "alloy-primitives 0.8.3", - "alloy-signer 0.3.3", + "alloy-signer", "async-trait", "k256", "rand", @@ -963,61 +596,28 @@ dependencies = [ "tiny-keccak", ] -[[package]] -name = "alloy-sol-macro" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b40397ddcdcc266f59f959770f601ce1280e699a91fc1862f29cef91707cd09" -dependencies = [ - "alloy-sol-macro-expander 0.7.7", - "alloy-sol-macro-input 0.7.7", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.72", -] - [[package]] name = "alloy-sol-macro" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0458ccb02a564228fcd76efb8eb5a520521a8347becde37b402afec9a1b83859" dependencies = [ - "alloy-sol-macro-expander 0.8.3", - "alloy-sol-macro-input 0.8.3", + "alloy-sol-macro-expander", + "alloy-sol-macro-input", "proc-macro-error2", "proc-macro2", "quote", "syn 2.0.72", ] -[[package]] -name = "alloy-sol-macro-expander" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "867a5469d61480fea08c7333ffeca52d5b621f5ca2e44f271b117ec1fc9a0525" -dependencies = [ - "alloy-json-abi 0.7.7", - "alloy-sol-macro-input 0.7.7", - "const-hex", - "heck 0.5.0", - "indexmap", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.72", - "syn-solidity 0.7.7", - "tiny-keccak", -] - [[package]] name = "alloy-sol-macro-expander" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bc65475025fc1e84bf86fc840f04f63fcccdcf3cf12053c99918e4054dfbc69" dependencies = [ - "alloy-json-abi 0.8.3", - "alloy-sol-macro-input 0.8.3", + "alloy-json-abi", + "alloy-sol-macro-input", "const-hex", "heck 0.5.0", "indexmap", @@ -1029,30 +629,13 @@ dependencies = [ "tiny-keccak", ] -[[package]] -name = "alloy-sol-macro-input" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e482dc33a32b6fadbc0f599adea520bd3aaa585c141a80b404d0a3e3fa72528" -dependencies = [ - "alloy-json-abi 0.7.7", - "const-hex", - "dunce", - "heck 0.5.0", - "proc-macro2", - "quote", - "serde_json", - "syn 2.0.72", - "syn-solidity 0.7.7", -] - [[package]] name = "alloy-sol-macro-input" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ed10f0715a0b69fde3236ff3b9ae5f6f7c97db5a387747100070d3016b9266b" dependencies = [ - "alloy-json-abi 0.8.3", + "alloy-json-abi", "const-hex", "dunce", "heck 0.5.0", @@ -1063,16 +646,6 @@ dependencies = [ "syn-solidity 0.8.3", ] -[[package]] -name = "alloy-sol-type-parser" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbcba3ca07cf7975f15d871b721fb18031eec8bce51103907f6dcce00b255d98" -dependencies = [ - "serde", - "winnow", -] - [[package]] name = "alloy-sol-type-parser" version = "0.8.3" @@ -1095,58 +668,26 @@ dependencies = [ "serde", ] -[[package]] -name = "alloy-sol-types" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91ca40fa20793ae9c3841b83e74569d1cc9af29a2f5237314fd3452d51e38c7" -dependencies = [ - "alloy-json-abi 0.7.7", - "alloy-primitives 0.7.7", - "alloy-sol-macro 0.7.7", - "const-hex", - "serde", -] - [[package]] name = "alloy-sol-types" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1eb88e4da0a1b697ed6a9f811fdba223cf4d5c21410804fd1707836af73a462b" dependencies = [ - "alloy-json-abi 0.8.3", + "alloy-json-abi", "alloy-primitives 0.8.3", "alloy-sol-macro 0.8.3", "const-hex", "serde", ] -[[package]] -name = "alloy-transport" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0590afbdacf2f8cca49d025a2466f3b6584a016a8b28f532f29f8da1007bae" -dependencies = [ - "alloy-json-rpc 0.2.1", - "base64 0.22.1", - "futures-util", - "futures-utils-wasm", - "serde", - "serde_json", - "thiserror", - "tokio", - "tower 0.4.13", - "tracing", - "url", -] - [[package]] name = "alloy-transport" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd5dc4e902f1860d54952446d246ac05386311ad61030a2b906ae865416d36e0" dependencies = [ - "alloy-json-rpc 0.3.3", + "alloy-json-rpc", "base64 0.22.1", "futures-util", "futures-utils-wasm", @@ -1159,29 +700,14 @@ dependencies = [ "url", ] -[[package]] -name = "alloy-transport-http" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2437d145d80ea1aecde8574d2058cceb8b3c9cba05f6aea8e67907c660d46698" -dependencies = [ - "alloy-json-rpc 0.2.1", - "alloy-transport 0.2.1", - "reqwest", - "serde_json", - "tower 0.4.13", - "tracing", - "url", -] - [[package]] name = "alloy-transport-http" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1742b94bb814f1ca6b322a6f9dd38a0252ff45a3119e40e888fb7029afa500ce" dependencies = [ - "alloy-json-rpc 0.3.3", - "alloy-transport 0.3.3", + "alloy-json-rpc", + "alloy-transport", "reqwest", "serde_json", "tower 0.5.1", @@ -1189,34 +715,15 @@ dependencies = [ "url", ] -[[package]] -name = "alloy-transport-ipc" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804494366e20468776db4e18f9eb5db7db0fe14f1271eb6dbf155d867233405c" -dependencies = [ - "alloy-json-rpc 0.2.1", - "alloy-pubsub 0.2.1", - "alloy-transport 0.2.1", - "bytes", - "futures", - "interprocess", - "pin-project", - "serde_json", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "alloy-transport-ipc" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aa02db8751f9c0c37caf8c38ad3eb7aa1cfb09cfea3451a13aacaf06846c7a5" dependencies = [ - "alloy-json-rpc 0.3.3", - "alloy-pubsub 0.3.5", - "alloy-transport 0.3.3", + "alloy-json-rpc", + "alloy-pubsub", + "alloy-transport", "bytes", "futures", "interprocess", @@ -1227,32 +734,14 @@ dependencies = [ "tracing", ] -[[package]] -name = "alloy-transport-ws" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af855163e7df008799941aa6dd324a43ef2bf264b08ba4b22d44aad6ced65300" -dependencies = [ - "alloy-pubsub 0.2.1", - "alloy-transport 0.2.1", - "futures", - "http 1.1.0", - "rustls", - "serde_json", - "tokio", - "tokio-tungstenite", - "tracing", - "ws_stream_wasm", -] - [[package]] name = "alloy-transport-ws" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0a5c4a0929479bcb85a2df628c01173618a71c807b2f499939a236dbde5d008" dependencies = [ - "alloy-pubsub 0.3.5", - "alloy-transport 0.3.3", + "alloy-pubsub", + "alloy-transport", "futures", "http 1.1.0", "rustls", @@ -2275,19 +1764,6 @@ dependencies = [ "syn 2.0.72", ] -[[package]] -name = "dashmap" -version = "5.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" -dependencies = [ - "cfg-if", - "hashbrown", - "lock_api", - "once_cell", - "parking_lot_core", -] - [[package]] name = "dashmap" version = "6.1.0" @@ -2542,7 +2018,7 @@ version = "0.1.0" dependencies = [ "actix", "actix-rt", - "alloy 0.3.3", + "alloy", "alloy-primitives 0.6.4", "alloy-sol-types 0.6.4", "anyhow", @@ -2571,7 +2047,7 @@ name = "enclave_node" version = "0.1.0" dependencies = [ "actix-rt", - "alloy 0.3.3", + "alloy", "alloy-primitives 0.6.4", "async-std", "base64 0.22.1", @@ -3012,10 +2488,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi", - "wasm-bindgen", ] [[package]] @@ -3574,21 +3048,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "jsonwebtoken" -version = "9.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f" -dependencies = [ - "base64 0.21.7", - "js-sys", - "pem", - "ring 0.17.8", - "serde", - "serde_json", - "simple_asn1", -] - [[package]] name = "k256" version = "0.13.3" @@ -5884,18 +5343,6 @@ dependencies = [ "rand_core", ] -[[package]] -name = "simple_asn1" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" -dependencies = [ - "num-bigint", - "num-traits", - "thiserror", - "time", -] - [[package]] name = "slab" version = "0.4.9" @@ -5969,7 +5416,7 @@ dependencies = [ name = "sortition" version = "0.1.0" dependencies = [ - "alloy 0.2.1", + "alloy", "alloy-primitives 0.6.4", "alloy-sol-types 0.6.4", "eyre", @@ -6074,18 +5521,6 @@ dependencies = [ "syn 2.0.72", ] -[[package]] -name = "syn-solidity" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c837dc8852cb7074e46b444afb81783140dab12c58867b49fb3898fbafedf7ea" -dependencies = [ - "paste", - "proc-macro2", - "quote", - "syn 2.0.72", -] - [[package]] name = "syn-solidity" version = "0.8.3" @@ -6379,7 +5814,6 @@ dependencies = [ "tokio", "tower-layer", "tower-service", - "tracing", ] [[package]] @@ -6414,7 +5848,6 @@ version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "log", "pin-project-lite", "tracing-attributes", "tracing-core", diff --git a/packages/ciphernode/core/src/cipernode_selector.rs b/packages/ciphernode/core/src/cipernode_selector.rs index 975b2019..3c31667d 100644 --- a/packages/ciphernode/core/src/cipernode_selector.rs +++ b/packages/ciphernode/core/src/cipernode_selector.rs @@ -49,7 +49,7 @@ impl Handler for CiphernodeSelector { }; let seed = data.seed; - let size = data.threshold_m as usize; + let size = data.threshold_m; if let Ok(is_selected) = sortition .send(GetHasNode { diff --git a/packages/ciphernode/core/src/committee_meta.rs b/packages/ciphernode/core/src/committee_meta.rs index 7748bb48..5cd42b57 100644 --- a/packages/ciphernode/core/src/committee_meta.rs +++ b/packages/ciphernode/core/src/committee_meta.rs @@ -2,7 +2,7 @@ use crate::{ActorFactory, E3Requested, EnclaveEvent}; #[derive(Clone, Debug, PartialEq, Eq)] pub struct CommitteeMeta { - pub threshold_m: u32, + pub threshold_m: usize, pub seed: u64, } diff --git a/packages/ciphernode/core/src/events.rs b/packages/ciphernode/core/src/events.rs index 7edc206b..d61ee000 100644 --- a/packages/ciphernode/core/src/events.rs +++ b/packages/ciphernode/core/src/events.rs @@ -32,6 +32,12 @@ impl From for E3id { } } +impl From<&str> for E3id { + fn from(value: &str) -> Self { + E3id::new(value) + } +} + #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct EventId(pub [u8; 32]); @@ -267,7 +273,7 @@ pub struct PublicKeyAggregated { #[rtype(result = "()")] pub struct E3Requested { pub e3_id: E3id, - pub threshold_m: u32, + pub threshold_m: usize, pub seed: u64, // Should actually be much larger eg [u8;32] // fhe params @@ -286,7 +292,7 @@ pub struct E3Requested { #[rtype(result = "()")] pub struct CiphernodeSelected { pub e3_id: E3id, - pub threshold_m: u32, + pub threshold_m: usize, } #[derive(Message, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] diff --git a/packages/ciphernode/core/src/evm_ciphernode_registry.rs b/packages/ciphernode/core/src/evm_ciphernode_registry.rs index 9023929d..b6f9f209 100644 --- a/packages/ciphernode/core/src/evm_ciphernode_registry.rs +++ b/packages/ciphernode/core/src/evm_ciphernode_registry.rs @@ -30,8 +30,15 @@ impl From for events::CiphernodeAdded { fn from(value: CiphernodeAdded) -> Self { events::CiphernodeAdded { address: value.node.to_string(), - index: value.index.as_limbs()[0] as usize, - num_nodes: value.numNodes.as_limbs()[0] as usize, + // TODO: limit index and numNodes to uint32 at the solidity level + index: value + .index + .try_into() + .expect("Index exceeds usize capacity"), + num_nodes: value + .numNodes + .try_into() + .expect("NumNodes exceeds usize capacity"), } } } @@ -40,8 +47,14 @@ impl From for events::CiphernodeRemoved { fn from(value: CiphernodeRemoved) -> Self { events::CiphernodeRemoved { address: value.node.to_string(), - index: value.index.as_limbs()[0] as usize, - num_nodes: value.numNodes.as_limbs()[0] as usize, + index: value + .index + .try_into() + .expect("Index exceeds usize capacity"), + num_nodes: value + .numNodes + .try_into() + .expect("NumNodes exceeds usize capacity"), } } } @@ -66,24 +79,22 @@ pub async fn connect_evm_ciphernode_registry( bus: Addr, rpc_url: &str, contract_address: Address, -) { +) -> Result<()> { let evm_manager = EvmContractManager::attach(bus.clone(), rpc_url).await; let evm_listener = evm_manager .send(AddListener { contract_address }) - .await - .unwrap(); + .await?; evm_listener .send(AddEventHandler::::new()) - .await - .unwrap(); + .await?; evm_listener .send(AddEventHandler::::new()) - .await - .unwrap(); + .await?; evm_listener.do_send(StartListening); println!("Evm is listening to {}", contract_address); + Ok(()) } diff --git a/packages/ciphernode/core/src/evm_enclave.rs b/packages/ciphernode/core/src/evm_enclave.rs index c7c858da..976b6acf 100644 --- a/packages/ciphernode/core/src/evm_enclave.rs +++ b/packages/ciphernode/core/src/evm_enclave.rs @@ -7,7 +7,7 @@ use crate::{ setup_crp_params, EnclaveEvent, EventBus, ParamsWithCrp, }; use actix::Addr; -use alloy::{primitives::Address, sol, sol_types::SolEvent}; +use alloy::{primitives::Address, sol}; use anyhow::Result; use rand::SeedableRng; use rand_chacha::ChaCha20Rng; @@ -62,16 +62,18 @@ impl From for events::E3Requested { &[0x3FFFFFFF000001], 2048, 1032193, + // HACK: This is required to be fixed in order to have the same CRP bytes which will be + // resolved once we are decrypting params from the contract Arc::new(std::sync::Mutex::new(ChaCha20Rng::seed_from_u64(42))), ); events::E3Requested { moduli, plaintext_modulus, degree, - threshold_m: value.e3.threshold[0], + threshold_m: value.e3.threshold[0] as usize, crp: crp_bytes, // HACK: Following should be [u8;32] and not converted to u64 - seed: value.e3.seed.as_limbs()[0], // converting to u64 + seed: value.e3.seed.try_into().unwrap_or_default(), // converting to u64 e3_id: value.e3Id.to_string().into(), } } diff --git a/packages/ciphernode/core/src/logger.rs b/packages/ciphernode/core/src/logger.rs index 22d4f545..43f68984 100644 --- a/packages/ciphernode/core/src/logger.rs +++ b/packages/ciphernode/core/src/logger.rs @@ -1,8 +1,6 @@ use crate::{EnclaveEvent, EventBus, Subscribe}; use actix::{Actor, Addr, Context, Handler}; -use alloy::primitives::Address; use base64::prelude::*; -use std::fs; pub struct SimpleLogger { name: String, diff --git a/packages/ciphernode/core/src/plaintext_aggregator.rs b/packages/ciphernode/core/src/plaintext_aggregator.rs index cb868ce4..9ad82e96 100644 --- a/packages/ciphernode/core/src/plaintext_aggregator.rs +++ b/packages/ciphernode/core/src/plaintext_aggregator.rs @@ -8,7 +8,7 @@ use anyhow::{anyhow, Result}; #[derive(Debug, Clone)] pub enum PlaintextAggregatorState { Collecting { - threshold_m: u32, + threshold_m: usize, shares: OrderedSet>, seed: u64, }, @@ -41,7 +41,7 @@ impl PlaintextAggregator { bus: Addr, sortition: Addr, e3_id: E3id, - threshold_m: u32, + threshold_m: usize, seed: u64, ) -> Self { PlaintextAggregator { @@ -68,7 +68,7 @@ impl PlaintextAggregator { }; shares.insert(share); - if shares.len() == *threshold_m as usize { + if shares.len() == *threshold_m { return Ok(PlaintextAggregatorState::Computing { shares: shares.clone(), }); @@ -113,7 +113,7 @@ impl Handler for PlaintextAggregator { return Box::pin(fut::ready(Ok(()))); }; - let size = threshold_m as usize; + let size = threshold_m; let address = event.node; let e3_id = event.e3_id.clone(); let decryption_share = event.decryption_share.clone(); diff --git a/packages/ciphernode/core/src/plaintext_writer.rs b/packages/ciphernode/core/src/plaintext_writer.rs index 73810578..29ad330b 100644 --- a/packages/ciphernode/core/src/plaintext_writer.rs +++ b/packages/ciphernode/core/src/plaintext_writer.rs @@ -31,6 +31,9 @@ impl Handler for PlaintextWriter { println!("Write plaintext to {}", &self.path); let contents: Vec = output.iter().map(|&num| num.to_string()).collect(); + + // NOTE: panicking is kind of what we want here for now as we don't really need to handle the + // error yet not knowing if this feature will be in production write_file_with_dirs(&self.path, format!("{}", contents.join(",")).as_bytes()) .unwrap(); } diff --git a/packages/ciphernode/core/src/publickey_aggregator.rs b/packages/ciphernode/core/src/publickey_aggregator.rs index 7c184370..4bf14426 100644 --- a/packages/ciphernode/core/src/publickey_aggregator.rs +++ b/packages/ciphernode/core/src/publickey_aggregator.rs @@ -11,7 +11,7 @@ use anyhow::Result; #[derive(Debug, Clone)] pub enum PublicKeyAggregatorState { Collecting { - threshold_m: u32, + threshold_m: usize, keyshares: OrderedSet>, seed: u64, }, @@ -50,7 +50,7 @@ impl PublicKeyAggregator { bus: Addr, sortition: Addr, e3_id: E3id, - threshold_m: u32, + threshold_m: usize, seed: u64, ) -> Self { PublicKeyAggregator { @@ -76,7 +76,7 @@ impl PublicKeyAggregator { return Err(anyhow::anyhow!("Can only add keyshare in Collecting state")); }; keyshares.insert(keyshare); - if keyshares.len() == *threshold_m as usize { + if keyshares.len() == *threshold_m { return Ok(PublicKeyAggregatorState::Computing { keyshares: keyshares.clone(), }); @@ -125,7 +125,7 @@ impl Handler for PublicKeyAggregator { return Box::pin(fut::ready(Ok(()))); }; - let size = threshold_m as usize; + let size = threshold_m; let address = event.node; let e3_id = event.e3_id.clone(); let pubkey = event.pubkey.clone(); diff --git a/packages/ciphernode/enclave_node/src/main.rs b/packages/ciphernode/enclave_node/src/main.rs index 9e5aee83..c2079c01 100644 --- a/packages/ciphernode/enclave_node/src/main.rs +++ b/packages/ciphernode/enclave_node/src/main.rs @@ -1,14 +1,13 @@ use std::error::Error; -use p2p::EnclaveRouter; use bfv::EnclaveBFV; +use p2p::EnclaveRouter; use sortition::DistanceSortition; use tokio::{ self, io::{self, AsyncBufReadExt, BufReader}, }; - -use alloy_primitives::{address}; +use alloy::primitives::address; const OWO: &str = r#" ___ ___ ___ ___ ___ @@ -38,7 +37,11 @@ async fn main() -> Result<(), Box> { println!("\n\n\n\n"); println!("Hello, cipher world!"); - let mut committee = DistanceSortition::new(12, vec![address!("d8da6bf26964af9d7eed9e03e53415d37aa96045")], 10); + let mut committee = DistanceSortition::new( + 12, + vec![address!("d8da6bf26964af9d7eed9e03e53415d37aa96045")], + 10, + ); committee.get_committee(); let mut new_bfv = EnclaveBFV::new(4096, 4096, vec![0xffffee001, 0xffffc4001, 0x1ffffe0001]); diff --git a/packages/ciphernode/rust-toolchain.toml b/packages/ciphernode/rust-toolchain.toml new file mode 100644 index 00000000..4cef0b73 --- /dev/null +++ b/packages/ciphernode/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "1.81" diff --git a/packages/ciphernode/scripts/aggregator.sh b/packages/ciphernode/scripts/aggregator.sh index 78ca9ad7..6f113156 100755 --- a/packages/ciphernode/scripts/aggregator.sh +++ b/packages/ciphernode/scripts/aggregator.sh @@ -1,3 +1,3 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash -RUSTFLAGS="-A warnings" cargo run --bin aggregator -- $@ +RUSTFLAGS="-A warnings" cargo run --bin aggregator -- "$@" diff --git a/packages/ciphernode/scripts/launch.sh b/packages/ciphernode/scripts/launch.sh index 7f1f3844..547e3dbb 100755 --- a/packages/ciphernode/scripts/launch.sh +++ b/packages/ciphernode/scripts/launch.sh @@ -1,3 +1,3 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash -RUSTFLAGS="-A warnings" cargo run --bin node -- $@ +RUSTFLAGS="-A warnings" cargo run --bin node -- "$@" diff --git a/packages/ciphernode/scripts/test_encryptor.sh b/packages/ciphernode/scripts/test_encryptor.sh index cbe41ff2..d9a70485 100644 --- a/packages/ciphernode/scripts/test_encryptor.sh +++ b/packages/ciphernode/scripts/test_encryptor.sh @@ -1,3 +1,3 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash -RUSTFLAGS="-A warnings" cargo run --bin test_encryptor -- $@ +RUSTFLAGS="-A warnings" cargo run --bin test_encryptor -- "$@" diff --git a/packages/ciphernode/sortition/Cargo.toml b/packages/ciphernode/sortition/Cargo.toml index 54704919..5680e858 100644 --- a/packages/ciphernode/sortition/Cargo.toml +++ b/packages/ciphernode/sortition/Cargo.toml @@ -15,6 +15,6 @@ rand = "0.8.5" # Ethereum futures-util = "0.3" eyre = "0.6" -alloy = { version = "0.2.1", features = ["full"] } +alloy = { version = "0.3.3", features = ["full"] } alloy-primitives = { version = "0.6", default-features = false, features = ["rlp", "serde", "std"] } alloy-sol-types = { version = "0.6" } diff --git a/packages/ciphernode/sortition/src/distance.rs b/packages/ciphernode/sortition/src/distance.rs index 79b6bb86..bf11f405 100644 --- a/packages/ciphernode/sortition/src/distance.rs +++ b/packages/ciphernode/sortition/src/distance.rs @@ -1,4 +1,4 @@ -use alloy_primitives::{address, Address, keccak256}; +use alloy::primitives::{keccak256, Address}; use num::{BigInt, Num}; pub struct DistanceSortition { @@ -9,24 +9,30 @@ pub struct DistanceSortition { impl DistanceSortition { pub fn new(random_seed: u64, registered_nodes: Vec
, size: usize) -> Self { - Self { random_seed, registered_nodes, size } + Self { + random_seed, + registered_nodes, + size, + } } pub fn get_committee(&mut self) -> Vec<(BigInt, Address)> { - let mut scores = self.registered_nodes.iter() - .map(|address| - { - let concat = address.to_string() + &self.random_seed.to_string(); - let hash = keccak256(concat).to_string(); - let without_prefix = hash.trim_start_matches("0x"); - let z = BigInt::from_str_radix(without_prefix, 16).unwrap(); - let score = z - BigInt::from(self.random_seed); - (score, *address) - }) + let mut scores = self + .registered_nodes + .iter() + .map(|address| { + let concat = address.to_string() + &self.random_seed.to_string(); + let hash = keccak256(concat).to_string(); + let without_prefix = hash.trim_start_matches("0x"); + let z = BigInt::from_str_radix(without_prefix, 16).unwrap(); + let score = z - BigInt::from(self.random_seed); + (score, *address) + }) .collect::>(); - + scores.sort_by(|a, b| a.0.cmp(&b.0)); let result = scores[0..self.size].to_vec(); result } -} \ No newline at end of file +} + diff --git a/packages/evm/deploy/mocks.ts b/packages/evm/deploy/mocks.ts index 58dae802..7a506487 100644 --- a/packages/evm/deploy/mocks.ts +++ b/packages/evm/deploy/mocks.ts @@ -48,6 +48,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { console.log(`Successfully set MockDecryptionVerifier in Enclave contract`); } catch (error) { console.error("Error setting MockDecryptionVerifier:", error); + process.exit(1); } }; export default func; diff --git a/tests/basic_integration/lib/fake_encrypt.sh b/tests/basic_integration/lib/fake_encrypt.sh index a7b456d2..416d868c 100755 --- a/tests/basic_integration/lib/fake_encrypt.sh +++ b/tests/basic_integration/lib/fake_encrypt.sh @@ -1,3 +1,3 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash -cd packages/ciphernode && RUSTFLAGS="-A warnings" cargo run --bin test_encryptor -- $@ +cd packages/ciphernode && RUSTFLAGS="-A warnings" cargo run --bin test_encryptor -- "$@" From a08755d90e8217d1ddcdf2eeb8d0a81aeee34423 Mon Sep 17 00:00:00 2001 From: ryardley Date: Thu, 26 Sep 2024 13:12:11 +1000 Subject: [PATCH 27/35] exit if not run from root --- tests/basic_integration/test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/basic_integration/test.sh b/tests/basic_integration/test.sh index fd9f88e9..c5b40638 100755 --- a/tests/basic_integration/test.sh +++ b/tests/basic_integration/test.sh @@ -9,6 +9,7 @@ PLAINTEXT="1234,567890" if [[ "$ROOT_DIR" != "$(pwd)" ]]; then echo "This script must be run from the root" + exit 1 fi # Environment variables From d80957d7705240b61eed7c43516c9fcec79a3e35 Mon Sep 17 00:00:00 2001 From: ryardley Date: Thu, 26 Sep 2024 13:49:54 +1000 Subject: [PATCH 28/35] Add waiton and decrease the use of sleep --- tests/basic_integration/test.sh | 53 ++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/tests/basic_integration/test.sh b/tests/basic_integration/test.sh index c5b40638..ac195282 100755 --- a/tests/basic_integration/test.sh +++ b/tests/basic_integration/test.sh @@ -40,6 +40,29 @@ heading() { echo "" } +waiton() { + local file_path="$1" + until [ -f "$file_path" ]; do + sleep 1 + done +} + +waiton-files() { + while true; do + all_exist=true + for file in "$@"; do + if [ ! -f "$file" ]; then + all_exist=false + break + fi + done + if $all_exist; then + break + fi + sleep 1 + done +} + pkill -9 -f "target/debug/node" || true pkill -9 -f "hardhat node" || true pkill -9 -f "target/debug/aggregator" || true @@ -56,7 +79,9 @@ heading "Start the EVM node" yarn evm:node & -sleep 2 +until curl -f -s "http://localhost:8545" > /dev/null; do + sleep 1 +done heading "Launch ciphernode $CIPHERNODE_ADDRESS_1" yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_1 --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT & @@ -72,33 +97,27 @@ yarn ciphernode:launch --address $CIPHERNODE_ADDRESS_4 --rpc "$RPC_URL" --enclav yarn ciphernode:aggregator --rpc "$RPC_URL" --enclave-contract $ENCLAVE_CONTRACT --registry-contract $REGISTRY_CONTRACT --pubkey-write-path "$SCRIPT_DIR/output/pubkey.bin" --plaintext-write-path "$SCRIPT_DIR/output/plaintext.txt" & -sleep 2 +sleep 1 + +waiton-files "$ROOT_DIR/packages/ciphernode/target/debug/node" "$ROOT_DIR/packages/ciphernode/target/debug/aggregator" "$ROOT_DIR/packages/ciphernode/target/debug/test_encryptor" heading "Add ciphernode $CIPHERNODE_ADDRESS_1" yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_1 --network localhost -sleep 2 - heading "Add ciphernode $CIPHERNODE_ADDRESS_2" yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_2 --network localhost -sleep 2 - heading "Add ciphernode $CIPHERNODE_ADDRESS_3" yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_3 --network localhost -sleep 2 - heading "Add ciphernode $CIPHERNODE_ADDRESS_4" yarn ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_4 --network localhost -sleep 2 - heading "Request Committee" -yarn committee:new --network localhost --duration 6 +yarn committee:new --network localhost --duration 4 -sleep 2 +waiton "$SCRIPT_DIR/output/pubkey.bin" heading "Mock encrypted plaintext" @@ -108,24 +127,22 @@ heading "Mock publish committee key" cd packages/evm; yarn hardhat committee:publish --e3-id 0 --nodes $CIPHERNODE_ADDRESS_1,$CIPHERNODE_ADDRESS_2,$CIPHERNODE_ADDRESS_3,$CIPHERNODE_ADDRESS_4 --public-key 0x12345678 --network localhost; cd ../.. -sleep 2 - heading "Mock activate e3-id" yarn e3:activate --e3-id 0 --network localhost -sleep 2 - heading "Mock publish input e3-id" yarn e3:publishInput --network localhost --e3-id 0 --data 0x12345678 -sleep 2 +sleep 4 # wait for input deadline to pass + +waiton "$SCRIPT_DIR/output/output.bin" heading "Publish ciphertext to EVM" yarn e3:publishCiphertext --e3-id 0 --network localhost --data-file "$SCRIPT_DIR/output/output.bin" --proof 0x12345678 -sleep 10 +waiton "$SCRIPT_DIR/output/plaintext.txt" ACTUAL=$(cat $SCRIPT_DIR/output/plaintext.txt) From d1b13a49112f75398234e232d027a236e28e3bda Mon Sep 17 00:00:00 2001 From: ryardley Date: Thu, 26 Sep 2024 13:59:44 +1000 Subject: [PATCH 29/35] Tidy up cleanup trap in bash file --- tests/basic_integration/test.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/basic_integration/test.sh b/tests/basic_integration/test.sh index ac195282..18efb6ef 100755 --- a/tests/basic_integration/test.sh +++ b/tests/basic_integration/test.sh @@ -25,9 +25,8 @@ export CIPHERNODE_ADDRESS_4="0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199" # Function to clean up background processes cleanup() { - echo "Cleaning up processes..." >&2 + echo "Cleaning up processes..." kill $(jobs -p) 2>/dev/null - sleep 4 exit ${1:-1} } From b205e6d83fbe477d3cbeb5a82426df529f68d65d Mon Sep 17 00:00:00 2001 From: ryardley Date: Thu, 26 Sep 2024 14:08:48 +1000 Subject: [PATCH 30/35] Remove cd inline in script --- package.json | 1 + tests/basic_integration/test.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index a32dc695..4a47d8e6 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "ciphernode:test": "cd packages/ciphernode && cargo test", "ciphernode:build": "cd packages/ciphernode && cargo build --release", "committee:new": "cd packages/evm && yarn committee:new", + "committee:publish": "cd packages/evm && yarn hardhat committee:publish", "e3:activate": "cd packages/evm && yarn hardhat e3:activate", "e3:publishInput": "cd packages/evm && yarn hardhat e3:publishInput", "e3:publishCiphertext": "cd packages/evm && yarn hardhat e3:publishCiphertext", diff --git a/tests/basic_integration/test.sh b/tests/basic_integration/test.sh index 18efb6ef..213f6929 100755 --- a/tests/basic_integration/test.sh +++ b/tests/basic_integration/test.sh @@ -124,7 +124,7 @@ $SCRIPT_DIR/lib/fake_encrypt.sh --input "$SCRIPT_DIR/output/pubkey.bin" --output heading "Mock publish committee key" -cd packages/evm; yarn hardhat committee:publish --e3-id 0 --nodes $CIPHERNODE_ADDRESS_1,$CIPHERNODE_ADDRESS_2,$CIPHERNODE_ADDRESS_3,$CIPHERNODE_ADDRESS_4 --public-key 0x12345678 --network localhost; cd ../.. +yarn committee:publish --e3-id 0 --nodes $CIPHERNODE_ADDRESS_1,$CIPHERNODE_ADDRESS_2,$CIPHERNODE_ADDRESS_3,$CIPHERNODE_ADDRESS_4 --public-key 0x12345678 --network localhost heading "Mock activate e3-id" From 8bceba979980492face13ec8bb64246a103485b1 Mon Sep 17 00:00:00 2001 From: ryardley Date: Thu, 26 Sep 2024 14:16:53 +1000 Subject: [PATCH 31/35] Add timeout to wait on --- tests/basic_integration/test.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/basic_integration/test.sh b/tests/basic_integration/test.sh index 213f6929..49624852 100755 --- a/tests/basic_integration/test.sh +++ b/tests/basic_integration/test.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -set -e # Exit immediately if a command exits with a non-zero status +set -eu # Exit immediately if a command exits with a non-zero status # # Get the script's location SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" @@ -150,5 +150,7 @@ if [[ "$ACTUAL" != "$PLAINTEXT" ]]; then exit 1 fi +echo "Test PASSED" + cleanup 0 From 7a67578779e8f316b6278855b7bd077cba1ee3a2 Mon Sep 17 00:00:00 2001 From: ryardley Date: Thu, 26 Sep 2024 14:18:12 +1000 Subject: [PATCH 32/35] Make timeout 10 min --- tests/basic_integration/test.sh | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/tests/basic_integration/test.sh b/tests/basic_integration/test.sh index 49624852..47fffa87 100755 --- a/tests/basic_integration/test.sh +++ b/tests/basic_integration/test.sh @@ -47,19 +47,25 @@ waiton() { } waiton-files() { - while true; do - all_exist=true - for file in "$@"; do - if [ ! -f "$file" ]; then - all_exist=false - break - fi - done - if $all_exist; then - break - fi - sleep 1 + local timeout=600 # 10 minutes timeout + local start_time=$(date +%s) + while true; do + all_exist=true + for file in "$@"; do + if [ ! -f "$file" ]; then + all_exist=false + break + fi done + if $all_exist; then + break + fi + if [ $(($(date +%s) - start_time)) -ge $timeout ]; then + echo "Timeout waiting for files: $@" >&2 + return 1 + fi + sleep 1 + done } pkill -9 -f "target/debug/node" || true From f5ccc4fb16222c05679c90329cf6137ced9b0b50 Mon Sep 17 00:00:00 2001 From: ryardley Date: Thu, 26 Sep 2024 14:20:32 +1000 Subject: [PATCH 33/35] Use version 2 rust toolchain --- .github/workflows/integration.yml | 2 +- .github/workflows/rust-ci.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 1a667c1f..81fae295 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -35,7 +35,7 @@ jobs: node-version: 20 - name: Install Rust 1.81.0 - uses: actions-rs/toolchain@v1 + uses: actions-rs/toolchain@v2 with: toolchain: 1.81.0 override: true diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 3e9d2f46..a968e6a1 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v2 - name: Install Rust 1.81.0 - uses: actions-rs/toolchain@v1 + uses: actions-rs/toolchain@v2 with: toolchain: 1.81.0 override: true From d0b75806cbac1baa6522e805658aa8dd26d25d24 Mon Sep 17 00:00:00 2001 From: ryardley Date: Thu, 26 Sep 2024 14:22:11 +1000 Subject: [PATCH 34/35] Revert bad suggestion from coderabbit --- .github/workflows/integration.yml | 2 +- .github/workflows/rust-ci.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 81fae295..1a667c1f 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -35,7 +35,7 @@ jobs: node-version: 20 - name: Install Rust 1.81.0 - uses: actions-rs/toolchain@v2 + uses: actions-rs/toolchain@v1 with: toolchain: 1.81.0 override: true diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index a968e6a1..3e9d2f46 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v2 - name: Install Rust 1.81.0 - uses: actions-rs/toolchain@v2 + uses: actions-rs/toolchain@v1 with: toolchain: 1.81.0 override: true From a8217cdb4c89468a06e0c4305a81eeb858663670 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=B3=CE=BB?= Date: Fri, 27 Sep 2024 01:28:52 +1000 Subject: [PATCH 35/35] Architecture fixes (#114) * Extract FHE to a library * Ciphernode -> Keyshare * Remove serializers * Fix decryption and aggregation hacks --- packages/ciphernode/core/src/e3_request.rs | 18 +- packages/ciphernode/core/src/events.rs | 8 +- packages/ciphernode/core/src/fhe.rs | 178 +++++++----------- .../core/src/{ciphernode.rs => keyshare.rs} | 55 +++--- packages/ciphernode/core/src/lib.rs | 74 +++----- packages/ciphernode/core/src/logger.rs | 5 - .../ciphernode/core/src/main_aggregator.rs | 13 +- .../ciphernode/core/src/main_ciphernode.rs | 4 +- .../core/src/plaintext_aggregator.rs | 64 ++++--- .../core/src/publickey_aggregator.rs | 51 ++--- .../core/src/serializers/ciphertext.rs | 56 ------ .../core/src/serializers/decryption_share.rs | 72 ------- .../ciphernode/core/src/serializers/mod.rs | 11 -- .../core/src/serializers/public_key.rs | 77 -------- .../core/src/serializers/public_key_share.rs | 81 -------- .../core/src/serializers/secret_key.rs | 44 ----- .../enclave_node/src/bin/test_encryptor.rs | 6 +- tests/basic_integration/test.sh | 8 +- 18 files changed, 211 insertions(+), 614 deletions(-) rename packages/ciphernode/core/src/{ciphernode.rs => keyshare.rs} (75%) delete mode 100644 packages/ciphernode/core/src/serializers/ciphertext.rs delete mode 100644 packages/ciphernode/core/src/serializers/decryption_share.rs delete mode 100644 packages/ciphernode/core/src/serializers/mod.rs delete mode 100644 packages/ciphernode/core/src/serializers/public_key.rs delete mode 100644 packages/ciphernode/core/src/serializers/public_key_share.rs delete mode 100644 packages/ciphernode/core/src/serializers/secret_key.rs diff --git a/packages/ciphernode/core/src/e3_request.rs b/packages/ciphernode/core/src/e3_request.rs index c59f3a16..0df4c472 100644 --- a/packages/ciphernode/core/src/e3_request.rs +++ b/packages/ciphernode/core/src/e3_request.rs @@ -1,17 +1,17 @@ -use std::collections::HashMap; +use std::{collections::HashMap, sync::Arc}; use actix::{Actor, Addr, Context, Handler, Recipient}; use crate::{ - Ciphernode, CommitteeMeta, E3id, EnclaveEvent, EventBus, Fhe, PlaintextAggregator, + Keyshare, CommitteeMeta, E3id, EnclaveEvent, EventBus, Fhe, PlaintextAggregator, PublicKeyAggregator, Subscribe, }; #[derive(Default)] // TODO: Set this up with a Typestate pattern pub struct E3RequestContext { - pub ciphernode: Option>, - pub fhe: Option>, + pub keyshare: Option>, + pub fhe: Option>, pub plaintext: Option>, pub publickey: Option>, pub meta: Option, @@ -38,8 +38,8 @@ impl E3RequestContext { fn recipients(&self) -> Vec<(String, Option>)> { vec![ ( - "ciphernode".to_owned(), - self.ciphernode.clone().map(|addr| addr.into()), + "keyshare".to_owned(), + self.keyshare.clone().map(|addr| addr.into()), ), ( "plaintext".to_owned(), @@ -66,12 +66,6 @@ impl E3RequestContext { } } -struct E3RequestBuffers { - ciphernode: Vec, - publickey: Vec, - plaintext: Vec, -} - pub type ActorFactory = Box; // TODO: setup typestate pattern so that we have to place factories within correct order of diff --git a/packages/ciphernode/core/src/events.rs b/packages/ciphernode/core/src/events.rs index d61ee000..01dcbd95 100644 --- a/packages/ciphernode/core/src/events.rs +++ b/packages/ciphernode/core/src/events.rs @@ -345,15 +345,13 @@ impl EnclaveEvent { #[cfg(test)] mod tests { use super::EnclaveEvent; - use crate::{ - events::extract_enclave_event_name, serializers::PublicKeyShareSerializer, E3id, - KeyshareCreated, - }; + use crate::{events::extract_enclave_event_name, E3id, KeyshareCreated}; use alloy_primitives::address; use fhe::{ bfv::{BfvParametersBuilder, SecretKey}, mbfv::{CommonRandomPoly, PublicKeyShare}, }; + use fhe_traits::Serialize; use rand::SeedableRng; use rand_chacha::ChaCha20Rng; use std::error::Error; @@ -384,7 +382,7 @@ mod tests { let crp = CommonRandomPoly::new(¶ms, &mut rng)?; let sk_share = { SecretKey::random(¶ms, &mut rng) }; let pk_share = { PublicKeyShare::new(&sk_share, crp.clone(), &mut rng)? }; - let pubkey = PublicKeyShareSerializer::to_bytes(pk_share, params.clone(), crp.clone())?; + let pubkey = pk_share.to_bytes(); let kse = EnclaveEvent::from(KeyshareCreated { e3_id: E3id::from(1001), pubkey, diff --git a/packages/ciphernode/core/src/fhe.rs b/packages/ciphernode/core/src/fhe.rs index 7085f7a1..be3189b7 100644 --- a/packages/ciphernode/core/src/fhe.rs +++ b/packages/ciphernode/core/src/fhe.rs @@ -1,45 +1,24 @@ -use crate::{ - ordered_set::OrderedSet, - serializers::{ - CiphertextSerializer, DecryptionShareSerializer, PublicKeySerializer, - PublicKeyShareSerializer, SecretKeySerializer, - }, - ActorFactory, E3Requested, EnclaveEvent, -}; -use actix::{Actor, Context, Handler, Message}; +use crate::{ordered_set::OrderedSet, ActorFactory, E3Requested, EnclaveEvent}; use anyhow::*; use fhe::{ - bfv::{BfvParameters, BfvParametersBuilder, Encoding, Plaintext, PublicKey, SecretKey}, + bfv::{ + BfvParameters, BfvParametersBuilder, Ciphertext, Encoding, Plaintext, PublicKey, SecretKey, + }, mbfv::{AggregateIter, CommonRandomPoly, DecryptionShare, PublicKeyShare}, }; -use fhe_traits::{FheDecoder, Serialize}; -use rand::SeedableRng; -use rand_chacha::{ChaCha20Rng, ChaCha8Rng}; -use std::{ - hash::Hash, - sync::{Arc, Mutex}, -}; +use fhe_traits::{DeserializeParametrized, FheDecoder, Serialize}; +use rand_chacha::ChaCha20Rng; +use std::sync::{Arc, Mutex}; -#[derive(Message, Clone, Debug, PartialEq, Eq, Hash)] -#[rtype(result = "Result<(Vec, Vec)>")] -pub struct GenerateKeyshare { - // responder_pk: Vec, // TODO: use this to encrypt the secret data -} - -#[derive(Message, Clone, Debug, PartialEq, Eq)] -#[rtype(result = "Result<(Vec)>")] pub struct GetAggregatePublicKey { pub keyshares: OrderedSet>, } -#[derive(Message, Clone, Debug, PartialEq, Eq)] -#[rtype(result = "Result<(Vec)>")] pub struct GetAggregatePlaintext { pub decryptions: OrderedSet>, + pub ciphertext_output: Vec, } -#[derive(Message, Clone, Debug, PartialEq, Eq)] -#[rtype(result = "Result<(Vec)>")] pub struct DecryptCiphertext { pub unsafe_secret: Vec, pub ciphertext: Vec, @@ -47,49 +26,19 @@ pub struct DecryptCiphertext { pub type SharedRng = Arc>; -/// Fhe library adaptor. All FHE computations should happen through this actor. +/// Fhe library adaptor. +#[derive(Clone)] pub struct Fhe { params: Arc, crp: CommonRandomPoly, rng: SharedRng, } -impl Actor for Fhe { - type Context = Context; -} - impl Fhe { pub fn new(params: Arc, crp: CommonRandomPoly, rng: SharedRng) -> Self { Self { params, crp, rng } } - // Deprecated - pub fn try_default() -> Result { - // TODO: The production bootstrapping of this will involve receiving a crp bytes and param - // input form the event - let moduli = &vec![0x3FFFFFFF000001]; - let degree = 2048usize; - let plaintext_modulus = 1032193u64; - let rng = Arc::new(Mutex::new(ChaCha20Rng::from_entropy())); - let crp = CommonRandomPoly::new( - &BfvParametersBuilder::new() - .set_degree(degree) - .set_plaintext_modulus(plaintext_modulus) - .set_moduli(&moduli) - .build_arc()?, - &mut *rng.lock().unwrap(), - )? - .to_bytes(); - - Ok(Fhe::from_raw_params( - moduli, - degree, - plaintext_modulus, - &crp, - rng, - )?) - } - pub fn from_raw_params( moduli: &[u64], degree: usize, @@ -109,77 +58,56 @@ impl Fhe { rng, )) } -} -impl Handler for Fhe { - type Result = Result<(Vec, Vec)>; - fn handle(&mut self, _event: GenerateKeyshare, _: &mut Self::Context) -> Self::Result { + pub fn generate_keyshare(&self) -> Result<(Vec, Vec)> { let sk_share = { SecretKey::random(&self.params, &mut *self.rng.lock().unwrap()) }; let pk_share = { PublicKeyShare::new(&sk_share, self.crp.clone(), &mut *self.rng.lock().unwrap())? }; Ok(( - SecretKeySerializer::to_bytes(sk_share, self.params.clone())?, - PublicKeyShareSerializer::to_bytes(pk_share, self.params.clone(), self.crp.clone())?, + SecretKeySerializer::to_bytes(sk_share)?, + pk_share.to_bytes(), )) } -} -impl Handler for Fhe { - type Result = Result>; - fn handle(&mut self, msg: DecryptCiphertext, _: &mut Self::Context) -> Self::Result { + pub fn decrypt_ciphertext(&self, msg: DecryptCiphertext) -> Result> { let DecryptCiphertext { - unsafe_secret, // TODO: fix security issues with sending secrets between actors + unsafe_secret, ciphertext, } = msg; - let secret_key = SecretKeySerializer::from_bytes(&unsafe_secret)?; - let ct = Arc::new(CiphertextSerializer::from_bytes(&ciphertext)?); - let inner = DecryptionShare::new(&secret_key, &ct, &mut *self.rng.lock().unwrap()).unwrap(); - - Ok(DecryptionShareSerializer::to_bytes( - inner, - self.params.clone(), - ct.clone(), - )?) + let secret_key = SecretKeySerializer::from_bytes(&unsafe_secret, self.params.clone())?; + let ct = Arc::new( + Ciphertext::from_bytes(&ciphertext, &self.params) + .context("Error deserializing ciphertext")?, + ); + let decryption_share = + DecryptionShare::new(&secret_key, &ct, &mut *self.rng.lock().unwrap()).unwrap(); + Ok(decryption_share.to_bytes()) } -} -impl Handler for Fhe { - type Result = Result>; - - fn handle(&mut self, msg: GetAggregatePublicKey, _: &mut Self::Context) -> Self::Result { + pub fn get_aggregate_public_key(&self, msg: GetAggregatePublicKey) -> Result> { let public_key: PublicKey = msg .keyshares .iter() - .map(|k| PublicKeyShareSerializer::from_bytes(k)) - .collect::>>()? - .into_iter() + .map(|k| PublicKeyShare::deserialize(k, &self.params, self.crp.clone())) .aggregate()?; Ok(public_key.to_bytes()) } -} -impl Handler for Fhe { - type Result = Result>; - fn handle(&mut self, msg: GetAggregatePlaintext, _: &mut Self::Context) -> Self::Result { + pub fn get_aggregate_plaintext(&self, msg: GetAggregatePlaintext) -> Result> { + let arc_ct = Arc::new(Ciphertext::from_bytes( + &msg.ciphertext_output, + &self.params, + )?); + let plaintext: Plaintext = msg .decryptions .iter() - .map(|k| DecryptionShareSerializer::from_bytes(k)) - .collect::>>()? - .into_iter() + .map(|k| DecryptionShare::deserialize(k, &self.params, arc_ct.clone())) .aggregate()?; - // XXX: how do we know what the expected output of the plaintext is in order to decrypt - // here for serialization? - // This would be dependent on the computation that is running. - // For now assuming testcase of Vec and currently represents a "HARDCODED" program - // output format of Vec - // This could be determined based on the "program" config events - let decoded = Vec::::try_decode(&plaintext, Encoding::poly())?; - let decoded = &decoded[0..2]; // TODO: this will be computation dependent Ok(bincode::serialize(&decoded)?) } } @@ -201,11 +129,45 @@ impl FheFactory { .. } = data; - ctx.fhe = Some( + ctx.fhe = Some(Arc::new( Fhe::from_raw_params(&moduli, degree, plaintext_modulus, &crp, rng.clone()) - .unwrap() - .start(), - ); + .unwrap(), + )); + }) + } +} + +struct SecretKeySerializer { + pub inner: SecretKey, +} + +impl SecretKeySerializer { + pub fn to_bytes(inner: SecretKey) -> Result> { + let value = Self { inner }; + Ok(value.unsafe_serialize()?) + } + + pub fn from_bytes(bytes: &[u8], params: Arc) -> Result { + Ok(Self::deserialize(bytes, params)?.inner) + } +} + +#[derive(serde::Serialize, serde::Deserialize)] +struct SecretKeyData { + coeffs: Box<[i64]>, +} + +impl SecretKeySerializer { + pub fn unsafe_serialize(&self) -> Result> { + Ok(bincode::serialize(&SecretKeyData { + coeffs: self.inner.coeffs.clone(), + })?) + } + + pub fn deserialize(bytes: &[u8], params: Arc) -> Result { + let SecretKeyData { coeffs } = bincode::deserialize(&bytes)?; + Ok(Self { + inner: SecretKey::new(coeffs.to_vec(), ¶ms), }) } } diff --git a/packages/ciphernode/core/src/ciphernode.rs b/packages/ciphernode/core/src/keyshare.rs similarity index 75% rename from packages/ciphernode/core/src/ciphernode.rs rename to packages/ciphernode/core/src/keyshare.rs index 002bb3df..69f6aba6 100644 --- a/packages/ciphernode/core/src/ciphernode.rs +++ b/packages/ciphernode/core/src/keyshare.rs @@ -1,40 +1,43 @@ +use std::sync::Arc; + use crate::{ data::{Data, Insert}, eventbus::EventBus, events::{EnclaveEvent, KeyshareCreated}, - fhe::{Fhe, GenerateKeyshare}, + fhe::Fhe, ActorFactory, CiphernodeSelected, CiphertextOutputPublished, DecryptCiphertext, DecryptionshareCreated, Get, }; use actix::prelude::*; use anyhow::Result; +use anyhow::Context; -pub struct Ciphernode { - fhe: Addr, +pub struct Keyshare { + fhe: Arc, data: Addr, bus: Addr, address: String, } -impl Actor for Ciphernode { - type Context = Context; +impl Actor for Keyshare { + type Context = actix::Context; } -impl Ciphernode { - pub fn new(bus: Addr, fhe: Addr, data: Addr, address: &str) -> Self { +impl Keyshare { + pub fn new(bus: Addr, data: Addr, fhe: Arc, address: &str) -> Self { Self { bus, fhe, data, - address:address.to_string(), + address: address.to_string(), } } } -impl Handler for Ciphernode { +impl Handler for Keyshare { type Result = (); - fn handle(&mut self, event: EnclaveEvent, ctx: &mut Context) -> Self::Result { + fn handle(&mut self, event: EnclaveEvent, ctx: &mut actix::Context) -> Self::Result { match event { EnclaveEvent::CiphernodeSelected { data, .. } => ctx.address().do_send(data), EnclaveEvent::CiphertextOutputPublished { data, .. } => ctx.address().do_send(data), @@ -43,10 +46,10 @@ impl Handler for Ciphernode { } } -impl Handler for Ciphernode { +impl Handler for Keyshare { type Result = ResponseFuture<()>; - fn handle(&mut self, event: CiphernodeSelected, _: &mut Context) -> Self::Result { + fn handle(&mut self, event: CiphernodeSelected, _: &mut actix::Context) -> Self::Result { let fhe = self.fhe.clone(); let data = self.data.clone(); let bus = self.bus.clone(); @@ -59,10 +62,10 @@ impl Handler for Ciphernode { } } -impl Handler for Ciphernode { +impl Handler for Keyshare { type Result = ResponseFuture<()>; - fn handle(&mut self, event: CiphertextOutputPublished, _: &mut Context) -> Self::Result { + fn handle(&mut self, event: CiphertextOutputPublished, _: &mut actix::Context) -> Self::Result { println!("Ciphernode::CiphertextOutputPublished"); let fhe = self.fhe.clone(); let data = self.data.clone(); @@ -77,7 +80,7 @@ impl Handler for Ciphernode { } async fn on_ciphernode_selected( - fhe: Addr, + fhe: Arc, data: Addr, bus: Addr, event: CiphernodeSelected, @@ -86,7 +89,7 @@ async fn on_ciphernode_selected( let CiphernodeSelected { e3_id, .. } = event; // generate keyshare - let (sk, pubkey) = fhe.send(GenerateKeyshare {}).await??; + let (sk, pubkey) = fhe.generate_keyshare()?; // TODO: decrypt from FHE actor // save encrypted key against e3_id/sk @@ -110,7 +113,7 @@ async fn on_ciphernode_selected( } async fn on_decryption_requested( - fhe: Addr, + fhe: Arc, data: Addr, bus: Addr, event: CiphertextOutputPublished, @@ -128,12 +131,10 @@ async fn on_decryption_requested( println!("\n\nDECRYPTING!\n\n"); - let decryption_share = fhe - .send(DecryptCiphertext { - ciphertext: ciphertext_output, - unsafe_secret, - }) - .await??; + let decryption_share = fhe.decrypt_ciphertext(DecryptCiphertext { + ciphertext: ciphertext_output, + unsafe_secret, + }).context("error decrypting ciphertext")?; let event = EnclaveEvent::from(DecryptionshareCreated { e3_id, @@ -146,8 +147,8 @@ async fn on_decryption_requested( Ok(()) } -pub struct CiphernodeFactory; -impl CiphernodeFactory { +pub struct KeyshareFactory; +impl KeyshareFactory { pub fn create(bus: Addr, data: Addr, address: &str) -> ActorFactory { let address = address.to_string(); Box::new(move |ctx, evt| { @@ -160,8 +161,8 @@ impl CiphernodeFactory { return; }; - ctx.ciphernode = - Some(Ciphernode::new(bus.clone(), fhe.clone(), data.clone(), &address).start()) + ctx.keyshare = + Some(Keyshare::new(bus.clone(), data.clone(), fhe.clone(), &address).start()) }) } } diff --git a/packages/ciphernode/core/src/lib.rs b/packages/ciphernode/core/src/lib.rs index 5d9635c9..e2d4ac42 100644 --- a/packages/ciphernode/core/src/lib.rs +++ b/packages/ciphernode/core/src/lib.rs @@ -3,7 +3,6 @@ // #![warn(missing_docs, unused_imports)] mod cipernode_selector; -mod ciphernode; mod committee_meta; mod data; mod e3_request; @@ -14,38 +13,37 @@ mod evm_enclave; mod evm_listener; mod evm_manager; mod fhe; +mod keyshare; mod logger; mod main_aggregator; mod main_ciphernode; mod ordered_set; mod p2p; mod plaintext_aggregator; +mod plaintext_writer; +mod public_key_writer; mod publickey_aggregator; -mod serializers; mod sortition; mod utils; -mod public_key_writer; -mod plaintext_writer; // TODO: this is too permissive pub use actix::prelude::*; pub use cipernode_selector::*; -pub use ciphernode::*; pub use committee_meta::*; pub use data::*; pub use e3_request::*; pub use eventbus::*; pub use events::*; pub use fhe::*; +pub use keyshare::*; pub use logger::*; pub use main_aggregator::*; pub use main_ciphernode::*; pub use p2p::*; pub use plaintext_aggregator::*; -pub use publickey_aggregator::*; -pub use public_key_writer::*; pub use plaintext_writer::*; -pub use serializers::*; +pub use public_key_writer::*; +pub use publickey_aggregator::*; pub use sortition::*; pub use utils::*; @@ -58,12 +56,10 @@ mod tests { eventbus::{EventBus, GetHistory}, events::{E3Requested, E3id, EnclaveEvent, KeyshareCreated, PublicKeyAggregated}, p2p::P2p, - serializers::{CiphertextSerializer, DecryptionShareSerializer, PublicKeyShareSerializer}, utils::{setup_crp_params, ParamsWithCrp}, - CiphernodeAdded, CiphernodeFactory, CiphernodeSelected, CiphertextOutputPublished, - CommitteeMetaFactory, DecryptionshareCreated, E3RequestManager, FheFactory, - PlaintextAggregated, PlaintextAggregatorFactory, PublicKeyAggregatorFactory, ResetHistory, - SharedRng, Sortition, + CiphernodeAdded, CiphernodeSelected, CiphertextOutputPublished, CommitteeMetaFactory, + DecryptionshareCreated, E3RequestManager, FheFactory, KeyshareFactory, PlaintextAggregated, + PlaintextAggregatorFactory, PublicKeyAggregatorFactory, ResetHistory, SharedRng, Sortition, }; use actix::prelude::*; use alloy::primitives::Address; @@ -105,7 +101,7 @@ mod tests { bus.clone(), sortition.clone(), )) - .add_hook(CiphernodeFactory::create(bus.clone(), data.clone(), addr)) + .add_hook(KeyshareFactory::create(bus.clone(), data.clone(), addr)) .build(); } @@ -113,13 +109,9 @@ mod tests { params: Arc, crp: CommonRandomPoly, rng: SharedRng, - ) -> Result<(Vec, SecretKey)> { + ) -> Result<(PublicKeyShare, SecretKey)> { let sk = SecretKey::random(¶ms, &mut *rng.lock().unwrap()); - let pk = PublicKeyShareSerializer::to_bytes( - PublicKeyShare::new(&sk, crp.clone(), &mut *rng.lock().unwrap())?, - params.clone(), - crp, - )?; + let pk = PublicKeyShare::new(&sk, crp.clone(), &mut *rng.lock().unwrap())?; Ok((pk, sk)) } @@ -204,9 +196,8 @@ mod tests { let (p2, sk2) = generate_pk_share(params.clone(), crpoly.clone(), rng_test.clone())?; let (p3, sk3) = generate_pk_share(params.clone(), crpoly.clone(), rng_test.clone())?; - let pubkey: PublicKey = [p1.clone(), p2.clone(), p3.clone()] - .iter() - .map(|k| PublicKeyShareSerializer::from_bytes(k).unwrap()) + let pubkey: PublicKey = vec![p1.clone(), p2.clone(), p3.clone()] + .into_iter() .aggregate()?; assert_eq!(history.len(), 9); @@ -230,17 +221,17 @@ mod tests { threshold_m: 3, }), EnclaveEvent::from(KeyshareCreated { - pubkey: p1.clone(), + pubkey: p1.to_bytes(), e3_id: e3_id.clone(), node: eth_addrs[0].clone() }), EnclaveEvent::from(KeyshareCreated { - pubkey: p2.clone(), + pubkey: p2.to_bytes(), e3_id: e3_id.clone(), node: eth_addrs[1].clone() }), EnclaveEvent::from(KeyshareCreated { - pubkey: p3.clone(), + pubkey: p3.to_bytes(), e3_id: e3_id.clone(), node: eth_addrs[2].clone() }), @@ -253,7 +244,12 @@ mod tests { // Aggregate decryption bus.send(ResetHistory).await?; - + fn pad_end(input: &[u64], pad: u64, total: usize) -> Vec { + let len = input.len(); + let mut cop = input.to_vec(); + cop.extend(std::iter::repeat(pad).take(total - len)); + cop + } // TODO: // Making these values large (especially the yes value) requires changing // the params we use here - as we tune the FHE we need to take care @@ -261,33 +257,22 @@ mod tests { let no = 873827u64; let raw_plaintext = vec![yes, no]; - let expected_raw_plaintext = bincode::serialize(&raw_plaintext)?; + let padded = &pad_end(&raw_plaintext, 0, 2048); + let expected_raw_plaintext = bincode::serialize(&padded)?; let pt = Plaintext::try_encode(&raw_plaintext, Encoding::poly(), ¶ms)?; let ciphertext = pubkey.try_encrypt(&pt, &mut ChaCha20Rng::seed_from_u64(42))?; let event = EnclaveEvent::from(CiphertextOutputPublished { - ciphertext_output: CiphertextSerializer::to_bytes(ciphertext.clone(), params.clone())?, + ciphertext_output: ciphertext.to_bytes(), e3_id: e3_id.clone(), }); let arc_ct = Arc::new(ciphertext); - let ds1 = DecryptionShareSerializer::to_bytes( - DecryptionShare::new(&sk1, &arc_ct, &mut *rng_test.lock().unwrap()).unwrap(), - params.clone(), - arc_ct.clone(), - )?; - let ds2 = DecryptionShareSerializer::to_bytes( - DecryptionShare::new(&sk2, &arc_ct, &mut *rng_test.lock().unwrap()).unwrap(), - params.clone(), - arc_ct.clone(), - )?; - let ds3 = DecryptionShareSerializer::to_bytes( - DecryptionShare::new(&sk3, &arc_ct, &mut *rng_test.lock().unwrap()).unwrap(), - params.clone(), - arc_ct.clone(), - )?; + let ds1 = DecryptionShare::new(&sk1, &arc_ct, &mut *rng_test.lock().unwrap())?.to_bytes(); + let ds2 = DecryptionShare::new(&sk2, &arc_ct, &mut *rng_test.lock().unwrap())?.to_bytes(); + let ds3 = DecryptionShare::new(&sk3, &arc_ct, &mut *rng_test.lock().unwrap())?.to_bytes(); // let ds1 = sk1 bus.send(event.clone()).await?; @@ -296,6 +281,7 @@ mod tests { let history = bus.send(GetHistory).await?; assert_eq!(history.len(), 5); + assert_eq!( history, vec![ diff --git a/packages/ciphernode/core/src/logger.rs b/packages/ciphernode/core/src/logger.rs index 43f68984..6cb5c104 100644 --- a/packages/ciphernode/core/src/logger.rs +++ b/packages/ciphernode/core/src/logger.rs @@ -39,11 +39,6 @@ impl Handler for SimpleLogger { ); println!("[{}]: {}", self.name, msg); } - EnclaveEvent::PlaintextAggregated { data, .. } => { - let output: Vec = bincode::deserialize(&data.decrypted_output).unwrap(); - println!("[{}]: DECRYPTED: \n{:?}\n\n", self.name,output); - println!("[{}]: {}", self.name, msg); - } EnclaveEvent::CiphernodeAdded { data, .. } => { println!("[{}]: CiphernodeAdded({})", self.name, data.address); }, diff --git a/packages/ciphernode/core/src/main_aggregator.rs b/packages/ciphernode/core/src/main_aggregator.rs index 5a17f9fc..a7ab5a15 100644 --- a/packages/ciphernode/core/src/main_aggregator.rs +++ b/packages/ciphernode/core/src/main_aggregator.rs @@ -1,15 +1,14 @@ -use std::{ - env, - sync::{Arc, Mutex}, -}; - use crate::{ - committee_meta::CommitteeMetaFactory, evm_ciphernode_registry::connect_evm_ciphernode_registry, evm_enclave::connect_evm_enclave, public_key_writer::PublicKeyWriter, E3RequestManager, EventBus, FheFactory, P2p, PlaintextAggregatorFactory, PlaintextWriter, PublicKeyAggregatorFactory, SimpleLogger, Sortition + committee_meta::CommitteeMetaFactory, evm_ciphernode_registry::connect_evm_ciphernode_registry, + evm_enclave::connect_evm_enclave, public_key_writer::PublicKeyWriter, E3RequestManager, + EventBus, FheFactory, P2p, PlaintextAggregatorFactory, PlaintextWriter, + PublicKeyAggregatorFactory, SimpleLogger, Sortition, }; use actix::{Actor, Addr, Context}; use alloy::primitives::Address; use rand::SeedableRng; use rand_chacha::rand_core::OsRng; +use std::sync::{Arc, Mutex}; use tokio::task::JoinHandle; /// Main Ciphernode Actor @@ -42,7 +41,7 @@ impl MainAggregator { enclave_contract: Address, registry_contract: Address, pubkey_write_path: Option<&str>, - plaintext_write_path: Option<&str> + plaintext_write_path: Option<&str>, ) -> (Addr, JoinHandle<()>) { let rng = Arc::new(Mutex::new( rand_chacha::ChaCha20Rng::from_rng(OsRng).expect("Failed to create RNG"), diff --git a/packages/ciphernode/core/src/main_ciphernode.rs b/packages/ciphernode/core/src/main_ciphernode.rs index b6c0e8ec..027f5c7f 100644 --- a/packages/ciphernode/core/src/main_ciphernode.rs +++ b/packages/ciphernode/core/src/main_ciphernode.rs @@ -2,7 +2,7 @@ use std::sync::{Arc, Mutex}; use crate::{ evm_ciphernode_registry::connect_evm_ciphernode_registry, evm_enclave::connect_evm_enclave, - CiphernodeFactory, CiphernodeSelector, CommitteeMetaFactory, Data, E3RequestManager, EventBus, + KeyshareFactory, CiphernodeSelector, CommitteeMetaFactory, Data, E3RequestManager, EventBus, FheFactory, P2p, SimpleLogger, Sortition, }; use actix::{Actor, Addr, Context}; @@ -66,7 +66,7 @@ impl MainCiphernode { let e3_manager = E3RequestManager::builder(bus.clone()) .add_hook(CommitteeMetaFactory::create()) .add_hook(FheFactory::create(rng.clone())) - .add_hook(CiphernodeFactory::create( + .add_hook(KeyshareFactory::create( bus.clone(), data.clone(), &address.to_string(), diff --git a/packages/ciphernode/core/src/plaintext_aggregator.rs b/packages/ciphernode/core/src/plaintext_aggregator.rs index 9ad82e96..14d37000 100644 --- a/packages/ciphernode/core/src/plaintext_aggregator.rs +++ b/packages/ciphernode/core/src/plaintext_aggregator.rs @@ -1,9 +1,11 @@ +use std::sync::Arc; + use crate::{ ordered_set::OrderedSet, ActorFactory, DecryptionshareCreated, E3id, EnclaveEvent, EventBus, Fhe, GetAggregatePlaintext, GetHasNode, PlaintextAggregated, Sortition, }; use actix::prelude::*; -use anyhow::{anyhow, Result}; +use anyhow::Result; #[derive(Debug, Clone)] pub enum PlaintextAggregatorState { @@ -11,9 +13,11 @@ pub enum PlaintextAggregatorState { threshold_m: usize, shares: OrderedSet>, seed: u64, + ciphertext_output: Vec, }, Computing { shares: OrderedSet>, + ciphertext_output: Vec, }, Complete { decrypted: Vec, @@ -25,10 +29,11 @@ pub enum PlaintextAggregatorState { #[rtype(result = "anyhow::Result<()>")] struct ComputeAggregate { pub shares: OrderedSet>, + pub ciphertext_output: Vec, } pub struct PlaintextAggregator { - fhe: Addr, + fhe: Arc, bus: Addr, sortition: Addr, e3_id: E3id, @@ -37,12 +42,13 @@ pub struct PlaintextAggregator { impl PlaintextAggregator { pub fn new( - fhe: Addr, + fhe: Arc, bus: Addr, sortition: Addr, e3_id: E3id, threshold_m: usize, seed: u64, + ciphertext_output: Vec, ) -> Self { PlaintextAggregator { fhe, @@ -53,6 +59,7 @@ impl PlaintextAggregator { threshold_m, shares: OrderedSet::new(), seed, + ciphertext_output, }, } } @@ -61,6 +68,7 @@ impl PlaintextAggregator { let PlaintextAggregatorState::Collecting { threshold_m, shares, + ciphertext_output, .. } = &mut self.state else { @@ -71,6 +79,7 @@ impl PlaintextAggregator { if shares.len() == *threshold_m { return Ok(PlaintextAggregatorState::Computing { shares: shares.clone(), + ciphertext_output: ciphertext_output.to_vec(), }); } @@ -78,7 +87,7 @@ impl PlaintextAggregator { } pub fn set_decryption(&mut self, decrypted: Vec) -> Result { - let PlaintextAggregatorState::Computing { shares } = &mut self.state else { + let PlaintextAggregatorState::Computing { shares, .. } = &mut self.state else { return Ok(self.state.clone()); }; @@ -142,9 +151,14 @@ impl Handler for PlaintextAggregator { act.state = act.add_share(decryption_share)?; // Check the state and if it has changed to the computing - if let PlaintextAggregatorState::Computing { shares } = &act.state { + if let PlaintextAggregatorState::Computing { + shares, + ciphertext_output, + } = &act.state + { ctx.notify(ComputeAggregate { shares: shares.clone(), + ciphertext_output: ciphertext_output.to_vec(), }) } @@ -155,29 +169,25 @@ impl Handler for PlaintextAggregator { } impl Handler for PlaintextAggregator { - type Result = ResponseActFuture>; + type Result = Result<()>; fn handle(&mut self, msg: ComputeAggregate, _: &mut Self::Context) -> Self::Result { - Box::pin( - self.fhe - .send(GetAggregatePlaintext { - decryptions: msg.shares.clone(), - }) - .into_actor(self) - .map(|res, act, _| { - let decrypted_output = res??; - // Update the local state - act.state = act.set_decryption(decrypted_output.clone())?; - - // Dispatch the PublicKeyAggregated event - let event = EnclaveEvent::from(PlaintextAggregated { - decrypted_output, - e3_id: act.e3_id.clone(), - }); - act.bus.do_send(event); + let decrypted_output = self.fhe.get_aggregate_plaintext(GetAggregatePlaintext { + decryptions: msg.shares.clone(), + ciphertext_output: msg.ciphertext_output + })?; - Ok(()) - }), - ) + // Update the local state + self.state = self.set_decryption(decrypted_output.clone())?; + + // Dispatch the PlaintextAggregated event + let event = EnclaveEvent::from(PlaintextAggregated { + decrypted_output, + e3_id: self.e3_id.clone(), + }); + + self.bus.do_send(event); + + Ok(()) } } @@ -195,6 +205,7 @@ impl PlaintextAggregatorFactory { let Some(ref meta) = ctx.meta else { return; }; + ctx.plaintext = Some( PlaintextAggregator::new( fhe.clone(), @@ -203,6 +214,7 @@ impl PlaintextAggregatorFactory { data.e3_id, meta.threshold_m, meta.seed, + data.ciphertext_output, ) .start(), ); diff --git a/packages/ciphernode/core/src/publickey_aggregator.rs b/packages/ciphernode/core/src/publickey_aggregator.rs index 4bf14426..6222057c 100644 --- a/packages/ciphernode/core/src/publickey_aggregator.rs +++ b/packages/ciphernode/core/src/publickey_aggregator.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use crate::{ eventbus::EventBus, events::{E3id, EnclaveEvent, KeyshareCreated, PublicKeyAggregated}, @@ -31,7 +33,7 @@ struct ComputeAggregate { } pub struct PublicKeyAggregator { - fhe: Addr, + fhe: Arc, bus: Addr, sortition: Addr, e3_id: E3id, @@ -46,7 +48,7 @@ pub struct PublicKeyAggregator { /// for them. impl PublicKeyAggregator { pub fn new( - fhe: Addr, + fhe: Arc, bus: Addr, sortition: Addr, e3_id: E3id, @@ -169,43 +171,28 @@ impl Handler for PublicKeyAggregator { } impl Handler for PublicKeyAggregator { - type Result = ResponseActFuture>; + type Result = Result<()>; fn handle(&mut self, msg: ComputeAggregate, _: &mut Self::Context) -> Self::Result { - // Futures are awkward in Actix from what I can tell we should try and structure events so - // that futures that don't require access to self like the following... - Box::pin( - // Run the async future. - self.fhe - .send(GetAggregatePublicKey { - keyshares: msg.keyshares.clone(), - }) - // allow access to the actor - .into_actor(self) - // map into some sync stuff - .map(|res, act, _| { - // We have to double unwrap here. Suggestions? - // 1st - Mailbox error. - // 2nd - GetAggregatePublicKey Response. - let pubkey = res??; + let pubkey = self.fhe.get_aggregate_public_key(GetAggregatePublicKey { + keyshares: msg.keyshares.clone(), + })?; - // Update the local state - act.state = act.set_pubkey(pubkey.clone())?; + // Update the local state + self.state = self.set_pubkey(pubkey.clone())?; - // Dispatch the PublicKeyAggregated event - let event = EnclaveEvent::from(PublicKeyAggregated { - pubkey, - e3_id: act.e3_id.clone(), - }); + // Dispatch the PublicKeyAggregated event + let event = EnclaveEvent::from(PublicKeyAggregated { + pubkey, + e3_id: self.e3_id.clone(), + }); - act.bus.do_send(event); + self.bus.do_send(event); - // Return - Ok(()) - }), - ) + // Return + Ok(()) } -} +} pub struct PublicKeyAggregatorFactory; impl PublicKeyAggregatorFactory { diff --git a/packages/ciphernode/core/src/serializers/ciphertext.rs b/packages/ciphernode/core/src/serializers/ciphertext.rs deleted file mode 100644 index 271fef7b..00000000 --- a/packages/ciphernode/core/src/serializers/ciphertext.rs +++ /dev/null @@ -1,56 +0,0 @@ -use anyhow::*; -use fhe::bfv::{BfvParameters, Ciphertext}; -use fhe_traits::{Deserialize, DeserializeParametrized, Serialize}; -use serde::Serializer; -use std::sync::Arc; - -pub struct CiphertextSerializer { - pub inner: Ciphertext, - pub params: Arc, -} - -impl CiphertextSerializer { - pub fn to_bytes(inner: Ciphertext, params: Arc) -> Result> { - let value = Self { inner, params }; - Ok(bincode::serialize(&value)?) - } - - pub fn from_bytes(bytes:&[u8]) -> Result{ - let wct: Self = bincode::deserialize(&bytes)?; - Ok(wct.inner) - } -} - -/// Deserialize from serde to PublicKeySerializer -impl<'de> serde::Deserialize<'de> for CiphertextSerializer { - fn deserialize(deserializer: D) -> std::result::Result - where - D: serde::Deserializer<'de>, - { - // Intermediate struct of bytes for deserialization - #[derive(serde::Deserialize)] - struct DeserializedBytes { - par: Vec, - bytes: Vec, - } - let DeserializedBytes { par, bytes } = DeserializedBytes::deserialize(deserializer)?; - let params = Arc::new(BfvParameters::try_deserialize(&par).unwrap()); - let inner = Ciphertext::from_bytes(&bytes, ¶ms).map_err(serde::de::Error::custom)?; - std::result::Result::Ok(Self { inner, params }) - } -} -impl serde::Serialize for CiphertextSerializer { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - use serde::ser::SerializeStruct; - let bytes = self.inner.to_bytes(); - let par_bytes = self.params.to_bytes(); - // Intermediate struct of bytes - let mut state = serializer.serialize_struct("Ciphertext", 2)?; - state.serialize_field("par_bytes", &par_bytes)?; - state.serialize_field("bytes", &bytes)?; - state.end() - } -} diff --git a/packages/ciphernode/core/src/serializers/decryption_share.rs b/packages/ciphernode/core/src/serializers/decryption_share.rs deleted file mode 100644 index bc99d12e..00000000 --- a/packages/ciphernode/core/src/serializers/decryption_share.rs +++ /dev/null @@ -1,72 +0,0 @@ -use anyhow::*; -use fhe::{ - bfv::{BfvParameters, Ciphertext}, - mbfv::DecryptionShare, -}; -use fhe_traits::{Deserialize, DeserializeParametrized, Serialize}; -use serde::Serializer; -use std::sync::Arc; - -pub struct DecryptionShareSerializer { - inner: DecryptionShare, - params: Arc, - ct: Arc, -} - -impl DecryptionShareSerializer { - pub fn to_bytes( - inner: DecryptionShare, - params: Arc, - ct: Arc, - ) -> Result> { - let value = Self { inner, params, ct }; - Ok(bincode::serialize(&value)?) - } - - pub fn from_bytes(bytes: &[u8]) -> Result { - let ds: DecryptionShareSerializer = bincode::deserialize(&bytes)?; - Ok(ds.inner) - } -} - -/// Deserialize from serde to PublicKeySerializer -impl<'de> serde::Deserialize<'de> for DecryptionShareSerializer { - fn deserialize(deserializer: D) -> std::result::Result - where - D: serde::Deserializer<'de>, - { - // Intermediate struct of bytes for deserialization - #[derive(serde::Deserialize)] - struct DecryptionShareBytes { - par: Vec, - bytes: Vec, - ct: Vec, - } - let DecryptionShareBytes { par, bytes, ct } = - DecryptionShareBytes::deserialize(deserializer)?; - let params = Arc::new(BfvParameters::try_deserialize(&par).unwrap()); // TODO: fix errors - let ct = Arc::new(Ciphertext::from_bytes(&ct, ¶ms).unwrap()); // TODO: fix errors - let inner = DecryptionShare::deserialize(&bytes, ¶ms, ct.clone()) - .map_err(serde::de::Error::custom)?; - // TODO: how do we create an invariant that the deserialized params match the global params? - std::result::Result::Ok(Self { inner, params, ct }) - } -} -/// Serialize to serde bytes representation -impl serde::Serialize for DecryptionShareSerializer { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - use serde::ser::SerializeStruct; - let bytes = self.inner.to_bytes(); - let par_bytes = self.params.to_bytes(); - let ct_bytes = self.ct.to_bytes(); - // Intermediate struct of bytes - let mut state = serializer.serialize_struct("DecryptionShareBytes", 2)?; - state.serialize_field("par", &par_bytes)?; - state.serialize_field("bytes", &bytes)?; - state.serialize_field("bytes", &ct_bytes)?; - state.end() - } -} diff --git a/packages/ciphernode/core/src/serializers/mod.rs b/packages/ciphernode/core/src/serializers/mod.rs deleted file mode 100644 index e5c15eeb..00000000 --- a/packages/ciphernode/core/src/serializers/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -mod ciphertext; -mod decryption_share; -mod public_key; -mod public_key_share; -mod secret_key; - -pub use ciphertext::*; -pub use decryption_share::*; -pub use public_key::*; -pub use public_key_share::*; -pub use secret_key::*; diff --git a/packages/ciphernode/core/src/serializers/public_key.rs b/packages/ciphernode/core/src/serializers/public_key.rs deleted file mode 100644 index a485334b..00000000 --- a/packages/ciphernode/core/src/serializers/public_key.rs +++ /dev/null @@ -1,77 +0,0 @@ -use anyhow::*; -use fhe::bfv::{BfvParameters, PublicKey}; -use fhe_traits::{Deserialize, DeserializeParametrized, Serialize}; -use serde::Serializer; -use std::sync::Arc; - -pub struct PublicKeySerializer { - inner: PublicKey, - params: Arc, -} - -impl PublicKeySerializer { - pub fn to_bytes(inner: PublicKey, params: Arc) -> Result> { - let value = Self { inner, params }; - Ok(bincode::serialize(&value)?) - } - - pub fn from_bytes(bytes: Vec) -> Result { - let wpk: PublicKeySerializer = bincode::deserialize(&bytes)?; - Ok(wpk.inner) - } -} - -/// Deserialize from serde to PublicKeySerializer -impl<'de> serde::Deserialize<'de> for PublicKeySerializer { - fn deserialize(deserializer: D) -> std::result::Result - where - D: serde::Deserializer<'de>, - { - // Intermediate struct of bytes for deserialization - #[derive(serde::Deserialize)] - struct PublicKeyBytes { - par: Vec, - bytes: Vec, - } - let PublicKeyBytes { par, bytes } = PublicKeyBytes::deserialize(deserializer)?; - let params = Arc::new(BfvParameters::try_deserialize(&par).unwrap()); // TODO: fix errors - let inner = PublicKey::from_bytes(&bytes, ¶ms).map_err(serde::de::Error::custom)?; - // TODO: how do we create an invariant that the deserialized params match the global params? - std::result::Result::Ok(Self { inner, params }) - } -} - -/// Serialize to serde bytes representation -impl serde::Serialize for PublicKeySerializer { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - use serde::ser::SerializeStruct; - let bytes = self.inner.to_bytes(); - let par_bytes = self.params.to_bytes(); - // Intermediate struct of bytes - let mut state = serializer.serialize_struct("PublicKey", 2)?; - state.serialize_field("par_bytes", &par_bytes)?; - state.serialize_field("bytes", &bytes)?; - state.end() - } -} - -// impl Hash for PublicKeySerializer { -// fn hash(&self, state: &mut H) { -// self.inner.to_bytes().hash(state) -// } -// } -// -// impl Ord for PublicKeySerializer { -// fn cmp(&self, other: &Self) -> Ordering { -// self.inner.to_bytes().cmp(&other.inner.to_bytes()) -// } -// } -// -// impl PartialOrd for PublicKeySerializer { -// fn partial_cmp(&self, other: &Self) -> Option { -// Some(self.cmp(other)) -// } -// } diff --git a/packages/ciphernode/core/src/serializers/public_key_share.rs b/packages/ciphernode/core/src/serializers/public_key_share.rs deleted file mode 100644 index cf7a6c6d..00000000 --- a/packages/ciphernode/core/src/serializers/public_key_share.rs +++ /dev/null @@ -1,81 +0,0 @@ -use anyhow::*; -use fhe::{ - bfv::BfvParameters, - mbfv::{CommonRandomPoly, PublicKeyShare}, -}; -use fhe_traits::{Deserialize, Serialize}; -use serde::Serializer; -use std::sync::Arc; - -pub struct PublicKeyShareSerializer { - inner: PublicKeyShare, - // We need to hold copies of the params and crp in order to effectively serialize and - // deserialize the wrapped type - params: Arc, - crp: CommonRandomPoly, -} - -impl PublicKeyShareSerializer { - /// Public function to serialize specifically from the wrapped type including types that are - /// private from outside the crate - pub fn to_bytes( - inner: PublicKeyShare, - params: Arc, - crp: CommonRandomPoly, - ) -> Result> { - let value = Self { inner, params, crp }; - Ok(bincode::serialize(&value)?) - } - - pub fn from_bytes(bytes: &[u8]) -> Result { - let wpk: Self = bincode::deserialize(&bytes)?; - Ok(wpk.inner) - } -} - -/// Deserialize from serde to PublicKeyShareSerializer -impl<'de> serde::Deserialize<'de> for PublicKeyShareSerializer { - fn deserialize(deserializer: D) -> std::result::Result - where - D: serde::Deserializer<'de>, - { - // Intermediate struct of bytes for deserialization - #[derive(serde::Deserialize)] - struct PublicKeyShareBytes { - par_bytes: Vec, - crp_bytes: Vec, - bytes: Vec, - } - let PublicKeyShareBytes { - par_bytes, - crp_bytes, - bytes, - } = PublicKeyShareBytes::deserialize(deserializer)?; - let params = Arc::new(BfvParameters::try_deserialize(&par_bytes).unwrap()); - let crp = - CommonRandomPoly::deserialize(&crp_bytes, ¶ms).map_err(serde::de::Error::custom)?; - let inner = PublicKeyShare::deserialize(&bytes, ¶ms, crp.clone()) - .map_err(serde::de::Error::custom)?; - // TODO: how do we create an invariant that the deserialized params match the global params? - std::result::Result::Ok(Self { inner, params, crp }) - } -} - -/// Serialize to serde bytes representation -impl serde::Serialize for PublicKeyShareSerializer { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - use serde::ser::SerializeStruct; - let bytes = self.inner.to_bytes(); - let par_bytes = self.params.to_bytes(); - let crp_bytes = self.crp.to_bytes(); - // Intermediate struct of bytes - let mut state = serializer.serialize_struct("PublicKeyShare", 3)?; - state.serialize_field("par_bytes", &par_bytes)?; - state.serialize_field("crp_bytes", &crp_bytes)?; - state.serialize_field("bytes", &bytes)?; - state.end() - } -} diff --git a/packages/ciphernode/core/src/serializers/secret_key.rs b/packages/ciphernode/core/src/serializers/secret_key.rs deleted file mode 100644 index 95abca76..00000000 --- a/packages/ciphernode/core/src/serializers/secret_key.rs +++ /dev/null @@ -1,44 +0,0 @@ -use anyhow::*; -use fhe::bfv::{BfvParameters, SecretKey}; -use fhe_traits::{Deserialize, Serialize}; -use std::sync::Arc; - -pub struct SecretKeySerializer { - pub inner: SecretKey, - pub params: Arc, -} - -impl SecretKeySerializer { - pub fn to_bytes(inner: SecretKey, params: Arc) -> Result> { - let value = Self { inner, params }; - Ok(value.unsafe_serialize()?) - } - - pub fn from_bytes(bytes: &[u8]) -> Result { - Ok(Self::deserialize(bytes)?.inner) - } -} - -#[derive(serde::Serialize, serde::Deserialize)] -struct SecretKeyData { - coeffs: Box<[i64]>, - par: Vec, -} - -impl SecretKeySerializer { - pub fn unsafe_serialize(&self) -> Result> { - Ok(bincode::serialize(&SecretKeyData { - coeffs: self.inner.coeffs.clone(), - par: self.params.clone().to_bytes(), - })?) - } - - pub fn deserialize(bytes: &[u8]) -> Result { - let SecretKeyData { coeffs, par } = bincode::deserialize(&bytes)?; - let params = Arc::new(BfvParameters::try_deserialize(&par).unwrap()); - Ok(Self { - inner: SecretKey::new(coeffs.to_vec(), ¶ms), - params, - }) - } -} diff --git a/packages/ciphernode/enclave_node/src/bin/test_encryptor.rs b/packages/ciphernode/enclave_node/src/bin/test_encryptor.rs index 4cc74a08..9a1531f2 100644 --- a/packages/ciphernode/enclave_node/src/bin/test_encryptor.rs +++ b/packages/ciphernode/enclave_node/src/bin/test_encryptor.rs @@ -1,8 +1,8 @@ // This is a test script designed to encrypt some fixed data to a fhe public key use clap::Parser; -use enclave_core::{setup_bfv_params, CiphertextSerializer}; +use enclave_core::setup_bfv_params; use fhe::bfv::{Encoding, Plaintext, PublicKey}; -use fhe_traits::{DeserializeParametrized, FheEncoder, FheEncrypter}; +use fhe_traits::{DeserializeParametrized, FheEncoder, FheEncrypter, Serialize}; use rand::SeedableRng; use rand_chacha::ChaCha20Rng; use std::fs; @@ -36,7 +36,7 @@ fn main() -> Result<(), Box> { let pt = Plaintext::try_encode(&raw_plaintext, Encoding::poly(), ¶ms)?; let ciphertext = pubkey.try_encrypt(&pt, &mut ChaCha20Rng::seed_from_u64(42))?; - let ciphertext_bytes = CiphertextSerializer::to_bytes(ciphertext.clone(), params.clone())?; + let ciphertext_bytes = ciphertext.clone().to_bytes(); fs::write(&args.output, &ciphertext_bytes)?; println!("Created {}", args.output); diff --git a/tests/basic_integration/test.sh b/tests/basic_integration/test.sh index 47fffa87..8080e6e0 100755 --- a/tests/basic_integration/test.sh +++ b/tests/basic_integration/test.sh @@ -150,13 +150,17 @@ yarn e3:publishCiphertext --e3-id 0 --network localhost --data-file "$SCRIPT_DIR waiton "$SCRIPT_DIR/output/plaintext.txt" ACTUAL=$(cat $SCRIPT_DIR/output/plaintext.txt) + -if [[ "$ACTUAL" != "$PLAINTEXT" ]]; then +# Assume plaintext is shorter + +if [[ "$ACTUAL" != "$PLAINTEXT"* ]]; then echo "Invalid plaintext decrypted: actual='$ACTUAL' expected='$PLAINTEXT'" + echo "Test FAILED" exit 1 fi -echo "Test PASSED" +heading "Test PASSED !" cleanup 0