diff --git a/crates/crypto/proof-setup/src/all.rs b/crates/crypto/proof-setup/src/all.rs index f3e8316e1b..52c0e978cb 100644 --- a/crates/crypto/proof-setup/src/all.rs +++ b/crates/crypto/proof-setup/src/all.rs @@ -109,11 +109,11 @@ impl From for Phase2RawCeremonyCRS { } } -impl TryInto for Phase2CeremonyCRS { +impl TryFrom for pb::CeremonyCrs { type Error = anyhow::Error; - fn try_into(self) -> Result { - Phase2RawCeremonyCRS::from(self).try_into() + fn try_from(data: Phase2CeremonyCRS) -> Result { + Phase2RawCeremonyCRS::from(data).try_into() } } @@ -413,11 +413,11 @@ impl From for Phase2RawCeremonyContribution { } } -impl TryInto for Phase2CeremonyContribution { +impl TryFrom for pb::participate_request::Contribution { type Error = anyhow::Error; - fn try_into(self) -> Result { - Phase2RawCeremonyContribution::from(self).try_into() + fn try_from(data: Phase2CeremonyContribution) -> Result { + Phase2RawCeremonyContribution::from(data).try_into() } } diff --git a/tools/summonerd/src/coordinator.rs b/tools/summonerd/src/coordinator.rs index 27f6d90971..edb7e69cd3 100644 --- a/tools/summonerd/src/coordinator.rs +++ b/tools/summonerd/src/coordinator.rs @@ -142,12 +142,10 @@ impl Coordinator { return Ok(()); } }; - //if let Some(contribution) = contribution.validate(&mut OsRng, &self.storage.root().await?) { - if true { - let contribution = contribution.assume_valid(); + if let Some(contribution) = contribution.validate(&mut OsRng, &self.storage.root().await?) { if contribution.is_linked_to(&parent) { self.storage - .commit_contribution(contributor, &contribution) + .commit_contribution(contributor, contribution) .await?; participant .confirm(self.storage.current_slot().await?) diff --git a/tools/summonerd/src/storage.rs b/tools/summonerd/src/storage.rs index 29a2519a16..30a3ffc07e 100644 --- a/tools/summonerd/src/storage.rs +++ b/tools/summonerd/src/storage.rs @@ -1,17 +1,22 @@ -use std::sync::Arc; - use anyhow::Result; use camino::Utf8Path; use penumbra_keys::Address; -use penumbra_proof_setup::all::{Phase2CeremonyCRS, Phase2CeremonyContribution}; +use penumbra_proof_setup::all::{ + Phase2CeremonyCRS, Phase2CeremonyContribution, Phase2RawCeremonyCRS, + Phase2RawCeremonyContribution, +}; +use penumbra_proto::{ + penumbra::tools::summoning::v1alpha1::{ + self as pb, participate_request::Contribution as PBContribution, + }, + Message, +}; use r2d2_sqlite::{rusqlite::OpenFlags, SqliteConnectionManager}; -use tokio::sync::Mutex; use tokio::task::spawn_blocking; #[derive(Clone)] pub struct Storage { pool: r2d2::Pool, - crs: Arc>, } impl Storage { @@ -35,15 +40,16 @@ impl Storage { // Create the tables tx.execute_batch(include_str!("storage/schema.sql"))?; + // TODO: Remove this in favor of a specific command for initializing root + let root = Phase2CeremonyCRS::root()?; + tx.execute( + "INSERT INTO phase2_contributions VALUES (0, 1, ?1, NULL)", + [pb::CeremonyCrs::try_from(root)?.encode_to_vec()], + )?; tx.commit()?; - drop(conn); - let root = Phase2CeremonyCRS::root()?; - Ok(Storage { - pool, - crs: Arc::new(Mutex::new(root.clone())), - }) + Ok(Storage { pool }) }) .await? } @@ -65,10 +71,8 @@ impl Storage { } pub async fn load(path: impl AsRef) -> anyhow::Result { - let root: Phase2CeremonyCRS = Phase2CeremonyCRS::root()?; let storage = Self { pool: Self::connect(path)?, - crs: Arc::new(Mutex::new(root.clone())), }; Ok(storage) @@ -83,22 +87,42 @@ impl Storage { } pub async fn current_crs(&self) -> Result { - Ok(self.crs.lock().await.clone()) + let mut conn = self.pool.get()?; + let tx = conn.transaction()?; + let (is_root, contribution_or_crs) = tx.query_row( + "SELECT is_root, contribution_or_crs FROM phase2_contributions ORDER BY slot DESC LIMIT 1", + [], + |row| Ok((row.get::(0)?, row.get::>(1)?)), + )?; + let crs = if is_root { + Phase2RawCeremonyCRS::try_from(pb::CeremonyCrs::decode( + contribution_or_crs.as_slice(), + )?)? + .assume_valid() + } else { + Phase2RawCeremonyContribution::try_from(PBContribution::decode( + contribution_or_crs.as_slice(), + )?)? + .assume_valid() + .new_elements() + }; + Ok(crs) } - // TODO: Add other stuff here pub async fn commit_contribution( &self, contributor: Address, - contribution: &Phase2CeremonyContribution, + contribution: Phase2CeremonyContribution, ) -> Result<()> { - *self.crs.lock().await = contribution.new_elements(); let mut conn = self.pool.get()?; let tx = conn.transaction()?; let contributor_bytes = contributor.to_vec(); tx.execute( - "INSERT INTO phase2_contributions VALUES(NULL, ?1)", - [contributor_bytes], + "INSERT INTO phase2_contributions VALUES(NULL, 0, ?1, ?2)", + [ + PBContribution::try_from(contribution)?.encode_to_vec(), + contributor_bytes, + ], )?; tx.commit()?; Ok(()) @@ -114,4 +138,18 @@ impl Storage { .unwrap_or(0); Ok(out) } + + pub async fn root(&self) -> Result { + let mut conn = self.pool.get()?; + let tx = conn.transaction()?; + let data = tx.query_row( + "SELECT contribution_or_crs FROM phase2_contributions WHERE is_root LIMIT 1", + [], + |row| row.get::>(0), + )?; + Ok(Phase2RawCeremonyCRS::try_from(pb::CeremonyCrs::decode( + data.as_slice(), + )?)? + .assume_valid()) + } } diff --git a/tools/summonerd/src/storage/schema.sql b/tools/summonerd/src/storage/schema.sql index 9e491ab196..7992715fcc 100644 --- a/tools/summonerd/src/storage/schema.sql +++ b/tools/summonerd/src/storage/schema.sql @@ -1,5 +1,10 @@ -- used for storing phase 2 contribution information CREATE TABLE phase2_contributions ( slot INTEGER PRIMARY KEY, - address BLOB NOT NULL + -- 1 if this is a root + is_root INTEGER NOT NULL, + -- If this is the root, will be just the elements, and not a full contribution + contribution_or_crs BLOB NOT NULL, + -- NULL in the specific case that this is the root + address BLOB );