-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: refactoring into crates and adding nova, sp1 (#115)
* feat(WIP): nova * fix: not using struct variants in step enum * removing dead code * fuck this man what am i even doing * feat: beginning of migration to jmt * refactor: redis as JMT backend (temporarily) * progress on JMT migration: removing lifetime annotations to own TreeReader * build errors * supernova * fix some things * write_batch * failing test * nova batch updates * cargo fix imports * removing unused deps * adding pp serde * updating cargo toml * feat: playing around with supernova rehashing * membership proof * invalid witness length * i give up * restructuring to crates * readding groth16 as new crate * readding groth16 as new crate * adding sp1 crate * trimming deps * readmes * clippy * readmes and clippy * debugging storage.rs for jmt * fixing tests * patches * clippy --------- Co-authored-by: sebasti810 <spusch@outlook.de>
- Loading branch information
1 parent
d8e74ea
commit 2967421
Showing
48 changed files
with
3,525 additions
and
2,757 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[package] | ||
name = "prism-common" | ||
version.workspace = true | ||
edition.workspace = true | ||
license.workspace = true | ||
homepage.workspace = true | ||
repository.workspace = true | ||
|
||
[dependencies] | ||
anyhow.workspace = true | ||
bls12_381.workspace = true | ||
borsh.workspace = true | ||
jmt.workspace = true | ||
serde.workspace = true | ||
hex.workspace = true | ||
sha2.workspace = true | ||
blake2.workspace = true | ||
celestia-types.workspace = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
use anyhow::{bail, Result}; | ||
use borsh::{BorshDeserialize, BorshSerialize}; | ||
use jmt::KeyHash; | ||
use serde::{Deserialize, Serialize}; | ||
use std::ops::{Deref, DerefMut}; | ||
|
||
use crate::{ | ||
operation::{AccountSource, Operation}, | ||
tree::{hash, Digest, Hasher}, | ||
}; | ||
|
||
#[derive(Clone, BorshSerialize, BorshDeserialize, Serialize, Deserialize, Debug, PartialEq)] | ||
pub struct Hashchain { | ||
pub id: String, | ||
pub entries: Vec<HashchainEntry>, | ||
} | ||
|
||
impl IntoIterator for Hashchain { | ||
type Item = HashchainEntry; | ||
type IntoIter = std::vec::IntoIter<Self::Item>; | ||
|
||
fn into_iter(self) -> Self::IntoIter { | ||
self.entries.into_iter() | ||
} | ||
} | ||
|
||
impl<'a> IntoIterator for &'a Hashchain { | ||
type Item = &'a HashchainEntry; | ||
type IntoIter = std::slice::Iter<'a, HashchainEntry>; | ||
|
||
fn into_iter(self) -> Self::IntoIter { | ||
self.entries.iter() | ||
} | ||
} | ||
|
||
impl<'a> IntoIterator for &'a mut Hashchain { | ||
type Item = &'a mut HashchainEntry; | ||
type IntoIter = std::slice::IterMut<'a, HashchainEntry>; | ||
|
||
fn into_iter(self) -> Self::IntoIter { | ||
self.entries.iter_mut() | ||
} | ||
} | ||
|
||
impl Deref for Hashchain { | ||
type Target = Vec<HashchainEntry>; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
&self.entries | ||
} | ||
} | ||
|
||
impl DerefMut for Hashchain { | ||
fn deref_mut(&mut self) -> &mut Self::Target { | ||
&mut self.entries | ||
} | ||
} | ||
|
||
impl Hashchain { | ||
pub fn new(id: String) -> Self { | ||
Self { | ||
id, | ||
entries: Vec::new(), | ||
} | ||
} | ||
|
||
pub fn iter(&self) -> std::slice::Iter<'_, HashchainEntry> { | ||
self.entries.iter() | ||
} | ||
|
||
pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, HashchainEntry> { | ||
self.entries.iter_mut() | ||
} | ||
|
||
pub fn create_account(&mut self, value: String, source: AccountSource) -> Result<Digest> { | ||
let operation = Operation::CreateAccount { | ||
id: self.id.clone(), | ||
value, | ||
source, | ||
}; | ||
self.push(operation) | ||
} | ||
|
||
pub fn get(&self, idx: usize) -> &HashchainEntry { | ||
&self.entries[idx] | ||
} | ||
|
||
pub fn push(&mut self, operation: Operation) -> Result<Digest> { | ||
if operation.id() != self.id { | ||
bail!("Operation ID does not match Hashchain ID"); | ||
} | ||
|
||
let previous_hash = self | ||
.entries | ||
.last() | ||
.map_or(Digest::new([0u8; 32]), |entry| entry.hash); | ||
|
||
let entry = HashchainEntry::new(operation, previous_hash); | ||
self.entries.push(entry.clone()); | ||
|
||
Ok(entry.hash) | ||
} | ||
|
||
// TODO: Obviously, this needs to be authenticated by an existing key. | ||
pub fn add(&mut self, value: String) -> Result<Digest> { | ||
let operation = Operation::Add { | ||
id: self.id.clone(), | ||
value, | ||
}; | ||
self.push(operation) | ||
} | ||
|
||
pub fn revoke(&mut self, value: String) -> Result<Digest> { | ||
let operation = Operation::Revoke { | ||
id: self.id.clone(), | ||
value, | ||
}; | ||
self.push(operation) | ||
} | ||
|
||
pub fn get_keyhash(&self) -> KeyHash { | ||
KeyHash::with::<Hasher>(self.id.clone()) | ||
} | ||
|
||
pub fn is_empty(&self) -> bool { | ||
self.entries.is_empty() | ||
} | ||
|
||
pub fn len(&self) -> usize { | ||
self.entries.len() | ||
} | ||
} | ||
|
||
#[derive(Clone, BorshSerialize, BorshDeserialize, Serialize, Deserialize, Debug, PartialEq)] | ||
// A [`HashchainEntry`] represents a single entry in an account's hashchain. | ||
// The value in the leaf of the corresponding account's node in the IMT is the hash of the last node in the hashchain. | ||
pub struct HashchainEntry { | ||
pub hash: Digest, | ||
pub previous_hash: Digest, | ||
pub operation: Operation, | ||
} | ||
|
||
impl HashchainEntry { | ||
pub fn new(operation: Operation, previous_hash: Digest) -> Self { | ||
let hash = { | ||
let mut data = Vec::new(); | ||
data.extend_from_slice(operation.to_string().as_bytes()); | ||
data.extend_from_slice(previous_hash.as_ref()); | ||
// TODO: replace with sha256 after JMT complete | ||
hash(&data) | ||
}; | ||
Self { | ||
hash, | ||
previous_hash, | ||
operation, | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub mod hashchain; | ||
pub mod operation; | ||
pub mod tree; |
Oops, something went wrong.