zone witness in cross zone transfer scenario

This commit is contained in:
David Rusu 2025-02-24 18:50:03 +04:00
parent c35ad00767
commit 643dbb8e55
3 changed files with 54 additions and 61 deletions

View File

@ -113,7 +113,7 @@ impl OutputWitness {
)
}
pub fn split_input(
pub fn spend_with_change(
input: InputWitness,
amount: u64,
to_pk: NullifierCommitment,

View File

@ -11,7 +11,7 @@ pub struct ProvedLedgerTransition {
}
impl ProvedLedgerTransition {
pub fn prove(mut ledger: LedgerState, zone_id: ZoneId, bundles: Vec<ProvedBundle>) -> Self {
pub fn prove(ledger: &mut LedgerState, zone_id: ZoneId, bundles: Vec<ProvedBundle>) -> Self {
let mut env = risc0_zkvm::ExecutorEnv::builder();
let mut w_bundles = Vec::new();
let mut nullifiers = Vec::new();

View File

@ -1,8 +1,8 @@
use cl::{
crust::{
balance::{UnitWitness, NOP_COVENANT},
BundleWitness, InputWitness, Nullifier, NullifierCommitment, NullifierSecret,
OutputWitness, TxWitness,
BundleWitness, InputWitness, NoteCommitment, Nullifier, NullifierCommitment,
NullifierSecret, OutputWitness, TxWitness,
},
ds::mmr::{MMRProof, MMR},
mantle::{
@ -16,7 +16,7 @@ use ledger::{
update::ProvedBatchUpdate,
};
use ledger_proof_statements::stf::StfPublic;
use rand::Rng;
use rand::{Rng, RngCore};
use rand_core::CryptoRngCore;
const ZONE_A: ZoneId = [0u8; 32];
@ -52,13 +52,14 @@ fn cross_transfer_transition(
to: User,
amount: u64,
to_zone: ZoneId,
mut ledger_in: LedgerState,
mut ledger_out: LedgerState,
ledger_in: &mut LedgerState,
ledger_out: &mut LedgerState,
) -> (ProvedLedgerTransition, ProvedLedgerTransition) {
assert!(amount <= input.value);
let mut rng = rand::thread_rng();
let (transfer, change) = OutputWitness::split_input(input, amount, to.pk(), to_zone, &mut rng);
let (transfer, change) =
OutputWitness::spend_with_change(input, amount, to.pk(), to_zone, &mut rng);
let tx_witness = TxWitness::default()
.add_input(input, input_proof)
@ -81,35 +82,51 @@ fn cross_transfer_transition(
println!("proving ledger A transition");
let ledger_in_transition =
ProvedLedgerTransition::prove(ledger_in.clone(), input.zone_id, vec![bundle.clone()]);
ProvedLedgerTransition::prove(ledger_in, input.zone_id, vec![bundle.clone()]);
println!("proving ledger B transition");
let ledger_out_transition =
ProvedLedgerTransition::prove(ledger_out.clone(), to_zone, vec![bundle]);
ledger_in.add_commitment(&change.note_commitment());
ledger_in.add_nullifiers(vec![input.nullifier()]);
ledger_out.add_commitment(&transfer.note_commitment());
assert_eq!(
ledger_in_transition.public().ledger,
ledger_in.to_witness().commit()
);
assert_eq!(
ledger_out_transition.public().ledger,
ledger_out.to_witness().commit()
);
let ledger_out_transition = ProvedLedgerTransition::prove(ledger_out, to_zone, vec![bundle]);
(ledger_in_transition, ledger_out_transition)
}
struct ZoneWitness {
ledger: LedgerState,
}
impl ZoneWitness {
fn new() -> Self {
let ledger = LedgerState::default();
Self { ledger }
}
fn state(&self) -> ZoneState {
ZoneState {
stf: StfProof::nop_stf(),
zone_data: [0; 32],
ledger: self.ledger.to_witness().commit(),
}
}
fn fill_nfs(&mut self, amount: usize, mut rng: impl RngCore) {
self.ledger.add_nullifiers(
std::iter::repeat_with(|| Nullifier(rng.gen()))
.take(amount)
.collect(),
);
}
fn add_commitment(&mut self, cm: &NoteCommitment) -> (MMR, MMRProof) {
self.ledger.add_commitment(cm)
}
}
#[test]
fn zone_update_cross() {
let mut rng = rand::thread_rng();
// alice is sending 8 NMO to bob.
// Alice is sending 8 NMO to bob.
let alice = User::random(&mut rng);
let bob = User::random(&mut rng);
@ -118,49 +135,25 @@ fn zone_update_cross() {
let alice_input = InputWitness::from_output(utxo, alice.sk(), nmo());
let mut ledger_a = LedgerState::default();
let mut zone_a = ZoneWitness::new();
zone_a.fill_nfs(2_usize.pow(10), &mut rng);
let alice_cm_proof = zone_a.add_commitment(&utxo.note_commitment());
// To make the scenario a bit more realistic, we fill the nullifier set with a bunch of nullififiers
ledger_a.add_nullifiers(
std::iter::repeat_with(|| Nullifier(rng.gen()))
.take(2_usize.pow(10))
.collect(),
);
let alice_cm_proof = ledger_a.add_commitment(&utxo.note_commitment());
let mut zone_b = ZoneWitness::new();
let ledger_b = LedgerState::default();
let (zone_a_old, zone_b_old) = (zone_a.state(), zone_b.state());
let zone_a_old = ZoneState {
stf: StfProof::nop_stf(),
zone_data: [0; 32],
ledger: ledger_a.to_witness().commit(),
};
let zone_b_old = ZoneState {
stf: StfProof::nop_stf(),
zone_data: [0; 32],
ledger: ledger_b.to_witness().commit(),
};
let (ledger_a_transition, ledger_b_transition) = cross_transfer_transition(
let (ledger_proof_a, ledger_proof_b) = cross_transfer_transition(
alice_input,
alice_cm_proof,
bob,
8,
ZONE_B,
ledger_a,
ledger_b,
&mut zone_a.ledger,
&mut zone_b.ledger,
);
let zone_a_new = ZoneState {
ledger: ledger_a_transition.public().ledger,
..zone_a_old
};
let zone_b_new = ZoneState {
ledger: ledger_b_transition.public().ledger,
..zone_b_old
};
let (zone_a_new, zone_b_new) = (zone_a.state(), zone_b.state());
let stf_proof_a = StfProof::prove_nop(StfPublic {
old: zone_a_old,
@ -187,7 +180,7 @@ fn zone_update_cross() {
let proved_batch = ProvedBatchUpdate {
batch,
ledger_proofs: vec![ledger_a_transition, ledger_b_transition],
ledger_proofs: vec![ledger_proof_a, ledger_proof_b],
stf_proofs: vec![stf_proof_a, stf_proof_b],
};