add zone tx inclusion proof (#20)

* add zone tx inclusion proof

* rename input to tx
This commit is contained in:
Giacomo Pasini 2024-08-09 11:52:42 +02:00 committed by GitHub
parent 5d3f3ab9fb
commit 85a3e941b9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 47 additions and 20 deletions

View File

@ -1,4 +1,4 @@
use cl::{balance::Unit, nullifier::NullifierCommitment};
use cl::{balance::Unit, merkle, nullifier::NullifierCommitment};
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
@ -38,7 +38,7 @@ impl ZoneMetadata {
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct StateWitness {
pub balances: BTreeMap<AccountId, u64>,
pub included_txs: Vec<Input>,
pub included_txs: Vec<Tx>,
pub zone_metadata: ZoneMetadata,
pub nonce: [u8; 32],
}
@ -62,7 +62,7 @@ impl StateWitness {
}
pub fn withdraw(mut self, w: Withdraw) -> Self {
self.included_txs.push(Input::Withdraw(w));
self.included_txs.push(Tx::Withdraw(w));
let Withdraw {
from,
@ -79,7 +79,7 @@ impl StateWitness {
}
pub fn deposit(mut self, d: Deposit) -> Self {
self.included_txs.push(Input::Deposit(d));
self.included_txs.push(Tx::Deposit(d));
let Deposit { to, amount } = d;
@ -91,10 +91,13 @@ impl StateWitness {
}
pub fn included_txs_root(&self) -> [u8; 32] {
// this is a placeholder
let tx_bytes = [vec![0u8; 32]];
let tx_merkle_leaves = cl::merkle::padded_leaves(&tx_bytes);
cl::merkle::root::<MAX_TXS>(tx_merkle_leaves)
merkle::root::<MAX_TXS>(self.included_tx_merkle_leaves())
}
pub fn included_tx_witness(&self, idx: usize) -> IncludedTxWitness {
let tx = self.included_txs.get(idx).unwrap().clone();
let path = merkle::path(self.included_tx_merkle_leaves(), idx);
IncludedTxWitness { tx, path }
}
pub fn balances_root(&self) -> [u8; 32] {
@ -105,7 +108,7 @@ impl StateWitness {
bytes
}));
let balance_merkle_leaves = cl::merkle::padded_leaves(&balance_bytes);
cl::merkle::root::<MAX_BALANCES>(balance_merkle_leaves)
merkle::root::<MAX_BALANCES>(balance_merkle_leaves)
}
pub fn total_balance(&self) -> u64 {
@ -124,6 +127,15 @@ impl StateWitness {
..self
}
}
fn included_tx_merkle_leaves(&self) -> [[u8; 32]; MAX_TXS] {
let tx_bytes = self
.included_txs
.iter()
.map(|t| t.to_bytes())
.collect::<Vec<_>>();
merkle::padded_leaves(&tx_bytes)
}
}
impl From<StateCommitment> for [u8; 32] {
@ -166,7 +178,22 @@ impl Deposit {
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum Input {
pub enum Tx {
Withdraw(Withdraw),
Deposit(Deposit),
}
impl Tx {
pub fn to_bytes(&self) -> Vec<u8> {
match self {
Tx::Withdraw(withdraw) => withdraw.to_bytes().to_vec(),
Tx::Deposit(deposit) => deposit.to_bytes().to_vec(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct IncludedTxWitness {
pub tx: Tx,
pub path: Vec<merkle::PathNode>,
}

View File

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

View File

@ -17,7 +17,7 @@ enum Action {
},
}
fn stf_prove_stark(state: StateWitness, inputs: Vec<Input>) {
fn stf_prove_stark(state: StateWitness, inputs: Vec<Tx>) {
let env = ExecutorEnv::builder()
.write(&inputs)
.unwrap()

View File

@ -1,7 +1,7 @@
use std::collections::{BTreeMap, VecDeque};
use cl::{NoteWitness, NullifierNonce, NullifierSecret};
use common::{Input, StateWitness, ZoneMetadata, ZONE_CL_FUNDS_UNIT};
use common::{StateWitness, Tx, ZoneMetadata, ZONE_CL_FUNDS_UNIT};
use ledger::death_constraint::DeathProof;
use rand_core::CryptoRngCore;
@ -108,7 +108,7 @@ fn test_withdrawal() {
zone_state_in.nullifier(),
executor::prove_zone_stf(
init_state.clone(),
vec![Input::Withdraw(withdraw)],
vec![Tx::Withdraw(withdraw)],
withdraw_ptx.input_witness(0), // input state note (input #0)
withdraw_ptx.output_witness(0), // output state note (output #0)
withdraw_ptx.output_witness(1), // output funds note (output #1)
@ -142,7 +142,7 @@ fn test_withdrawal() {
zone_state_out.note.state,
StateWitness {
balances: BTreeMap::from_iter([(alice, 22)]),
included_txs: vec![Input::Withdraw(withdraw)],
included_txs: vec![Tx::Withdraw(withdraw)],
zone_metadata: init_state.zone_metadata,
nonce: init_state.evolve_nonce().nonce,
}

View File

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

View File

@ -129,8 +129,8 @@ fn main() {
for input in inputs {
state = match input {
Input::Withdraw(w) => withdraw(state, output_root, w, withdrawals.pop_front().unwrap()),
Input::Deposit(d) => deposit(state, input_root, d, deposits.pop_front().unwrap()),
Tx::Withdraw(w) => withdraw(state, output_root, w, withdrawals.pop_front().unwrap()),
Tx::Deposit(d) => deposit(state, input_root, d, deposits.pop_front().unwrap()),
}
}