pub mod circuit;
mod bytes;
mod parse;
mod serialize;
use crate::ledger::{
BlockPath,
HeaderLeaf,
HeaderPath,
TransactionLeaf,
TransactionPath,
TransactionsPath,
TransitionLeaf,
TransitionPath,
};
use console::{network::prelude::*, types::Field};
#[derive(Clone, PartialEq, Eq)]
pub struct StatePath<N: Network> {
state_root: N::StateRoot,
block_path: BlockPath<N>,
block_hash: N::BlockHash,
previous_block_hash: N::BlockHash,
header_root: Field<N>,
header_path: HeaderPath<N>,
header_leaf: HeaderLeaf<N>,
transactions_path: TransactionsPath<N>,
transaction_id: N::TransactionID,
transaction_path: TransactionPath<N>,
transaction_leaf: TransactionLeaf<N>,
transition_path: TransitionPath<N>,
transition_leaf: TransitionLeaf<N>,
}
impl<N: Network> StatePath<N> {
#[allow(clippy::too_many_arguments)]
pub fn new(
state_root: N::StateRoot,
block_path: BlockPath<N>,
block_hash: N::BlockHash,
previous_block_hash: N::BlockHash,
header_root: Field<N>,
header_path: HeaderPath<N>,
header_leaf: HeaderLeaf<N>,
transactions_path: TransactionsPath<N>,
transaction_id: N::TransactionID,
transaction_path: TransactionPath<N>,
transaction_leaf: TransactionLeaf<N>,
transition_path: TransitionPath<N>,
transition_leaf: TransitionLeaf<N>,
) -> Result<Self> {
ensure!(
N::verify_merkle_path_bhp(&transition_path, &transaction_leaf.id(), &transition_leaf.to_bits_le()),
"'{}' (an input or output ID) does not belong to '{}' (a function or transition)",
transition_leaf.id(),
transaction_leaf.id()
);
ensure!(
N::verify_merkle_path_bhp(&transaction_path, &transaction_id, &transaction_leaf.to_bits_le()),
"'{}' (a function or transition) does not belong to transaction '{transaction_id}'",
transaction_leaf.id(),
);
ensure!(
N::verify_merkle_path_bhp(&transactions_path, &header_leaf.id(), &transaction_id.to_bits_le()),
"Transaction '{transaction_id}' does not belong to '{header_leaf}' (a header leaf)",
);
ensure!(
N::verify_merkle_path_bhp(&header_path, &header_root, &header_leaf.to_bits_le()),
"'{header_leaf}' (a header leaf) does not belong to '{block_hash}' (a block header)",
);
let preimage = (*previous_block_hash).to_bits_le().into_iter().chain(header_root.to_bits_le().into_iter());
ensure!(
*block_hash == N::hash_bhp1024(&preimage.collect::<Vec<_>>())?,
"Block hash '{block_hash}' is incorrect. Double-check the previous block hash and block header root."
);
ensure!(
N::verify_merkle_path_bhp(&block_path, &state_root, &block_hash.to_bits_le()),
"'{block_hash}' (a block hash) does not belong to '{state_root}' (a state root)",
);
Ok(Self {
state_root,
block_path,
block_hash,
previous_block_hash,
header_root,
header_path,
header_leaf,
transactions_path,
transaction_id,
transaction_path,
transaction_leaf,
transition_path,
transition_leaf,
})
}
pub const fn state_root(&self) -> N::StateRoot {
self.state_root
}
pub const fn block_path(&self) -> &BlockPath<N> {
&self.block_path
}
pub const fn block_hash(&self) -> N::BlockHash {
self.block_hash
}
pub const fn previous_block_hash(&self) -> N::BlockHash {
self.previous_block_hash
}
pub const fn header_root(&self) -> &Field<N> {
&self.header_root
}
pub const fn header_path(&self) -> &HeaderPath<N> {
&self.header_path
}
pub const fn header_leaf(&self) -> &HeaderLeaf<N> {
&self.header_leaf
}
pub const fn transactions_path(&self) -> &TransactionsPath<N> {
&self.transactions_path
}
pub const fn transaction_id(&self) -> &N::TransactionID {
&self.transaction_id
}
pub const fn transaction_path(&self) -> &TransactionPath<N> {
&self.transaction_path
}
pub const fn transaction_leaf(&self) -> &TransactionLeaf<N> {
&self.transaction_leaf
}
pub const fn transition_path(&self) -> &TransitionPath<N> {
&self.transition_path
}
pub const fn transition_leaf(&self) -> &TransitionLeaf<N> {
&self.transition_leaf
}
}