mirror of
https://github.com/logos-blockchain/lez-fuzzing.git
synced 2026-07-02 07:49:45 +00:00
fix: derive account_id from private_key
This commit is contained in:
parent
e4c4d1eca7
commit
e8cd1a767e
@ -1,8 +1,8 @@
|
||||
use arbitrary::{Arbitrary, Unstructured};
|
||||
use common::{block::HashableBlockData, transaction::LeeTransaction};
|
||||
use nssa::{AccountId, PrivateKey};
|
||||
use nssa::{AccountId, PrivateKey, PublicKey};
|
||||
|
||||
use crate::arbitrary_types::{ArbAccountId, ArbLeeTransaction, ArbPrivateKey};
|
||||
use crate::arbitrary_types::{ArbLeeTransaction, ArbPrivateKey};
|
||||
use proptest::prelude::*;
|
||||
use testnet_initial_state::initial_pub_accounts_private_keys;
|
||||
|
||||
@ -31,16 +31,29 @@ pub fn signer_account_ids(tx: &common::transaction::LeeTransaction) -> Vec<nssa:
|
||||
}
|
||||
}
|
||||
|
||||
/// The public-account [`AccountId`] that a transaction signed with `key` will have as its
|
||||
/// signer — i.e. exactly what the validator derives from the witness set.
|
||||
///
|
||||
/// Centralises the `AccountId::from(&PublicKey::new_from_private_key(key))` derivation that
|
||||
/// funded-account generation and the privacy synthesiser both depend on, so the funded
|
||||
/// account and its signer never drift apart again.
|
||||
#[must_use]
|
||||
pub fn account_id_for_key(key: &PrivateKey) -> AccountId {
|
||||
AccountId::from(&PublicKey::new_from_private_key(key))
|
||||
}
|
||||
|
||||
// ── Fuzz-driven state generation ─────────────────────────────────────────────
|
||||
|
||||
/// An account with an arbitrary identifier, balance, and private key,
|
||||
/// generated entirely from unstructured fuzzer bytes.
|
||||
/// An account with a fuzz-driven balance and private key, plus the [`AccountId`]
|
||||
/// **derived from that key**.
|
||||
///
|
||||
/// Using random account IDs (rather than the fixed `testnet_initial_state` set)
|
||||
/// exposes state-dependent bugs that only manifest with specific account shapes —
|
||||
/// for example: zero balance, [`u128::MAX`] balance, or a nonce at the
|
||||
/// wrap-around boundary. The [`PrivateKey`] field lets downstream generators
|
||||
/// produce correctly-signed transfers referencing accounts present in this state.
|
||||
/// Deriving `account_id` from `private_key` (rather than drawing it independently)
|
||||
/// is what makes the funded account and its signer the *same* account: a transfer
|
||||
/// signed by `private_key` is then authorized to spend `account_id`, so downstream
|
||||
/// generators like [`arb_fuzz_native_transfer`] can actually reach the **successful**
|
||||
/// state-transition path instead of always being rejected as unauthorized. The key
|
||||
/// is still fuzz-driven, so account shapes (zero balance, [`u128::MAX`] balance,
|
||||
/// nonce wrap-around) remain controlled by the fuzzer.
|
||||
pub struct FuzzAccount {
|
||||
pub account_id: AccountId,
|
||||
pub balance: u128,
|
||||
@ -62,12 +75,16 @@ pub struct FuzzAccount {
|
||||
pub fn arbitrary_fuzz_state(u: &mut Unstructured<'_>) -> arbitrary::Result<Vec<FuzzAccount>> {
|
||||
let n = ((u8::arbitrary(u)? as usize) % 8) + 1; // 1..=8
|
||||
std::iter::repeat_with(|| {
|
||||
let private_key = ArbPrivateKey::arbitrary(u)?.0;
|
||||
// Derive the account id from the key so the funded account *is* the signer;
|
||||
// otherwise every "biased-valid" transfer is unauthorized and rejected.
|
||||
let account_id = account_id_for_key(&private_key);
|
||||
Ok(FuzzAccount {
|
||||
account_id: ArbAccountId::arbitrary(u)?.0,
|
||||
account_id,
|
||||
// Divide by 8 so the sum of 8 accounts is at most u128::MAX, preventing
|
||||
// false-positive checked_add panics that would mask real inflation bugs.
|
||||
balance: u128::arbitrary(u)? / 8,
|
||||
private_key: ArbPrivateKey::arbitrary(u)?.0,
|
||||
private_key,
|
||||
})
|
||||
})
|
||||
.take(n)
|
||||
|
||||
@ -40,8 +40,7 @@
|
||||
use arbitrary::{Arbitrary, Result as ArbResult, Unstructured};
|
||||
use borsh::to_vec as borsh_to_vec;
|
||||
use nssa::{
|
||||
AccountId, PRIVACY_PRESERVING_CIRCUIT_ID, PrivacyPreservingTransaction, PrivateKey, PublicKey,
|
||||
V03State,
|
||||
AccountId, PRIVACY_PRESERVING_CIRCUIT_ID, PrivacyPreservingTransaction, PrivateKey, V03State,
|
||||
privacy_preserving_transaction::{
|
||||
Message as PPMessage, WitnessSet as PPWitnessSet, circuit::Proof,
|
||||
},
|
||||
@ -54,7 +53,7 @@ use nssa_core::{
|
||||
};
|
||||
use risc0_zkvm::{FakeReceipt, InnerReceipt, ReceiptClaim};
|
||||
|
||||
use crate::generators::FuzzAccount;
|
||||
use crate::generators::{FuzzAccount, account_id_for_key};
|
||||
|
||||
/// Synthesise a [`Proof`] that **passes** `Proof::is_valid_for` for `message` against
|
||||
/// `state`, under `RISC0_DEV_MODE`.
|
||||
@ -193,8 +192,9 @@ pub fn arb_privacy_preserving_tx(
|
||||
) -> ArbResult<PrivacyPreservingTransaction> {
|
||||
// ── Signers ──────────────────────────────────────────────────────────────────────
|
||||
// 0..=3 distinct signers drawn from the keyed fuzz accounts. A signer's public-account
|
||||
// id is `AccountId::from(&its_public_key)` — exactly what the validator derives from the
|
||||
// witness set — and is independent of `FuzzAccount.account_id`.
|
||||
// id is `account_id_for_key(key)` — exactly what the validator derives from the witness
|
||||
// set. Since `arbitrary_fuzz_state` now derives `FuzzAccount.account_id` the same way,
|
||||
// this id also equals that account's `account_id`, so the funded account is the signer.
|
||||
let max_signers = accounts.len().min(3);
|
||||
let n_signers = if max_signers == 0 {
|
||||
0
|
||||
@ -205,7 +205,7 @@ pub fn arb_privacy_preserving_tx(
|
||||
let mut signer_ids: Vec<AccountId> = Vec::with_capacity(n_signers);
|
||||
for _ in 0..n_signers {
|
||||
let key = &accounts[(u8::arbitrary(u)? as usize) % accounts.len()].private_key;
|
||||
let id = AccountId::from(&PublicKey::new_from_private_key(key));
|
||||
let id = account_id_for_key(key);
|
||||
if signer_ids.contains(&id) {
|
||||
continue; // keep signer ids distinct so `nonces` stays 1:1 with `keys`
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user