mirror of
https://github.com/logos-co/nomos-pocs.git
synced 2025-01-12 18:34:10 +00:00
add deposit-merge vk
This commit is contained in:
parent
a320c20d25
commit
d7cf1a3eaf
@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize};
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum Event {
|
||||
Spend(Spend),
|
||||
Merge(Merge),
|
||||
}
|
||||
|
||||
impl Event {
|
||||
@ -10,6 +11,7 @@ impl Event {
|
||||
// TODO: add variant tag to byte encoding
|
||||
match self {
|
||||
Event::Spend(spend) => spend.to_bytes().to_vec(),
|
||||
Event::Merge(merge) => merge.to_bytes().to_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -34,3 +36,18 @@ impl Spend {
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
||||
/// An event that authorizes spending zone funds to merge with other notes
|
||||
/// Balancing of the transaction is done in the zone state death constraint
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Merge {
|
||||
pub nf: cl::Nullifier,
|
||||
}
|
||||
|
||||
impl Merge {
|
||||
pub fn to_bytes(&self) -> [u8; 32] {
|
||||
let mut bytes = [0; 32];
|
||||
bytes.copy_from_slice(self.nf.as_bytes());
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
@ -19,3 +19,19 @@ pub struct SpendFundsPrivate {
|
||||
/// Merkle root of balances in the zone
|
||||
pub balances_root: [u8; 32],
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct MergePrivate {
|
||||
// The note we're spending
|
||||
pub funds_note: cl::PartialTxInputWitness,
|
||||
// The zone note that is authorizing the spend
|
||||
pub zone_note: cl::PartialTxOutputWitness,
|
||||
// The event emitted by the zone that authorizes spending this note
|
||||
pub merge_event: common::events::Merge,
|
||||
// Path to the zone output events root
|
||||
pub merge_event_state_path: Vec<cl::merkle::PathNode>,
|
||||
// Merkle root of txs included in the zone
|
||||
pub txs_root: [u8; 32],
|
||||
// Merkle root of balances in the zone
|
||||
pub balances_root: [u8; 32],
|
||||
}
|
||||
|
@ -7,5 +7,5 @@ edition = "2021"
|
||||
risc0-build = { version = "1.0" }
|
||||
|
||||
[package.metadata.risc0]
|
||||
methods = ["spend_zone_funds", "zone_state"]
|
||||
methods = ["spend_zone_funds", "zone_state", "zone_merge"]
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
[package]
|
||||
name = "zone-merge"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[workspace]
|
||||
|
||||
[dependencies]
|
||||
risc0-zkvm = { version = "1.0", default-features = false, features = ['std'] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
cl = { path = "../../../cl/cl" }
|
||||
goas_proof_statements = { path = "../../proof_statements" }
|
||||
ledger_proof_statements = { path = "../../../cl/ledger_proof_statements" }
|
||||
sha2 = "0.10"
|
||||
|
||||
|
||||
[patch.crates-io]
|
||||
# add RISC Zero accelerator support for all downstream usages of the following crates.
|
||||
sha2 = { git = "https://github.com/risc0/RustCrypto-hashes", tag = "sha2-v0.10.8-risczero.0" }
|
||||
crypto-bigint = { git = "https://github.com/risc0/RustCrypto-crypto-bigint", tag = "v0.5.5-risczero.0" }
|
||||
curve25519-dalek = { git = "https://github.com/risc0/curve25519-dalek", tag = "curve25519-4.1.2-risczero.0" }
|
@ -0,0 +1,44 @@
|
||||
use cl::{merkle, nullifier::Nullifier, PtxRoot};
|
||||
use goas_proof_statements::zone_funds::MergePrivate;
|
||||
use ledger_proof_statements::death_constraint::DeathConstraintPublic;
|
||||
use risc0_zkvm::guest::env;
|
||||
|
||||
fn main() {
|
||||
let MergePrivate {
|
||||
funds_note,
|
||||
zone_note,
|
||||
merge_event,
|
||||
merge_event_state_path,
|
||||
txs_root,
|
||||
balances_root,
|
||||
} = env::read();
|
||||
|
||||
let input_root = funds_note.input_root();
|
||||
let output_root = zone_note.output_root();
|
||||
let nf = Nullifier::new(funds_note.input.nf_sk, funds_note.input.nonce);
|
||||
// check the zone funds note is the one in the spend event
|
||||
assert_eq!(nf, merge_event.nf);
|
||||
|
||||
// ** Assert merge spent event was an output of the correct zone stf **
|
||||
// The zone state field is a merkle tree over:
|
||||
// root
|
||||
// / \
|
||||
// io state
|
||||
// / \ / \
|
||||
// events txs zoneid balances
|
||||
// We need to check that:
|
||||
// 1) There is a valid path from the spend event to the events root
|
||||
// 2) The zone id matches the one in the current funds note state
|
||||
// 3) The witnesses for merge path, txs and balances allow to calculate the correct root
|
||||
let zone_id = funds_note.input.note.state; // TODO: is there more state?
|
||||
let merge_event_leaf = merkle::leaf(&merge_event.to_bytes());
|
||||
let event_root = merkle::path_root(merge_event_leaf, &merge_event_state_path);
|
||||
|
||||
assert_eq!(
|
||||
merkle::root([event_root, txs_root, zone_id, balances_root]),
|
||||
zone_note.output.note.state
|
||||
);
|
||||
let ptx_root = PtxRoot(merkle::node(input_root, output_root));
|
||||
|
||||
env::commit(&DeathConstraintPublic { ptx_root, nf });
|
||||
}
|
@ -94,6 +94,13 @@ fn deposit(
|
||||
.checked_add(amount)
|
||||
.expect("overflow when depositing");
|
||||
|
||||
// authorize the merge of the zone funds
|
||||
state
|
||||
.output_events
|
||||
.push(events::Event::Merge(events::Merge {
|
||||
nf: Nullifier::new(zone_funds_in.nf_sk, zone_funds_in.nonce),
|
||||
}));
|
||||
|
||||
state
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user