use northroot_proof_engine::{
compute_identity_root, compute_trace_set_root, ArtifactRef, MethodRef, SpanCommitment,
SpanStatus,
};
#[test]
fn test_identity_root_isolation() {
let trace_id = "tr_01H1234567890";
let identity1 = "did:key:zTenant1";
let identity2 = "did:key:zTenant2";
let spans = vec![
"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".to_string(),
"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb".to_string(),
];
let set_root1 = compute_trace_set_root(&spans).unwrap();
let set_root2 = compute_trace_set_root(&spans).unwrap();
assert_eq!(
set_root1, set_root2,
"trace_set_root must be independent of identity"
);
let id_root1 = compute_identity_root(trace_id, identity1, &spans).unwrap();
let id_root2 = compute_identity_root(trace_id, identity2, &spans).unwrap();
assert_ne!(
id_root1, id_root2,
"Different identities must produce different identity_root"
);
let id_root3 = compute_identity_root(trace_id, identity1, &spans).unwrap();
assert_eq!(
id_root1, id_root3,
"Same identity must produce same identity_root"
);
}
#[test]
fn test_trace_set_root_independent_of_identity() {
let spans = vec![
"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".to_string(),
"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb".to_string(),
];
let root1 = compute_trace_set_root(&spans).unwrap();
let root2 = compute_trace_set_root(&spans).unwrap();
assert_eq!(root1, root2);
let id_root1 = compute_identity_root("tr1", "did:key:z1", &spans).unwrap();
let id_root2 = compute_identity_root("tr1", "did:key:z2", &spans).unwrap();
assert_ne!(id_root1, id_root2, "Identity root should change");
let root3 = compute_trace_set_root(&spans).unwrap();
assert_eq!(root1, root3, "trace_set_root must remain unchanged");
}
#[test]
fn test_span_commitment_independent_of_optional_fields() {
let base_commitment = SpanCommitment {
schema_version: "proof.v2".to_string(),
trace_id: "tr_01H1234567890".to_string(),
span_id: "sp-0001".to_string(),
method_ref: MethodRef {
method_id: "com.test/method".to_string(),
version: "1.0.0".to_string(),
method_shape_root:
"sha256:0000000000000000000000000000000000000000000000000000000000000000"
.to_string(),
image_digest: "sha256:0000000000000000000000000000000000000000000000000000000000000000"
.to_string(),
method_fingerprint: "git:deadbeef".to_string(),
},
data_shape_hash: "sha256:1111111111111111111111111111111111111111111111111111111111111111"
.to_string(),
span_shape_hash: "sha256:2222222222222222222222222222222222222222222222222222222222222222"
.to_string(),
inputs: vec![ArtifactRef {
name: "input.csv".to_string(),
content_hash: "sha256:3333333333333333333333333333333333333333333333333333333333333333"
.to_string(),
uri: None,
}],
outputs: vec![ArtifactRef {
name: "output.json".to_string(),
content_hash: "sha256:4444444444444444444444444444444444444444444444444444444444444444"
.to_string(),
uri: None,
}],
start_time: "2025-11-06T12:00:00.000Z".to_string(),
end_time: "2025-11-06T12:00:00.042Z".to_string(),
status: SpanStatus::OK,
meta: None,
};
let hash1 = northroot_proof_engine::compute_span_commitment_hash(&base_commitment).unwrap();
let mut with_meta = base_commitment.clone();
with_meta.meta = Some(northroot_proof_engine::SpanMeta {
lamport: Some(1),
parents: None,
order_index: None,
});
let hash2 = northroot_proof_engine::compute_span_commitment_hash(&with_meta).unwrap();
assert_ne!(
hash1, hash2,
"Adding meta should change hash (it's part of commitment)"
);
let hash3 = northroot_proof_engine::compute_span_commitment_hash(&base_commitment).unwrap();
assert_eq!(hash1, hash3, "Same commitment must produce same hash");
}