mirror of
https://github.com/logos-blockchain/lez-fuzzing.git
synced 2026-08-06 17:33:15 +00:00
fix: missed mutants harness
This commit is contained in:
parent
dec23d373c
commit
865bf96b5c
@ -199,6 +199,22 @@ fn arb_private_action(
|
||||
})
|
||||
}
|
||||
|
||||
/// Append `action` to `actions` unless its nullifier **or** its commitment already appears
|
||||
/// there — either duplicate *alone* trips validator check 2 (nullifiers and commitments must
|
||||
/// each be unique across a message's private actions), so a partial collision must be
|
||||
/// dropped just like a full one.
|
||||
pub(crate) fn push_private_action_if_unique(
|
||||
actions: &mut Vec<PrivateAction>,
|
||||
action: PrivateAction,
|
||||
) {
|
||||
if !actions
|
||||
.iter()
|
||||
.any(|a| a.nullifier == action.nullifier || a.commitment == action.commitment)
|
||||
{
|
||||
actions.push(action);
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate a privacy-preserving transaction aimed at the **state-transition executor**.
|
||||
///
|
||||
/// The transaction is built to *frequently* pass every validation check up to and including
|
||||
@ -288,12 +304,7 @@ pub fn arb_privacy_preserving_tx(
|
||||
let mut private_actions: Vec<PrivateAction> = Vec::new();
|
||||
for _ in 0..n_priv {
|
||||
let action = arb_private_action(u, live_root)?;
|
||||
if !private_actions
|
||||
.iter()
|
||||
.any(|a| a.nullifier == action.nullifier || a.commitment == action.commitment)
|
||||
{
|
||||
private_actions.push(action);
|
||||
}
|
||||
push_private_action_if_unique(&mut private_actions, action);
|
||||
}
|
||||
|
||||
// Validator check 1: the private-action list must be non-empty.
|
||||
|
||||
@ -3,7 +3,7 @@ use arbitrary::Unstructured;
|
||||
use crate::generators::{FuzzAccount, account_id_for_key};
|
||||
use crate::privacy::{
|
||||
arb_account, arb_conflicting_nullifier_pair, arb_privacy_preserving_tx, arb_validity_window,
|
||||
synthesize_passing_proof,
|
||||
push_private_action_if_unique, synthesize_passing_proof,
|
||||
};
|
||||
use nssa::privacy_preserving_transaction::{Message as PPMessage, WitnessSet as PPWitnessSet};
|
||||
use nssa::{AccountId, PrivacyPreservingTransaction, PrivateKey, V03State};
|
||||
@ -470,6 +470,51 @@ fn arb_privacy_preserving_tx_generator_invariants() {
|
||||
);
|
||||
}
|
||||
|
||||
/// The private-action dedup guard must reject a *partial* collision — a candidate sharing
|
||||
/// only the nullifier, or only the commitment, with an already-kept action — because
|
||||
/// validator check 2 requires nullifiers and commitments to *each* be unique across the
|
||||
/// message. Random fuzz draws never produce partial collisions (both fields derive from
|
||||
/// independent 32-byte draws), so this pins the guard's `||` directly: mutated to `&&`,
|
||||
/// both partial-collision cases below would be accepted and the assertions fail.
|
||||
#[test]
|
||||
fn push_private_action_if_unique_rejects_partial_collisions() {
|
||||
let state = crate::genesis::genesis_state(&[], vec![]);
|
||||
let kept = valid_private_action(&state, 1);
|
||||
let fresh = valid_private_action(&state, 2);
|
||||
|
||||
let mut actions = Vec::new();
|
||||
push_private_action_if_unique(&mut actions, kept.clone());
|
||||
assert_eq!(actions.len(), 1, "first action must always be accepted");
|
||||
|
||||
// Same nullifier, different commitment → rejected (duplicate-nullifier check 2).
|
||||
let mut nullifier_clash = fresh.clone();
|
||||
nullifier_clash.nullifier = kept.nullifier;
|
||||
push_private_action_if_unique(&mut actions, nullifier_clash);
|
||||
assert_eq!(
|
||||
actions.len(),
|
||||
1,
|
||||
"an action sharing only the nullifier must be rejected"
|
||||
);
|
||||
|
||||
// Different nullifier, same commitment → rejected (duplicate-commitment check 2).
|
||||
let mut commitment_clash = fresh.clone();
|
||||
commitment_clash.commitment = kept.commitment;
|
||||
push_private_action_if_unique(&mut actions, commitment_clash);
|
||||
assert_eq!(
|
||||
actions.len(),
|
||||
1,
|
||||
"an action sharing only the commitment must be rejected"
|
||||
);
|
||||
|
||||
// Fully distinct → accepted.
|
||||
push_private_action_if_unique(&mut actions, fresh.clone());
|
||||
assert_eq!(actions.len(), 2, "a fully distinct action must be kept");
|
||||
|
||||
// Exact duplicate → rejected.
|
||||
push_private_action_if_unique(&mut actions, fresh);
|
||||
assert_eq!(actions.len(), 2, "an exact duplicate must be rejected");
|
||||
}
|
||||
|
||||
// ── arb_conflicting_nullifier_pair ──────────────────────────────────────────────────────
|
||||
// The pair builder underpins `fuzz_transaction_ordering_independence`: it must always yield
|
||||
// two transactions that use *distinct* signers (so a rejection of the second application is
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user