Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Save keypair to and from repository #192

Merged
merged 10 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"preciphernode:build": "yarn evm:compile",
"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:activate": "cd packages/evm && yarn -s 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",
Expand Down
3 changes: 3 additions & 0 deletions packages/ciphernode/Cargo.lock

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

2 changes: 2 additions & 0 deletions packages/ciphernode/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ bincode = "1.3.3"
bs58 = "0.5.1"
base64 = "0.22.1"
clap = { version = "4.5.17", features = ["derive"] }
cipher = { path = "./cipher" }
dirs = "5.0.1"
data = { path = "./data" }
figment = { version = "0.10.19", features = ["yaml", "test"] }
fhe_rs = { package = "fhe", git = "https://github.com/gnosisguild/fhe.rs", version = "0.1.0-beta.7" }
fhe-traits = { git = "https://github.com/gnosisguild/fhe.rs", version = "0.1.0-beta.7" }
Expand Down
1 change: 1 addition & 0 deletions packages/ciphernode/cipher/src/cipher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ impl Cipher {
Ok(Self::new(FilePasswordManager::new(config.key_file())).await?)
}

/// Encrypt the given data and zeroize the data after encryption
pub fn encrypt_data(&self, data: &mut Vec<u8>) -> Result<Vec<u8>> {
encrypt_data(&self.key, data)
}
Expand Down
2 changes: 1 addition & 1 deletion packages/ciphernode/core/src/eventbus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub struct ResetHistory;

/// Central EventBus for each node. Actors publish events to this bus by sending it EnclaveEvents.
/// All events sent to this bus are assumed to be published over the network via pubsub.
/// Other actors such as the NetworkRelay and Evm actor connect to outside services and control which events
/// Other actors such as the NetworkManager and Evm actor connect to outside services and control which events
/// actually get published as well as ensure that local events are not rebroadcast locally after
/// being published.
pub struct EventBus {
Expand Down
10 changes: 8 additions & 2 deletions packages/ciphernode/enclave_node/src/aggregator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use evm::{
CiphernodeRegistrySol, EnclaveSol, RegistryFilterSol,
};
use logger::SimpleLogger;
use net::NetworkRelay;
use net::NetworkManager;
use rand::SeedableRng;
use rand_chacha::{rand_core::OsRng, ChaCha20Rng};
use router::{
Expand Down Expand Up @@ -81,7 +81,13 @@ pub async fn setup_aggregator(
.build()
.await?;

let (_, join_handle, peer_id) = NetworkRelay::setup_with_peer(bus.clone(), config.peers())?;
let (_, join_handle, peer_id) = NetworkManager::setup_with_peer(
bus.clone(),
config.peers(),
&cipher,
repositories.libp2pid(),
)
.await?;

if let Some(path) = pubkey_write_path {
PublicKeyWriter::attach(path, bus.clone());
Expand Down
10 changes: 8 additions & 2 deletions packages/ciphernode/enclave_node/src/ciphernode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use evm::{
CiphernodeRegistrySol, EnclaveSolReader,
};
use logger::SimpleLogger;
use net::NetworkRelay;
use net::NetworkManager;
use rand::SeedableRng;
use rand_chacha::rand_core::OsRng;
use router::{
Expand Down Expand Up @@ -73,7 +73,13 @@ pub async fn setup_ciphernode(
.build()
.await?;

let (_, join_handle, peer_id) = NetworkRelay::setup_with_peer(bus.clone(), config.peers())?;
let (_, join_handle, peer_id) = NetworkManager::setup_with_peer(
bus.clone(),
config.peers(),
&cipher,
repositories.libp2pid(),
)
.await?;

let nm = format!("CIPHER({})", &address.to_string()[0..5]);
SimpleLogger::attach(&nm, bus.clone());
Expand Down
3 changes: 3 additions & 0 deletions packages/ciphernode/net/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ repository = "https://github.com/gnosisguild/enclave/packages/ciphernode"
async-std = { workspace = true, features = ["attributes"] }
async-trait = { workspace = true }
futures = { workspace = true }
cipher = { workspace = true }
data = { workspace = true }
libp2p = { workspace = true, features = [
"async-std",
"gossipsub",
Expand All @@ -28,3 +30,4 @@ tracing-subscriber = { workspace = true, features = ["env-filter"] }
enclave-core = { path = "../core" }
anyhow = { workspace = true }
actix = { workspace = true }
zeroize = { workspace = true }
4 changes: 2 additions & 2 deletions packages/ciphernode/net/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#![crate_name = "net"]
#![crate_type = "lib"]

mod network_manager;
mod network_peer;
mod network_relay;

pub use network_manager::*;
pub use network_peer::*;
pub use network_relay::*;
Original file line number Diff line number Diff line change
@@ -1,33 +1,37 @@
use std::{collections::HashSet, error::Error};

use crate::NetworkPeer;
/// Actor for connecting to an libp2p client via it's mpsc channel interface
/// This Actor should be responsible for
use actix::prelude::*;
use anyhow::anyhow;
use anyhow::Result;
use cipher::Cipher;
use data::Repository;
use enclave_core::{EnclaveEvent, EventBus, EventId, Subscribe};
use libp2p::identity::ed25519;
use std::sync::Arc;
use std::{collections::HashSet, error::Error};
use tokio::sync::mpsc::{Receiver, Sender};
use tracing::{error, trace};
use tracing::{error, info, instrument, trace};
use zeroize::Zeroize;

/// NetworkRelay Actor converts between EventBus events and Libp2p events forwarding them to a
/// NetworkManager Actor converts between EventBus events and Libp2p events forwarding them to a
/// NetworkPeer for propagation over the p2p network
pub struct NetworkRelay {
pub struct NetworkManager {
bus: Addr<EventBus>,
tx: Sender<Vec<u8>>,
sent_events: HashSet<EventId>,
}

impl Actor for NetworkRelay {
impl Actor for NetworkManager {
type Context = Context<Self>;
}

#[derive(Message, Clone, Debug, PartialEq, Eq)]
#[rtype(result = "anyhow::Result<()>")]
struct LibP2pEvent(pub Vec<u8>);

impl NetworkRelay {
/// Create a new NetworkRelay actor
impl NetworkManager {
/// Create a new NetworkManager actor
pub fn new(bus: Addr<EventBus>, tx: Sender<Vec<u8>>) -> Self {
Self {
bus,
Expand All @@ -41,7 +45,7 @@ impl NetworkRelay {
tx: Sender<Vec<u8>>,
mut rx: Receiver<Vec<u8>>,
) -> Addr<Self> {
let addr = NetworkRelay::new(bus.clone(), tx).start();
let addr = NetworkManager::new(bus.clone(), tx).start();

// Listen on all events
bus.do_send(Subscribe {
Expand All @@ -63,20 +67,41 @@ impl NetworkRelay {
}

/// Spawn a Libp2p peer and hook it up to this actor
pub fn setup_with_peer(
#[instrument(name = "libp2p", skip_all)]
pub async fn setup_with_peer(
bus: Addr<EventBus>,
peers: Vec<String>,
cipher: &Arc<Cipher>,
repository: Repository<Vec<u8>>,
) -> Result<(Addr<Self>, tokio::task::JoinHandle<Result<()>>, String)> {
let keypair = libp2p::identity::Keypair::generate_ed25519();
info!("Reading from repository");
let mut bytes = if let Some(bytes) = repository.read().await? {
let decrypted = cipher.decrypt_data(&bytes)?;
info!("Found keypair in repository");
decrypted
} else {
let kp = libp2p::identity::Keypair::generate_ed25519();
info!("Generated new keypair {}", kp.public().to_peer_id());
let innerkp = kp.try_into_ed25519()?;
let bytes = innerkp.to_bytes().to_vec();

// We need to clone here so that returned bytes are not zeroized
repository.write(&cipher.encrypt_data(&mut bytes.clone())?);
info!("Saved new keypair to repository");
bytes
};

let ed25519_keypair = ed25519::Keypair::try_from_bytes(&mut bytes)?;
let keypair: libp2p::identity::Keypair = ed25519_keypair.try_into()?;
let mut peer = NetworkPeer::new(&keypair, peers, None, "tmp-enclave-gossip-topic")?;
let rx = peer.rx().ok_or(anyhow!("Peer rx already taken"))?;
let p2p_addr = NetworkRelay::setup(bus, peer.tx(), rx);
let p2p_addr = NetworkManager::setup(bus, peer.tx(), rx);
let handle = tokio::spawn(async move { Ok(peer.start().await?) });
Ok((p2p_addr, handle, keypair.public().to_peer_id().to_string()))
}
}

impl Handler<LibP2pEvent> for NetworkRelay {
impl Handler<LibP2pEvent> for NetworkManager {
type Result = anyhow::Result<()>;
fn handle(&mut self, msg: LibP2pEvent, _: &mut Self::Context) -> Self::Result {
let LibP2pEvent(bytes) = msg;
Expand All @@ -91,7 +116,7 @@ impl Handler<LibP2pEvent> for NetworkRelay {
}
}

impl Handler<EnclaveEvent> for NetworkRelay {
impl Handler<EnclaveEvent> for NetworkManager {
type Result = ResponseFuture<()>;
fn handle(&mut self, event: EnclaveEvent, _: &mut Self::Context) -> Self::Result {
let sent_events = self.sent_events.clone();
Expand Down
4 changes: 4 additions & 0 deletions packages/ciphernode/router/src/repositories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ impl Repositories {
Repository::new(self.store.scope(format!("//eth_private_key")))
}

pub fn libp2pid(&self) -> Repository<Vec<u8>> {
Repository::new(self.store.scope(format!("//libp2pid")))
}

pub fn enclave_sol_reader(&self, chain_id: u64) -> Repository<EvmEventReaderState> {
Repository::new(
self.store
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use enclave_core::{
};
use fhe::{setup_crp_params, ParamsWithCrp, SharedRng};
use logger::SimpleLogger;
use net::NetworkRelay;
use net::NetworkManager;
use router::{
CiphernodeSelector, E3RequestRouter, FheFeature, KeyshareFeature, PlaintextAggregatorFeature,
PublicKeyAggregatorFeature, RepositoriesFactory,
Expand Down Expand Up @@ -468,7 +468,7 @@ async fn test_p2p_actor_forwards_events_to_network() -> Result<()> {
let (tx, mut output) = channel(100); // Transmit byte events to the network
let (input, rx) = channel(100); // Receive byte events from the network
let bus = EventBus::new(true).start();
NetworkRelay::setup(bus.clone(), tx.clone(), rx);
NetworkManager::setup(bus.clone(), tx.clone(), rx);

// Capture messages from output on msgs vec
let msgs: Arc<Mutex<Vec<Vec<u8>>>> = Arc::new(Mutex::new(Vec::new()));
Expand Down Expand Up @@ -514,14 +514,14 @@ async fn test_p2p_actor_forwards_events_to_network() -> Result<()> {
assert_eq!(
*msgs.lock().await,
vec![evt_1.to_bytes()?, evt_2.to_bytes()?], // notice no local events
"NetworkRelay did not transmit correct events to the network"
"NetworkManager did not transmit correct events to the network"
);

assert_eq!(
history,
vec![evt_1, evt_2, local_evt_3], // all local events that have been broadcast but no
// events from the loopback
"NetworkRelay must not retransmit forwarded event to event bus"
"NetworkManager must not retransmit forwarded event to event bus"
);

Ok(())
Expand All @@ -535,7 +535,7 @@ async fn test_p2p_actor_forwards_events_to_bus() -> Result<()> {
let (tx, _) = channel(100); // Transmit byte events to the network
let (input, rx) = channel(100); // Receive byte events from the network
let bus = EventBus::new(true).start();
NetworkRelay::setup(bus.clone(), tx.clone(), rx);
NetworkManager::setup(bus.clone(), tx.clone(), rx);

// Capture messages from output on msgs vec
let event = EnclaveEvent::from(E3Requested {
Expand Down
3 changes: 2 additions & 1 deletion tests/basic_integration/base.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ 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 activate e3-id"
yarn e3:activate --e3-id 0 --public-key "0x$PUBLIC_KEY" --network localhost
# NOTE: using -s to avoid key spamming output
yarn -s e3:activate --e3-id 0 --public-key "0x$PUBLIC_KEY" --network localhost

heading "Mock publish input e3-id"
yarn e3:publishInput --network localhost --e3-id 0 --data 0x12345678
Expand Down
2 changes: 1 addition & 1 deletion tests/basic_integration/lib/prebuild.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/usr/bin/env sh

cd packages/ciphernode && RUSTFLAGS="-A warnings" cargo build --bin fake_encrypt --bin enclave;
cd packages/ciphernode && RUSTFLAGS="-A warnings" cargo build --bin fake_encrypt --bin enclave --bin pack_e3_params;
3 changes: 2 additions & 1 deletion tests/basic_integration/persist.sh
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ 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 activate e3-id"
yarn e3:activate --e3-id 0 --public-key "0x$PUBLIC_KEY" --network localhost
# NOTE using -s to avoid key spaming the output
yarn -s e3:activate --e3-id 0 --public-key "0x$PUBLIC_KEY" --network localhost

heading "Mock publish input e3-id"
yarn e3:publishInput --network localhost --e3-id 0 --data 0x12345678
Expand Down
Loading