use super::*;
#[derive(Clone, Debug)]
pub struct InclusionAssignment<N: Network> {
pub(crate) state_path: StatePath<N>,
commitment: Field<N>,
gamma: Group<N>,
serial_number: Field<N>,
is_record_block_height_reached: bool,
upgrade_block_height: u32,
local_state_root: N::TransactionID,
is_global: bool,
}
impl<N: Network> InclusionAssignment<N> {
pub fn new(
state_path: StatePath<N>,
commitment: Field<N>,
gamma: Group<N>,
serial_number: Field<N>,
is_record_block_height_reached: bool,
upgrade_block_height: u32,
local_state_root: N::TransactionID,
is_global: bool,
) -> Self {
Self {
state_path,
commitment,
gamma,
serial_number,
is_record_block_height_reached,
upgrade_block_height,
local_state_root,
is_global,
}
}
pub fn to_circuit_assignment<A: circuit::Aleo<Network = N>>(&self) -> Result<circuit::Assignment<N::Field>> {
use circuit::Inject;
assert_eq!(A::count(), (0, 1, 0, 0, (0, 0, 0)));
A::reset();
let state_path = circuit::StatePath::<A>::new(circuit::Mode::Private, self.state_path.clone());
let commitment = circuit::Field::<A>::new(circuit::Mode::Private, self.commitment);
let gamma = circuit::Group::<A>::new(circuit::Mode::Private, self.gamma);
let local_state_root = circuit::Field::<A>::new(circuit::Mode::Public, *self.local_state_root);
let is_global = circuit::Boolean::<A>::new(circuit::Mode::Private, self.is_global);
let serial_number = circuit::Field::<A>::new(circuit::Mode::Public, self.serial_number);
let is_record_block_height_reached =
circuit::Boolean::<A>::new(circuit::Mode::Public, self.is_record_block_height_reached);
let upgrade_block_height_field = circuit::Field::<A>::new(
circuit::Mode::Public,
console::types::Field::<N>::from_u32(self.upgrade_block_height),
);
let upgrade_block_height = circuit::U32::from_field(upgrade_block_height_field);
let candidate_serial_number =
circuit::Record::<A, circuit::Plaintext<A>>::serial_number_from_gamma(&gamma, commitment.clone());
A::assert_eq(candidate_serial_number, serial_number)?;
A::assert_eq(state_path.transition_leaf().id(), commitment)?;
A::assert(state_path.verify(&is_global, &local_state_root))?;
let record_block_height = U32::<A>::from_bits_le(&state_path.block_path().leaf_index().to_bits_le());
let is_record_block_height_past_upgrade_block_height =
record_block_height.is_greater_than_or_equal(&upgrade_block_height);
let is_block_height_check_valid =
is_record_block_height_reached.is_equal(&is_record_block_height_past_upgrade_block_height);
A::assert(is_global.not().bitor(is_block_height_check_valid))?;
Stack::log_circuit::<A>(
format_args!("State Path for {}", self.serial_number),
"InclusionAssignment".to_string(),
);
Ok(A::eject_assignment_and_reset())
}
}