Skip to content

Commit

Permalink
wip: write and load phase 1 from a file
Browse files Browse the repository at this point in the history
  • Loading branch information
redshiftzero committed Oct 12, 2023
1 parent 6d156c5 commit 5c98b36
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 45 deletions.
36 changes: 22 additions & 14 deletions crates/crypto/proof-setup/src/all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ fn to_bytes<T: CanonicalSerialize>(t: &T) -> Result<Vec<u8>> {
Ok(out)
}

fn to_bytes_uncompressed<T: CanonicalSerialize>(t: &T) -> Result<Vec<u8>> {
let mut out = Vec::new();
t.serialize_uncompressed(&mut out)?;
Ok(out)
}

pub const NUM_CIRCUITS: usize = 7;

/// Generate all of the circuits as matrices.
Expand Down Expand Up @@ -472,13 +478,13 @@ impl TryInto<pb::CeremonyCrs> for Phase1RawCeremonyCRS {

fn try_into(self) -> Result<pb::CeremonyCrs> {
Ok(pb::CeremonyCrs {
spend: to_bytes(&self.0[0])?,
output: to_bytes(&self.0[1])?,
delegator_vote: to_bytes(&self.0[2])?,
undelegate_claim: to_bytes(&self.0[3])?,
swap: to_bytes(&self.0[4])?,
swap_claim: to_bytes(&self.0[5])?,
nullifer_derivation_crs: to_bytes(&self.0[6])?,
spend: to_bytes_uncompressed(&self.0[0])?,
output: to_bytes_uncompressed(&self.0[1])?,
delegator_vote: to_bytes_uncompressed(&self.0[2])?,
undelegate_claim: to_bytes_uncompressed(&self.0[3])?,
swap: to_bytes_uncompressed(&self.0[4])?,
swap_claim: to_bytes_uncompressed(&self.0[5])?,
nullifer_derivation_crs: to_bytes_uncompressed(&self.0[6])?,
})
}
}
Expand All @@ -488,13 +494,15 @@ impl TryFrom<pb::CeremonyCrs> for Phase1RawCeremonyCRS {

fn try_from(value: pb::CeremonyCrs) -> std::result::Result<Self, Self::Error> {
Ok(Self([
Phase1RawCRSElements::deserialize_compressed(value.spend.as_slice())?,
Phase1RawCRSElements::deserialize_compressed(value.output.as_slice())?,
Phase1RawCRSElements::deserialize_compressed(value.delegator_vote.as_slice())?,
Phase1RawCRSElements::deserialize_compressed(value.undelegate_claim.as_slice())?,
Phase1RawCRSElements::deserialize_compressed(value.swap.as_slice())?,
Phase1RawCRSElements::deserialize_compressed(value.swap_claim.as_slice())?,
Phase1RawCRSElements::deserialize_compressed(value.nullifer_derivation_crs.as_slice())?,
Phase1RawCRSElements::deserialize_uncompressed(value.spend.as_slice())?,
Phase1RawCRSElements::deserialize_uncompressed(value.output.as_slice())?,
Phase1RawCRSElements::deserialize_uncompressed(value.delegator_vote.as_slice())?,
Phase1RawCRSElements::deserialize_uncompressed(value.undelegate_claim.as_slice())?,
Phase1RawCRSElements::deserialize_uncompressed(value.swap.as_slice())?,
Phase1RawCRSElements::deserialize_uncompressed(value.swap_claim.as_slice())?,
Phase1RawCRSElements::deserialize_uncompressed(
value.nullifer_derivation_crs.as_slice(),
)?,
]))
}
}
Expand Down
60 changes: 54 additions & 6 deletions tools/summonerd/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,19 @@ use coordinator::Coordinator;
use metrics_tracing_context::MetricsLayer;
use penumbra_keys::FullViewingKey;
use penumbra_proto::tools::summoning::v1alpha1::ceremony_coordinator_service_server::CeremonyCoordinatorServiceServer;
use penumbra_proto::tools::summoning::v1alpha1::CeremonyCrs;
use penumbra_proto::Message;
use std::fs::File;
use std::io::BufReader;
use std::io::Read;
use std::net::SocketAddr;
use storage::Storage;
use tonic::transport::Server;
use tracing_subscriber::{prelude::*, EnvFilter};
use url::Url;

use crate::{penumbra_knower::PenumbraKnower, server::CoordinatorService};
use penumbra_proof_setup::all::Phase1CeremonyCRS;
use penumbra_proof_setup::all::{Phase1CeremonyCRS, Phase1RawCeremonyCRS};

/// 100 MIB
const MAX_MESSAGE_SIZE: usize = 100 * 1024 * 1024;
Expand All @@ -41,6 +46,18 @@ struct Opt {

#[derive(Debug, clap::Subcommand)]
enum Command {
/// Generate a phase 1 root (for testing purposes).
GeneratePhase1 {
#[clap(long, display_order = 100)]
output: Utf8PathBuf,
},
/// Initialize the coordinator.
Init {
#[clap(long, display_order = 100)]
storage_dir: Utf8PathBuf,
#[clap(long, display_order = 200)]
phase1_root: Utf8PathBuf,
},
/// Start the coordinator.
Start {
#[clap(long, display_order = 700)]
Expand All @@ -63,11 +80,7 @@ impl Opt {
node,
listen,
} => {
// TODO: Later we will load the phase 1 root from a file passed in via a command line argument above.
let phase_1_root = Phase1CeremonyCRS::root()?;
let storage =
Storage::load_or_initialize(storage_dir.join("ceremony.db"), phase_1_root)
.await?;
let storage = Storage::load(storage_dir.join("ceremony.db")).await?;
let knower =
PenumbraKnower::load_or_initialize(storage_dir.join("penumbra.db"), &fvk, node)
.await?;
Expand All @@ -92,6 +105,41 @@ impl Opt {
};
Ok(())
}
Command::Init {
storage_dir,
phase1_root,
} => {
let file = File::open(phase1_root)?;
let mut reader = BufReader::new(file);

let mut phase_1_bytes = Vec::new();
let mut buffer = [0; 4096 * 10]; // 40 KB chunks

loop {
let bytes_read = reader.read(&mut buffer)?;
if bytes_read == 0 {
break;
}
phase_1_bytes.extend_from_slice(&buffer[..bytes_read]);
}
dbg!("loaded the file");

let phase_1_raw_root =
Phase1RawCeremonyCRS::try_from(CeremonyCrs::decode(&phase_1_bytes[..])?)?;

dbg!("got phase 1 root");
// This is assumed to be valid as it's the starting point for the ceremony.
let phase_1_root = phase_1_raw_root.assume_valid();

Storage::initialize(storage_dir.join("ceremony.db"), phase_1_root).await?;
Ok(())
}
Command::GeneratePhase1 { output } => {
let phase_1_root = Phase1CeremonyCRS::root()?;
let proto_encoded_phase_1_root: CeremonyCrs = phase_1_root.try_into()?;
std::fs::write(output, proto_encoded_phase_1_root.encode_to_vec())?;
Ok(())
}
}
}
}
Expand Down
27 changes: 2 additions & 25 deletions tools/summonerd/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,6 @@ pub struct Storage {
}

impl Storage {
/// If the database at `storage_path` exists, [`Self::load`] it, otherwise, [`Self::initialize`] it.
pub async fn load_or_initialize(
storage_path: impl AsRef<Utf8Path>,
phase_1_root: Phase1CeremonyCRS,
) -> anyhow::Result<Self> {
if storage_path.as_ref().exists() {
return Self::load(storage_path, phase_1_root).await;
}

Self::initialize(storage_path, phase_1_root).await
}

pub async fn initialize(
storage_path: impl AsRef<Utf8Path>,
phase_1_root: Phase1CeremonyCRS,
Expand Down Expand Up @@ -100,23 +88,11 @@ impl Storage {
Ok(r2d2::Pool::new(manager)?)
}

pub async fn load(
path: impl AsRef<Utf8Path>,
phase_1_root: Phase1CeremonyCRS,
) -> anyhow::Result<Self> {
pub async fn load(path: impl AsRef<Utf8Path>) -> anyhow::Result<Self> {
let storage = Self {
pool: Self::connect(path)?,
};

let current_phase_1_root = storage.phase_1_root().await?;
if current_phase_1_root != phase_1_root {
anyhow::bail!(
"Phase 1 root in database ({:?}) does not match expected root ({:?})",
current_phase_1_root,
phase_1_root
);
}

Ok(storage)
}

Expand Down Expand Up @@ -238,6 +214,7 @@ impl Storage {
}

/// Get Phase 1 root.
#[allow(dead_code)]
pub async fn phase_1_root(&self) -> Result<Phase1CeremonyCRS> {
let mut conn = self.pool.get()?;
let tx = conn.transaction()?;
Expand Down

0 comments on commit 5c98b36

Please sign in to comment.