soft3/bbg/rs/tests/state_certificate.rs

use bbg::certificate::{MAX_FIELDS, StateCertificate};
use bbg::{
    BbgState, Dim,
    types::{ParticleRecord, SignalRecord},
};

fn state() -> BbgState {
    let mut state = BbgState::new();
    state.set_root_version(bbg::RootVersion::V1); // certificates carry the v1 leaves
    let mut record = ParticleRecord::zero();
    record.energy = 77;
    state.particles.insert([1; 32], record);
    state.apply_signal_record(SignalRecord {
        neuron: [2; 32],
        network: [3; 32],
        link_count: 5,
        block_height: u64::MAX,
        proof_hash: [4; 32],
        step: 7,
    });
    state.refresh_root();
    state
}

#[test]
fn certificates_authenticate_actual_cells_and_the_same_root_as_query_proofs() {
    let state = state();
    let cert = StateCertificate::from_state(&state, &[9, 0]).unwrap();
    let root = cert.root().unwrap();
    assert_eq!(root.map(|v| v.to_le_bytes()).concat(), state.root());
    cert.verify(root).unwrap();
    assert_eq!(cert.cell(0, 11), Some(77));
    assert_eq!(cert.cell(1, 11), None);
    for table in &cert.dimensions {
        let dim = Dim::from_u64(table.namespace).unwrap();
        for index in [0, 11, table.fields.len() - 1] {
            let proof = bbg::proof::open_cell(&state, dim, index).unwrap();
            let expected = cert.leaves[table.namespace as usize]
                .map(|v| v.to_le_bytes())
                .concat();
            assert_eq!(proof.commitment.as_bytes(), expected);
            assert_eq!(
                u64::from_le_bytes(proof.value_bytes.try_into().unwrap()),
                table.fields[index]
            );
            assert_eq!(
                bbg::proof::cell_value(&state, dim, index).unwrap().as_u64(),
                table.fields[index]
            );
        }
        assert!(bbg::proof::open_cell(&state, dim, table.fields.len()).is_none());
        assert!(
            cert.cell(table.namespace, table.fields.len() as u64)
                .is_none()
        );
    }
}

#[test]
fn every_committed_component_and_structural_metadata_is_checked() {
    let state = state();
    let cert = StateCertificate::from_state(&state, &[0, 9]).unwrap();
    let root = cert.root().unwrap();
    for mutation in 0..10 {
        let mut bad = cert.clone();
        match mutation {
            0 => bad.dimensions[0].fields[11] += 1,
            1 => bad.leaves[0][0] = (bad.leaves[0][0] + 1) % nebu::field::P,
            2 => bad.leaves[13][0] = (bad.leaves[13][0] + 1) % nebu::field::P,
            3 => bad.dimensions.push(bad.dimensions[0].clone()),
            4 => bad.dimensions[0].namespace = 10,
            5 => bad.dimensions[0].fields[1] += 1,
            6 => bad.dimensions[0].fields[0] = 1,
            7 => bad.dimensions[0].fields[11] = nebu::field::P,
            8 => bad.lens_version = 1,
            _ => bad.dimensions[0].fields.resize(MAX_FIELDS + 1, 0),
        }
        assert!(bad.verify(root).is_err(), "mutation={mutation}");
    }
    assert!(cert.verify([nebu::field::P; 4]).is_err());
    assert!(StateCertificate::from_state(&state, &[0, 0]).is_err());
    assert!(StateCertificate::from_state(&state, &[10]).is_ok());
    assert!(StateCertificate::from_state(&state, &[11]).is_err());
}

#[test]
fn a_changed_signal_network_moves_the_certified_root() {
    let mut state = state();
    let old = StateCertificate::from_state(&state, &[9])
        .unwrap()
        .root()
        .unwrap();
    // Every mutation goes through the committed map, so the root is never
    // stale: a certificate taken right after the change binds the new root.
    state.signals.get_mut(&bbg::signal_key(&[2; 32], 7)).unwrap().network[0] += 1;
    let cert = StateCertificate::from_state(&state, &[9]).unwrap();
    assert_ne!(cert.root().unwrap(), old);
    assert!(cert.verify(old).is_err());
}

#[test]
fn arbitrary_key_bytes_and_u64_values_have_no_modulus_alias() {
    let mut a = BbgState::new();
    let mut b = BbgState::new();
    a.set_root_version(bbg::RootVersion::V1);
    b.set_root_version(bbg::RootVersion::V1);
    let first = [0; 32];
    let mut second = first;
    second[..8].copy_from_slice(&nebu::field::P.to_le_bytes());
    a.particles.insert(first, ParticleRecord::zero());
    b.particles.insert(second, ParticleRecord::zero());
    assert_ne!(a.compute_root(), b.compute_root());
    b.particles.clear();
    let mut record = ParticleRecord::zero();
    record.energy = nebu::field::P;
    b.particles.insert(first, record);
    assert_ne!(a.compute_root(), b.compute_root());
    let cert = StateCertificate::from_state(&b, &[0]).unwrap();
    assert_eq!(cert.cell(0, 11), Some(nebu::field::P & 0xffff_ffff));
    assert_eq!(cert.cell(0, 12), Some(nebu::field::P >> 32));
}

#[cfg(feature = "serde")]
#[test]
fn certificate_serde_requires_version_metadata_and_roundtrips() {
    let cert = StateCertificate::from_state(&state(), &[0, 9]).unwrap();
    let json = serde_json::to_string(&cert).unwrap();
    let decoded: StateCertificate = serde_json::from_str(&json).unwrap();
    assert_eq!(decoded, cert);
    decoded.verify(cert.root().unwrap()).unwrap();
    let mut missing = serde_json::to_value(&cert).unwrap();
    missing.as_object_mut().unwrap().remove("lens_version");
    assert!(serde_json::from_value::<StateCertificate>(missing).is_err());
}

Graph