refactor to remove cycle

This commit is contained in:
Giacomo Pasini 2024-08-09 17:23:29 +02:00
parent cf598f1397
commit 6dfceffc2d
No known key found for this signature in database
GPG Key ID: FC08489D2D895D4B
5 changed files with 67 additions and 46 deletions

View File

@ -62,15 +62,11 @@ impl StateWitness {
} }
pub fn withdraw(mut self, w: Withdraw) -> Self { pub fn withdraw(mut self, w: Withdraw) -> Self {
let Withdraw { let Withdraw { from, amount } = w;
from,
amount,
bind: _,
} = &w;
let from_balance = self.balances.entry(*from).or_insert(0); let from_balance = self.balances.entry(from).or_insert(0);
*from_balance = from_balance *from_balance = from_balance
.checked_sub(*amount) .checked_sub(amount)
.expect("insufficient funds in account"); .expect("insufficient funds in account");
self.included_txs.push(Tx::Withdraw(w)); self.included_txs.push(Tx::Withdraw(w));
@ -79,15 +75,11 @@ impl StateWitness {
} }
pub fn deposit(mut self, d: Deposit) -> Self { pub fn deposit(mut self, d: Deposit) -> Self {
let Deposit { let Deposit { to, amount } = d;
to,
amount,
bind: _,
} = &d;
let to_balance = self.balances.entry(*to).or_insert(0); let to_balance = self.balances.entry(to).or_insert(0);
*to_balance += to_balance *to_balance += to_balance
.checked_add(*amount) .checked_add(amount)
.expect("overflow in account balance"); .expect("overflow in account balance");
self.included_txs.push(Tx::Deposit(d)); self.included_txs.push(Tx::Deposit(d));
@ -148,37 +140,49 @@ impl From<StateCommitment> for [u8; 32] {
} }
} }
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct Withdraw { pub struct Withdraw {
pub from: AccountId, pub from: AccountId,
pub amount: u64, pub amount: u64,
pub bind: PartialTxInputWitness,
} }
impl Withdraw { impl Withdraw {
pub fn to_bytes(&self) -> [u8; 108] { pub fn to_bytes(&self) -> [u8; 12] {
let mut bytes = [0; 108]; let mut bytes = [0; 12];
bytes[0..4].copy_from_slice(&self.from.to_le_bytes()); bytes[0..4].copy_from_slice(&self.from.to_le_bytes());
bytes[4..12].copy_from_slice(&self.amount.to_le_bytes()); bytes[4..12].copy_from_slice(&self.amount.to_le_bytes());
bytes[12..108].copy_from_slice(&self.bind.input.commit().to_bytes());
bytes bytes
} }
} }
/// A deposit of funds into the zone /// A deposit of funds into the zone
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct Deposit { pub struct Deposit {
pub to: AccountId, pub to: AccountId,
pub amount: u64, pub amount: u64,
pub bind: PartialTxInputWitness,
} }
impl Deposit { impl Deposit {
pub fn to_bytes(&self) -> [u8; 108] { pub fn to_bytes(&self) -> [u8; 12] {
let mut bytes = [0; 108]; let mut bytes = [0; 12];
bytes[0..4].copy_from_slice(&self.to.to_le_bytes()); bytes[0..4].copy_from_slice(&self.to.to_le_bytes());
bytes[4..12].copy_from_slice(&self.amount.to_le_bytes()); bytes[4..12].copy_from_slice(&self.amount.to_le_bytes());
bytes[12..108].copy_from_slice(&self.bind.input.commit().to_bytes()); bytes
}
}
/// A Tx that is executed in the zone if and only if the bind is
/// present is the same partial transaction
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct BoundTx {
pub tx: Tx,
pub bind: PartialTxInputWitness,
}
impl BoundTx {
pub fn to_bytes(&self) -> Vec<u8> {
let mut bytes = self.tx.to_bytes();
bytes.extend(self.bind.input.commit().to_bytes());
bytes bytes
} }
} }

View File

@ -1,9 +1,9 @@
use common::{StateWitness, Tx}; use common::{BoundTx, StateWitness};
use goas_proof_statements::{zone_funds::SpendFundsPrivate, zone_state::ZoneStatePrivate}; use goas_proof_statements::{zone_funds::SpendFundsPrivate, zone_state::ZoneStatePrivate};
pub fn prove_zone_stf( pub fn prove_zone_stf(
state: StateWitness, state: StateWitness,
inputs: Vec<Tx>, inputs: Vec<BoundTx>,
zone_in: cl::PartialTxInputWitness, zone_in: cl::PartialTxInputWitness,
zone_out: cl::PartialTxOutputWitness, zone_out: cl::PartialTxOutputWitness,
funds_out: cl::PartialTxOutputWitness, funds_out: cl::PartialTxOutputWitness,

View File

@ -1,7 +1,7 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use cl::{NoteWitness, NullifierNonce, NullifierSecret}; use cl::{NoteWitness, NullifierNonce, NullifierSecret};
use common::{StateWitness, Tx, ZoneMetadata, ZONE_CL_FUNDS_UNIT}; use common::{BoundTx, StateWitness, Tx, ZoneMetadata, ZONE_CL_FUNDS_UNIT};
use ledger::death_constraint::DeathProof; use ledger::death_constraint::DeathProof;
use rand_core::CryptoRngCore; use rand_core::CryptoRngCore;
@ -75,15 +75,9 @@ fn test_withdrawal() {
&mut rng, &mut rng,
); );
let mut withdraw_ptx = cl::PartialTxWitness {
inputs: vec![zone_state_in, zone_fund_in, alice_intent],
outputs: vec![],
};
let withdraw = common::Withdraw { let withdraw = common::Withdraw {
from: alice, from: alice,
amount: 78, amount: 78,
bind: withdraw_ptx.input_witness(2),
}; };
let end_state = init_state.clone().withdraw(withdraw.clone()).evolve_nonce(); let end_state = init_state.clone().withdraw(withdraw.clone()).evolve_nonce();
@ -113,14 +107,20 @@ fn test_withdrawal() {
&mut rng, &mut rng,
); );
withdraw_ptx.outputs = vec![zone_state_out, zone_fund_out, alice_withdrawal]; let withdraw_ptx = cl::PartialTxWitness {
inputs: vec![zone_state_in, zone_fund_in, alice_intent],
outputs: vec![zone_state_out, zone_fund_out, alice_withdrawal],
};
let death_proofs = BTreeMap::from_iter([ let death_proofs = BTreeMap::from_iter([
( (
zone_state_in.nullifier(), zone_state_in.nullifier(),
executor::prove_zone_stf( executor::prove_zone_stf(
init_state.clone(), init_state.clone(),
vec![Tx::Withdraw(withdraw.clone())], vec![BoundTx {
tx: Tx::Withdraw(withdraw.clone()),
bind: withdraw_ptx.input_witness(2),
}],
withdraw_ptx.input_witness(0), // input state note (input #0) withdraw_ptx.input_witness(0), // input state note (input #0)
withdraw_ptx.output_witness(0), // output state note (output #0) withdraw_ptx.output_witness(0), // output state note (output #0)
withdraw_ptx.output_witness(1), // output funds note (output #1) withdraw_ptx.output_witness(1), // output funds note (output #1)
@ -140,8 +140,6 @@ fn test_withdrawal() {
), ),
]); ]);
println!("done");
let note_commitments = vec![ let note_commitments = vec![
zone_state_in.note_commitment(), zone_state_in.note_commitment(),
zone_fund_in.note_commitment(), zone_fund_in.note_commitment(),

View File

@ -1,10 +1,10 @@
use common::{StateWitness, Tx}; use common::{BoundTx, StateWitness};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ZoneStatePrivate { pub struct ZoneStatePrivate {
pub state: StateWitness, pub state: StateWitness,
pub inputs: Vec<Tx>, pub inputs: Vec<BoundTx>,
pub zone_in: cl::PartialTxInputWitness, pub zone_in: cl::PartialTxInputWitness,
pub zone_out: cl::PartialTxOutputWitness, pub zone_out: cl::PartialTxOutputWitness,
/// While the absence of birth constraints does not guarantee uniqueness of a note that can be used as /// While the absence of birth constraints does not guarantee uniqueness of a note that can be used as

View File

@ -1,17 +1,30 @@
use cl::{note::NoteWitness, nullifier::NullifierNonce, output::OutputWitness, PtxRoot}; use cl::{
note::NoteWitness, nullifier::NullifierNonce, output::OutputWitness, PartialTxInputWitness,
PtxRoot,
};
use common::*; use common::*;
use goas_proof_statements::zone_state::ZoneStatePrivate; use goas_proof_statements::zone_state::ZoneStatePrivate;
use ledger_proof_statements::death_constraint::DeathConstraintPublic; use ledger_proof_statements::death_constraint::DeathConstraintPublic;
use risc0_zkvm::guest::env; use risc0_zkvm::guest::env;
fn withdraw(state: StateWitness, input_root: [u8; 32], withdrawal: Withdraw) -> StateWitness { fn withdraw(
assert_eq!(input_root, withdrawal.bind.input_root()); state: StateWitness,
input_root: [u8; 32],
withdrawal: Withdraw,
bind: PartialTxInputWitness,
) -> StateWitness {
assert_eq!(bind.input_root(), input_root);
state.withdraw(withdrawal) state.withdraw(withdrawal)
} }
fn deposit(state: StateWitness, input_root: [u8; 32], deposit: Deposit) -> StateWitness { fn deposit(
assert_eq!(deposit.bind.input_root(), input_root); state: StateWitness,
input_root: [u8; 32],
deposit: Deposit,
bind: PartialTxInputWitness,
) -> StateWitness {
assert_eq!(bind.input_root(), input_root);
state.deposit(deposit) state.deposit(deposit)
} }
@ -87,8 +100,14 @@ fn main() {
for input in inputs { for input in inputs {
state = match input { state = match input {
Tx::Withdraw(w) => withdraw(state, input_root, w), BoundTx {
Tx::Deposit(d) => deposit(state, input_root, d), tx: Tx::Withdraw(w),
bind,
} => withdraw(state, input_root, w, bind),
BoundTx {
tx: Tx::Deposit(d),
bind,
} => deposit(state, input_root, d, bind),
} }
} }