mod common;
use common::{bbg_object_from_state, default_params, make_look_formula, zero_statement};
use bbg::ProofLookProvider;
use bbg::types::NeuronRecord;
use bbg::{BbgState, Cyberlink as BbgCyberlink, NeuronId, Particle, Signal as BbgSignal};
use cybergraph::{
SELF_NETWORK, Signal, SignalChain, challenge_from_hash, vdf_evaluate, vdf_verify,
};
use nox::{Order, Outcome, VecTrace, reduce};
use zheng::{commit, verify};
const ORDER_SIZE: usize = 1024;
fn neuron(seed: u8) -> NeuronId {
[seed; 32]
}
fn particle(seed: u8) -> Particle {
[seed; 32]
}
fn make_signal(n: NeuronId, step: u64, prev: Particle) -> Signal {
Signal {
neuron: n,
network: SELF_NETWORK,
links: vec![],
delta_pi: vec![],
box_moves: vec![],
prev,
step,
height: 0,
proof: None,
}
}
#[test]
fn signal_chain_ordering_and_rejection() {
let n = neuron(1);
let mut chain = SignalChain::new();
let s0 = make_signal(n, 0, [0u8; 32]);
let h0 = s0.hash();
chain.append(s0).unwrap();
let s1 = make_signal(n, 1, h0);
let h1 = s1.hash();
chain.append(s1).unwrap();
let s2 = make_signal(n, 2, h1);
chain.append(s2).unwrap();
assert_eq!(chain.entries.len(), 3);
assert!(
chain.append(make_signal(n, 5, [0u8; 32])).is_err(),
"wrong step must fail"
);
assert!(
chain.append(make_signal(n, 3, [0xffu8; 32])).is_err(),
"wrong prev must fail"
);
assert!(
chain.append(make_signal(n, 0, [0u8; 32])).is_err(),
"equivocation must fail"
);
}
#[test]
fn vdf_challenge_from_signal_hash_roundtrip() {
let n = neuron(1);
let s0 = make_signal(n, 0, [0u8; 32]);
let hash = s0.hash();
let challenge = challenge_from_hash(&hash);
assert_ne!(challenge, 0, "challenge must be non-zero");
let proof = vdf_evaluate(challenge, 500);
assert!(vdf_verify(&proof), "VDF proof must verify");
assert_ne!(proof.output, challenge, "VDF must advance the value");
let half = vdf_evaluate(challenge, 250);
let second = vdf_evaluate(half.output, 250);
assert_eq!(
second.output, proof.output,
"VDF must be sequentially composable"
);
}
#[test]
fn vdf_different_challenges_produce_different_outputs() {
let p1 = vdf_evaluate(
challenge_from_hash(&make_signal(neuron(1), 0, [0u8; 32]).hash()),
100,
);
let p2 = vdf_evaluate(
challenge_from_hash(&make_signal(neuron(2), 0, [0u8; 32]).hash()),
100,
);
assert_ne!(
p1.output, p2.output,
"different neurons β different VDF outputs"
);
}
#[test]
fn signal_to_bbg_state_to_look_proof() {
let n = neuron(1);
let mut chain = SignalChain::new();
let s0 = make_signal(n, 0, [0u8; 32]);
chain.append(s0).unwrap();
assert_eq!(chain.entries.len(), 1);
let mut state = BbgState::new();
state.neurons.insert(
n,
NeuronRecord {
focus: 100_000,
karma: 0,
stake: 0,
},
);
state
.insert(&BbgSignal {
neuron: n,
links: vec![BbgCyberlink {
from: particle(2),
to: particle(3),
token: particle(0),
amount: 1,
valence: 1,
}],
box_moves: vec![],
height: 0,
})
.unwrap();
state.time.insert(0, particle(42));
let prov = ProofLookProvider::new(&state);
let mut order = Order::<ORDER_SIZE>::new();
let obj = bbg_object_from_state(&mut order, &state);
let formula = make_look_formula(&mut order, 8, 0);
let mut trace = VecTrace::default();
let outcome = reduce(&mut order, obj, formula, 1000, &prov, &mut trace);
assert!(matches!(outcome, Outcome::Ok(_, _)), "look 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("signalβbbgβlook proof must verify");
}
#[test]
fn multiple_signals_same_neuron_bbg_state_consistent() {
let n = neuron(1);
let mut chain = SignalChain::new();
let s0 = make_signal(n, 0, [0u8; 32]);
let h0 = s0.hash();
let s1 = make_signal(n, 1, h0);
chain.append(s0).unwrap();
chain.append(s1).unwrap();
let mut state = BbgState::new();
state.neurons.insert(
n,
NeuronRecord {
focus: 200_000,
karma: 0,
stake: 0,
},
);
for step in 0u64..=1 {
state
.insert(&BbgSignal {
neuron: n,
links: vec![BbgCyberlink {
from: particle(2 + step as u8),
to: particle(10 + step as u8),
token: particle(0),
amount: 1,
valence: 1,
}],
box_moves: vec![],
height: step,
})
.unwrap();
}
assert!(
state
.particles
.contains_key(&bbg::state::axon_id(&particle(2), &particle(10)))
);
assert!(
state
.particles
.contains_key(&bbg::state::axon_id(&particle(3), &particle(11)))
);
}