-
Notifications
You must be signed in to change notification settings - Fork 221
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat!: implement command inclusion proof for eviction
- Loading branch information
Showing
19 changed files
with
2,581 additions
and
4 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
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
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
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,15 @@ | ||
[package] | ||
name = "tari_jellyfish" | ||
version.workspace = true | ||
edition.workspace = true | ||
authors.workspace = true | ||
|
||
[dependencies] | ||
tari_hashing = { workspace = true } | ||
tari_crypto = "0.21.0" | ||
|
||
serde = { version = "1.0", features = ["derive"] } | ||
borsh = "1.5" | ||
digest = "0.10" | ||
thiserror = "2.0" | ||
indexmap = { version = "2.6", features = ["serde"] } |
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,54 @@ | ||
// Copyright 2024 The Tari Project | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
|
||
use std::ops::Range; | ||
|
||
/// An iterator over a hash value that generates one bit for each iteration. | ||
pub struct BitIterator<'a> { | ||
/// The reference to the bytes that represent the `HashValue`. | ||
bytes: &'a [u8], | ||
pos: Range<usize>, | ||
// invariant hash_bytes.len() == HashValue::LENGTH; | ||
// invariant pos.end == hash_bytes.len() * 8; | ||
} | ||
|
||
impl<'a> BitIterator<'a> { | ||
/// Constructs a new `BitIterator` using given `HashValue`. | ||
pub fn new(bytes: &'a [u8]) -> Self { | ||
BitIterator { | ||
bytes, | ||
pos: 0..bytes.len() * 8, | ||
} | ||
} | ||
|
||
/// Returns the `index`-th bit in the bytes. | ||
fn get_bit(&self, index: usize) -> bool { | ||
// MIRAI annotations - important? | ||
// assume!(index < self.pos.end); // assumed precondition | ||
// assume!(self.hash_bytes.len() == 32); // invariant | ||
// assume!(self.pos.end == self.hash_bytes.len() * 8); // invariant | ||
let pos = index / 8; | ||
let bit = 7 - index % 8; | ||
(self.bytes[pos] >> bit) & 1 != 0 | ||
} | ||
} | ||
|
||
impl<'a> Iterator for BitIterator<'a> { | ||
type Item = bool; | ||
|
||
fn next(&mut self) -> Option<Self::Item> { | ||
self.pos.next().map(|x| self.get_bit(x)) | ||
} | ||
|
||
fn size_hint(&self) -> (usize, Option<usize>) { | ||
self.pos.size_hint() | ||
} | ||
} | ||
|
||
impl<'a> DoubleEndedIterator for BitIterator<'a> { | ||
fn next_back(&mut self) -> Option<Self::Item> { | ||
self.pos.next_back().map(|x| self.get_bit(x)) | ||
} | ||
} | ||
|
||
impl<'a> ExactSizeIterator for BitIterator<'a> {} |
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,30 @@ | ||
// Copyright 2024 The Tari Project | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
|
||
use crate::{LeafKey, TreeHash}; | ||
|
||
#[derive(Debug, thiserror::Error)] | ||
pub enum JmtProofVerifyError { | ||
#[error("Sparse Merkle Tree proof has more than 256 ({num_siblings}) siblings.")] | ||
TooManySiblings { num_siblings: usize }, | ||
#[error("Keys do not match. Key in proof: {actual_key}. Expected key: {expected_key}.")] | ||
KeyMismatch { actual_key: LeafKey, expected_key: LeafKey }, | ||
#[error("Value hashes do not match. Value hash in proof: {actual}. Expected value hash: {expected}.")] | ||
ValueMismatch { actual: TreeHash, expected: TreeHash }, | ||
#[error("Expected inclusion proof. Found non-inclusion proof.")] | ||
ExpectedInclusionProof, | ||
#[error("Expected non-inclusion proof, but key exists in proof.")] | ||
ExpectedNonInclusionProof, | ||
#[error( | ||
"Key would not have ended up in the subtree where the provided key in proof is the only existing key, if it \ | ||
existed. So this is not a valid non-inclusion proof." | ||
)] | ||
InvalidNonInclusionProof, | ||
#[error( | ||
"Root hashes do not match. Actual root hash: {actual_root_hash}. Expected root hash: {expected_root_hash}." | ||
)] | ||
RootHashMismatch { | ||
actual_root_hash: TreeHash, | ||
expected_root_hash: TreeHash, | ||
}, | ||
} |
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,77 @@ | ||
// Copyright 2024 The Tari Project | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
|
||
use std::{ | ||
fmt::{Display, Formatter}, | ||
ops::{Deref, DerefMut}, | ||
}; | ||
|
||
use borsh::{BorshDeserialize, BorshSerialize}; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
#[derive( | ||
Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, BorshSerialize, BorshDeserialize, Serialize, Deserialize, | ||
)] | ||
pub struct TreeHash([u8; 32]); | ||
|
||
impl TreeHash { | ||
pub const fn new(bytes: [u8; 32]) -> Self { | ||
Self(bytes) | ||
} | ||
|
||
pub const fn zero() -> Self { | ||
Self([0; 32]) | ||
} | ||
|
||
pub const fn into_array(self) -> [u8; 32] { | ||
self.0 | ||
} | ||
|
||
pub fn try_from_bytes(bytes: &[u8]) -> Result<Self, TreeHashSizeError> { | ||
if bytes.len() != 32 { | ||
return Err(TreeHashSizeError); | ||
} | ||
let mut arr = [0u8; 32]; | ||
arr.copy_from_slice(bytes); | ||
Ok(Self(arr)) | ||
} | ||
} | ||
|
||
impl From<[u8; 32]> for TreeHash { | ||
fn from(bytes: [u8; 32]) -> Self { | ||
Self(bytes) | ||
} | ||
} | ||
|
||
impl Deref for TreeHash { | ||
type Target = [u8; 32]; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
&self.0 | ||
} | ||
} | ||
|
||
impl DerefMut for TreeHash { | ||
fn deref_mut(&mut self) -> &mut Self::Target { | ||
&mut self.0 | ||
} | ||
} | ||
|
||
impl<T: AsRef<[u8]>> PartialEq<T> for TreeHash { | ||
fn eq(&self, other: &T) -> bool { | ||
self.0 == other.as_ref() | ||
} | ||
} | ||
|
||
impl Display for TreeHash { | ||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||
for b in self.0 { | ||
write!(f, "{:02x}", b)?; | ||
} | ||
Ok(()) | ||
} | ||
} | ||
|
||
#[derive(Debug, thiserror::Error)] | ||
#[error("Invalid TreeHash byte size. Must be 32 bytes.")] | ||
pub struct TreeHashSizeError; |
Oops, something went wrong.