Skip to content

Commit

Permalink
broken but better
Browse files Browse the repository at this point in the history
  • Loading branch information
distractedm1nd committed Sep 21, 2024
1 parent 508bf2f commit 3b6a5a0
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 348 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions crates/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ hex.workspace = true
sha2.workspace = true
celestia-types.workspace = true
bincode.workspace = true
log.workspace = true
ed25519-dalek.workspace = true
rand.workspace = true

Expand Down
21 changes: 8 additions & 13 deletions crates/common/src/hashchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl Hashchain {
signature: Vec<u8>,
service_id: String,
challenge: ServiceChallengeInput,
) -> Result<Digest> {
) -> Result<HashchainEntry> {
let operation = Operation::CreateAccount(CreateAccountArgs {
id: self.id.clone(),
signature,
Expand All @@ -143,7 +143,7 @@ impl Hashchain {
&self.entries[idx]
}

pub fn push(&mut self, operation: Operation) -> Result<Digest> {
fn push(&mut self, operation: Operation) -> Result<HashchainEntry> {
if operation.id() != self.id {
bail!("Operation ID does not match Hashchain ID");
}
Expand All @@ -156,18 +156,10 @@ impl Hashchain {
let entry = HashchainEntry::new(operation, previous_hash);
self.entries.push(entry.clone());

Ok(entry.hash)
Ok(entry)
}

pub fn add(&mut self, operation: Operation) -> Result<Digest> {
self.perform_operation(operation)
}

pub fn revoke(&mut self, operation: Operation) -> Result<Digest> {
self.perform_operation(operation)
}

fn perform_operation(&mut self, operation: Operation) -> Result<Digest> {
pub fn perform_operation(&mut self, operation: Operation) -> Result<HashchainEntry> {
self.validate_operation(&operation)?;
self.push(operation)
}
Expand All @@ -185,7 +177,10 @@ impl Hashchain {
self.verify_signature(&signing_key, &message, &args.signature.signature)
}
// TODO
Operation::CreateAccount(_) => unimplemented!(),
Operation::CreateAccount(_) => {
println!("oopsie");
Ok(())
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions crates/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@ pub mod hashchain;
pub mod operation;
pub mod tree;

#[macro_use]
extern crate log;

#[cfg(feature = "test_utils")]
pub mod test_utils;
18 changes: 11 additions & 7 deletions crates/common/src/test_utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::{
hashchain::{Hashchain, HashchainEntry},
operation::{KeyOperationArgs, Operation, PublicKey, SignatureBundle},
operation::{
CreateAccountArgs, KeyOperationArgs, Operation, PublicKey, ServiceChallengeInput,
SignatureBundle,
},
tree::{Digest, InsertProof, KeyDirectoryTree, SnarkableTree, UpdateProof},
};
use anyhow::{anyhow, Result};
Expand Down Expand Up @@ -96,8 +99,7 @@ impl TestTreeState {
signature,
});

account.hashchain.add(operation).unwrap();

account.hashchain.perform_operation(operation).unwrap();
Ok(())
}
}
Expand Down Expand Up @@ -173,7 +175,7 @@ pub fn create_random_update(state: &mut TestTreeState, rng: &mut StdRng) -> Upda
},
});

hc.add(final_operation)
hc.perform_operation(final_operation)
.expect("Adding to hashchain should succeed");
println!("updated key: {key:?}");

Expand All @@ -197,13 +199,15 @@ pub fn create_mock_hashchain(id: &str, signing_key: &SigningKey) -> Hashchain {
let public_key = PublicKey::Ed25519(signing_key.verifying_key().to_bytes().to_vec());
let signature = create_mock_signature(signing_key, id.as_bytes());

let op = Operation::AddKey(KeyOperationArgs {
let op = Operation::CreateAccount(CreateAccountArgs {
id: id.to_string(),
value: public_key.clone(),
signature,
signature: signature.signature,
service_id: "test".to_string(),
challenge: ServiceChallengeInput::Signed(Vec::new()),
});

hc.push(op).unwrap();
hc.perform_operation(op).unwrap();
hc
}

Expand Down
64 changes: 63 additions & 1 deletion crates/common/src/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ use jmt::{
storage::{NodeBatch, TreeReader, TreeUpdateBatch, TreeWriter},
JellyfishMerkleTree, KeyHash, RootHash, SimpleHasher,
};
use prism_errors::DatabaseError;
use serde::{ser::SerializeTupleStruct, Deserialize, Serialize};
use std::sync::Arc;

use crate::hashchain::Hashchain;
use crate::{
hashchain::Hashchain,
operation::{CreateAccountArgs, KeyOperationArgs, Operation, ServiceChallengeInput},
};

pub const SPARSE_MERKLE_PLACEHOLDER_HASH: Digest =
Digest::new(*b"SPARSE_MERKLE_PLACEHOLDER_HASH__");
Expand Down Expand Up @@ -229,6 +233,7 @@ impl UpdateProof {
}

pub trait SnarkableTree {
fn process_operation(&mut self, operation: &Operation) -> Result<Proof>;
fn insert(&mut self, key: KeyHash, value: Hashchain) -> Result<InsertProof>;
fn update(&mut self, key: KeyHash, value: Hashchain) -> Result<UpdateProof>;
fn get(&self, key: KeyHash) -> Result<Result<Hashchain, NonMembershipProof>>;
Expand Down Expand Up @@ -303,6 +308,63 @@ impl<S> SnarkableTree for KeyDirectoryTree<S>
where
S: TreeReader + TreeWriter,
{
fn process_operation(&mut self, operation: &Operation) -> Result<Proof> {
match operation {
Operation::AddKey(KeyOperationArgs { id, .. })
| Operation::RevokeKey(KeyOperationArgs { id, .. }) => {
let hashed_id = hash(id.as_bytes());
let key_hash = KeyHash::with::<Hasher>(hashed_id);

let mut current_chain = self
.get(key_hash)?
.map_err(|_| anyhow!("Failed to get hashchain for ID {}", id))?;

current_chain.perform_operation(operation.clone())?;

debug!("updating hashchain for user id {}", id.clone());
let proof = self.update(key_hash, current_chain.clone())?;

Ok(Proof::Update(proof))
}
Operation::CreateAccount(CreateAccountArgs {
id,
value,
signature,
service_id,
challenge,
}) => {
let hashed_id = hash(id.as_bytes());
let key_hash = KeyHash::with::<Hasher>(hashed_id);

match &challenge {
ServiceChallengeInput::Signed(_) => debug!("Signature verification for service challenge gate not yet implemented. Skipping verification.")
};

// hashchain should not already exist
if self.get(key_hash)?.is_ok() {
bail!(DatabaseError::NotFoundError(format!(
"empty slot for ID {}",
id
)));
}

debug!("creating new hashchain for user id {}", id);
let mut chain = Hashchain::new(id.clone());
chain.create_account(
value.clone(),
signature.clone(),
service_id.clone(),
// TODO: Challenge is a placeholder rn
ServiceChallengeInput::Signed(Vec::new()),
)?;

Ok(Proof::Insert(
self.insert(KeyHash::with::<Hasher>(hashed_id), chain)?,
))
}
}
}

fn insert(&mut self, key: KeyHash, value: Hashchain) -> Result<InsertProof> {
let serialized_value = Self::serialize_value(&value)?;

Expand Down
Loading

0 comments on commit 3b6a5a0

Please sign in to comment.