Skip to content

Commit

Permalink
more
Browse files Browse the repository at this point in the history
  • Loading branch information
altendky committed Jan 24, 2025
1 parent 796618e commit d3494d2
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
52 changes: 52 additions & 0 deletions crates/chia-datalayer/src/merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,46 @@ pub struct ProofOfInclusion {
pub layers: Vec<ProofOfInclusionLayer>,
}

impl ProofOfInclusion {
pub fn root_hash(&self) -> Hash {
if let Some(last) = self.layers.last() {
last.combined_hash
} else {
self.node_hash
}
}

pub fn valid(&self) -> bool {
let mut existing_hash = self.node_hash;

for layer in &self.layers {
let calculated_hash =
calculate_internal_hash(&existing_hash, layer.other_hash_side, &layer.other_hash);

if calculated_hash != layer.combined_hash {
return false;
}

existing_hash = calculated_hash;
}

existing_hash == self.root_hash()
}
}

#[cfg(feature = "py-bindings")]
#[pymethods]
impl ProofOfInclusion {
#[pyo3(name = "root_hash")]
pub fn py_root_hash(&self) -> Hash {
self.root_hash()
}
#[pyo3(name = "valid")]
pub fn py_valid(&self) -> bool {
self.valid()
}
}

#[allow(clippy::needless_pass_by_value)]
fn sha256_num<T: ToBytes>(input: T) -> Hash {
let mut hasher = Sha256::new();
Expand All @@ -334,6 +374,13 @@ fn internal_hash(left_hash: &Hash, right_hash: &Hash) -> Hash {
Hash(Bytes32::new(hasher.finalize()))
}

pub fn calculate_internal_hash(hash: &Hash, other_hash_side: Side, other_hash: &Hash) -> Hash {
match other_hash_side {
Side::Left => internal_hash(other_hash, hash),
Side::Right => internal_hash(hash, other_hash),
}
}

#[cfg_attr(feature = "py-bindings", pyclass(eq, eq_int))]
#[repr(u8)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Streamable)]
Expand Down Expand Up @@ -1631,6 +1678,11 @@ impl MerkleBlob {
pub fn py_get_key_index(&self, key: KeyId) -> PyResult<TreeIndex> {
Ok(self.get_key_index(key)?)
}

#[pyo3(name = "get_proof_of_inclusion")]
pub fn py_get_proof_of_inclusion(&self, key: KeyId) -> PyResult<ProofOfInclusion> {
Ok(self.get_proof_of_inclusion(key)?)
}
}

fn try_get_block(blob: &[u8], index: TreeIndex) -> Result<Block, Error> {
Expand Down
4 changes: 4 additions & 0 deletions wheel/python/chia_rs/datalayer.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ class ProofOfInclusion:
# children before parents
layers: list[ProofOfInclusionLayer]

def root_hash(self) -> bytes32: ...
def valid(self) -> bool: ...

@final
class MerkleBlob:
@property
Expand Down Expand Up @@ -103,6 +106,7 @@ class MerkleBlob:
def get_hash_at_index(self, index: uint32): ...
def get_keys_values(self) -> dict[int64, int64]: ...
def get_key_index(self, key: int64) -> uint32: ...
def get_proof_of_inclusion(self, key: int64) -> ProofOfInclusion: ...

def __len__(self) -> int: ...

Expand Down

0 comments on commit d3494d2

Please sign in to comment.