mod common;
use common::{bbg_object_from_state, default_params, make_look_formula, zero_statement};
use nox::{reduce, Order, VecTrace, Outcome};
use zheng::{commit, verify};
use bbg::{Bbg, Signal as BbgSignal, Cyberlink as BbgCyberlink, Particle, NeuronId};
use bbg::types::NeuronRecord;
use bbg::{BoxMove, InsertError, ProofLookProvider};
const ORDER_SIZE: usize = 1024;
fn neuron(seed: u8) -> NeuronId { [seed; 32] }
fn particle(seed: u8) -> Particle { [seed; 32] }
fn one_link(neuron: NeuronId, from: Particle, to: Particle, height: u64) -> BbgSignal {
BbgSignal {
neuron,
links: vec![BbgCyberlink { from, to, token: particle(0), amount: 1, valence: 1 }],
box_moves: vec![],
height,
}
}
#[test]
fn finalize_block_updates_root_and_look_proof_consistent() {
let mut bbg = Bbg::new();
let n = neuron(1);
bbg.state.neurons.insert(n, NeuronRecord { focus: 100_000, karma: 0, stake: 0 });
bbg.insert(&one_link(n, particle(2), particle(3), 0)).unwrap();
let root_before = bbg.state.root;
bbg.finalize_block();
assert_eq!(bbg.state.height, 1);
assert_ne!(bbg.state.root, root_before, "root must change after finalize");
assert!(bbg.state.time.contains_key(&0), "time[0] must exist after finalize");
let prov = ProofLookProvider::new(&bbg.state);
let mut order = Order::<ORDER_SIZE>::new();
let bbg_obj = bbg_object_from_state(&mut order, &bbg.state);
let formula = make_look_formula(&mut order, 8, 0);
let mut trace = VecTrace::default();
let outcome = reduce(&mut order, bbg_obj, formula, 1000, &prov, &mut trace);
assert!(matches!(outcome, Outcome::Ok(_, _)), "look(Time, 0) must succeed");
let look_openings = prov.take_look_openings();
assert_eq!(look_openings.len(), 1);
let stmt = zero_statement();
let proof = commit(&trace, &[], &[], &look_openings, &stmt, &default_params()).unwrap();
verify(&proof, &stmt, &default_params())
.expect("finalize+look proof must verify");
}
#[test]
fn box_moves_nullifier_double_spend_rejected() {
let mut bbg = Bbg::new();
let n = neuron(1);
bbg.state.neurons.insert(n, NeuronRecord { focus: 100_000, karma: 0, stake: 0 });
let nullifier = particle(77);
let mk = |commitment| BbgSignal {
neuron: n,
links: vec![],
box_moves: vec![BoxMove { nullifier, commitment }],
height: 0,
};
bbg.insert(&mk(Some((particle(88), 500)))).expect("first box spend must succeed");
assert_eq!(
bbg.insert(&mk(None)),
Err(InsertError::DoubleSpend),
"reusing nullifier must fail with DoubleSpend",
);
}
#[test]
fn checkpoint_tracks_state_after_finalize() {
let mut bbg = Bbg::new();
let n = neuron(1);
bbg.state.neurons.insert(n, NeuronRecord { focus: 100_000, karma: 0, stake: 0 });
bbg.insert(&one_link(n, particle(2), particle(3), 0)).unwrap();
bbg.finalize_block();
assert_eq!(bbg.checkpoint.root, bbg.state.root,
"checkpoint.root must match state.root after finalize");
assert_eq!(bbg.checkpoint.height, bbg.state.height,
"checkpoint.height must match state.height after finalize");
}
#[test]
fn multi_block_insert_finalize_cycle_then_look_proof() {
let mut bbg = Bbg::new();
let n = neuron(1);
bbg.state.neurons.insert(n, NeuronRecord { focus: 200_000, karma: 0, stake: 0 });
bbg.insert(&one_link(n, particle(2), particle(3), 0)).unwrap();
bbg.finalize_block();
bbg.insert(&one_link(n, particle(4), particle(5), 1)).unwrap();
bbg.finalize_block();
assert_eq!(bbg.state.height, 2);
assert!(bbg.state.time.contains_key(&0), "time[0] must exist");
assert!(bbg.state.time.contains_key(&1), "time[1] must exist");
let prov = ProofLookProvider::new(&bbg.state);
let mut order = Order::<ORDER_SIZE>::new();
let bbg_obj = bbg_object_from_state(&mut order, &bbg.state);
let formula = make_look_formula(&mut order, 8, 1);
let mut trace = VecTrace::default();
let outcome = reduce(&mut order, bbg_obj, formula, 1000, &prov, &mut trace);
assert!(matches!(outcome, Outcome::Ok(_, _)), "look(Time, 1) must succeed");
let look_openings = prov.take_look_openings();
assert_eq!(look_openings.len(), 1);
let stmt = zero_statement();
let proof = commit(&trace, &[], &[], &look_openings, &stmt, &default_params()).unwrap();
verify(&proof, &stmt, &default_params())
.expect("multi-block lifecycle look proof must verify");
}