Przeglądaj źródła

example/tx: Update for latest codebase.

parazyd 4 lat temu
rodzic
commit
e3d076d8d3
1 zmienionych plików z 64 dodań i 40 usunięć
  1. 64 40
      example/tx.rs

+ 64 - 40
example/tx.rs

@@ -1,43 +1,54 @@
+// Example transaction flow
 use incrementalmerkletree::{bridgetree::BridgeTree, Frontier, Tree};
 use rand::rngs::OsRng;
 
 use darkfi::{
     crypto::{
-        coin::Coin,
         keypair::{Keypair, PublicKey, SecretKey},
         merkle_node::MerkleNode,
         note::{EncryptedNote, Note},
         nullifier::Nullifier,
         proof::{ProvingKey, VerifyingKey},
         token_id::generate_id2,
+        OwnCoin, OwnCoins,
     },
     node::state::{state_transition, ProgramState, StateUpdate},
-    tx,
+    tx::builder::{
+        TransactionBuilder, TransactionBuilderClearInputInfo, TransactionBuilderInputInfo,
+        TransactionBuilderOutputInfo,
+    },
     util::NetworkName,
-    zk::circuit::{mint_contract::MintContract, spend_contract::SpendContract},
+    zk::circuit::{BurnContract, MintContract},
     Result,
 };
 
+/// The state machine, held in memory.
 struct MemoryState {
-    // The entire merkle tree state
+    /// The entire Merkle tree state
     tree: BridgeTree<MerkleNode, 32>,
-    // List of all previous and the current merkle roots
-    // This is the hashed value of all the children.
+    /// List of all previous and the current Merkle roots.
+    /// This is the hashed value of all the children.
     merkle_roots: Vec<MerkleNode>,
-    // Nullifiers prevent double spending
+    /// Nullifiers prevent double spending
     nullifiers: Vec<Nullifier>,
-    // All received coins
-    // NOTE: we need maybe a flag to keep track of which ones are spent
-    // Maybe the spend field links to a tx hash:input index
-    // We should also keep track of the tx hash:output index where this
-    // coin was received
-    own_coins: Vec<(Coin, Note)>,
+    /// All received coins
+    // NOTE: We need maybe a flag to keep track of which ones are
+    // spent. Maybe the spend field links to a tx hash:input index.
+    // We should also keep track of the tx hash:output index where
+    // this coin was received.
+    own_coins: OwnCoins,
+    /// Verifying key for the mint zk circuit.
     mint_vk: VerifyingKey,
-    spend_vk: VerifyingKey,
+    /// Verifying key for the burn zk circuit.
+    burn_vk: VerifyingKey,
 
-    // Public key of the cashier
+    /// Public key of the cashier
     cashier_signature_public: PublicKey,
-    // List of all our secret keys
+
+    /// Public key of the faucet
+    faucet_signature_public: PublicKey,
+
+    /// List of all our secret keys
     secrets: Vec<SecretKey>,
 }
 
@@ -46,6 +57,10 @@ impl ProgramState for MemoryState {
         public == &self.cashier_signature_public
     }
 
+    fn is_valid_faucet_public_key(&self, public: &PublicKey) -> bool {
+        public == &self.faucet_signature_public
+    }
+
     fn is_valid_merkle(&self, merkle_root: &MerkleNode) -> bool {
         self.merkle_roots.iter().any(|m| m == merkle_root)
     }
@@ -58,8 +73,8 @@ impl ProgramState for MemoryState {
         &self.mint_vk
     }
 
-    fn spend_vk(&self) -> &VerifyingKey {
-        &self.spend_vk
+    fn burn_vk(&self) -> &VerifyingKey {
+        &self.burn_vk
     }
 }
 
@@ -70,16 +85,19 @@ impl MemoryState {
 
         // Update merkle tree and witnesses
         for (coin, enc_note) in update.coins.into_iter().zip(update.enc_notes.into_iter()) {
-            // Add the new coins to the merkle tree
+            // Add the new coins to the Merkle tree
             let node = MerkleNode(coin.0);
             self.tree.append(&node);
 
-            // Keep track of all merkle roots that have existed
+            // Keep track of all Merkle roots that have existed
             self.merkle_roots.push(self.tree.root());
 
-            if let Some((note, _secret)) = self.try_decrypt_note(enc_note) {
-                self.own_coins.push((coin, note));
-                self.tree.witness();
+            // If it's our own coin, witness it and append to the vector.
+            if let Some((note, secret)) = self.try_decrypt_note(enc_note) {
+                let leaf_position = self.tree.witness().unwrap();
+                let nullifier = Nullifier::new(secret, note.serial);
+                let own_coin = OwnCoin { coin, note, secret, nullifier, leaf_position };
+                self.own_coins.push(own_coin);
             }
         }
     }
@@ -87,12 +105,13 @@ impl MemoryState {
     fn try_decrypt_note(&self, ciphertext: EncryptedNote) -> Option<(Note, SecretKey)> {
         // Loop through all our secret keys...
         for secret in &self.secrets {
-            // ... attempt to decrypt the note ...
+            // .. attempt to decrypt the note ...
             if let Ok(note) = ciphertext.decrypt(secret) {
                 // ... and return the decrypted note for this coin.
                 return Some((note, *secret))
             }
         }
+
         // We weren't able to decrypt the note with any of our keys.
         None
     }
@@ -102,11 +121,14 @@ fn main() -> Result<()> {
     let cashier_signature_secret = SecretKey::random(&mut OsRng);
     let cashier_signature_public = PublicKey::from_secret(cashier_signature_secret);
 
+    let faucet_signature_secret = SecretKey::random(&mut OsRng);
+    let faucet_signature_public = PublicKey::from_secret(faucet_signature_secret);
+
     let keypair = Keypair::random(&mut OsRng);
 
     const K: u32 = 11;
     let mint_vk = VerifyingKey::build(K, &MintContract::default());
-    let spend_vk = VerifyingKey::build(K, &SpendContract::default());
+    let burn_vk = VerifyingKey::build(K, &BurnContract::default());
 
     let mut state = MemoryState {
         tree: BridgeTree::<MerkleNode, 32>::new(100),
@@ -114,22 +136,23 @@ fn main() -> Result<()> {
         nullifiers: vec![],
         own_coins: vec![],
         mint_vk,
-        spend_vk,
+        burn_vk,
         cashier_signature_public,
+        faucet_signature_public,
         secrets: vec![keypair.secret],
     };
 
     let token_id =
         generate_id2("So11111111111111111111111111111111111111112", &NetworkName::Solana)?;
 
-    let builder = tx::TransactionBuilder {
-        clear_inputs: vec![tx::TransactionBuilderClearInputInfo {
+    let builder = TransactionBuilder {
+        clear_inputs: vec![TransactionBuilderClearInputInfo {
             value: 110,
             token_id,
             signature_secret: cashier_signature_secret,
         }],
         inputs: vec![],
-        outputs: vec![tx::TransactionBuilderOutputInfo {
+        outputs: vec![TransactionBuilderOutputInfo {
             value: 110,
             token_id,
             public: keypair.public,
@@ -137,10 +160,10 @@ fn main() -> Result<()> {
     };
 
     let mint_pk = ProvingKey::build(K, &MintContract::default());
-    let spend_pk = ProvingKey::build(K, &SpendContract::default());
-    let tx = builder.build(&mint_pk, &spend_pk)?;
+    let burn_pk = ProvingKey::build(K, &BurnContract::default());
+    let tx = builder.build(&mint_pk, &burn_pk)?;
 
-    tx.verify(&state.mint_vk, &state.spend_vk).expect("tx verify");
+    tx.verify(&state.mint_vk, &state.burn_vk)?;
 
     let _note = tx.outputs[0].enc_note.decrypt(&keypair.secret)?;
 
@@ -148,26 +171,27 @@ fn main() -> Result<()> {
     state.apply(update);
 
     // Now spend
-    let (coin, note) = &state.own_coins[0];
-    let node = MerkleNode(coin.0);
-    let (leaf_position, merkle_path) = state.tree.authentication_path(&node).unwrap();
+    let owncoin = &state.own_coins[0];
+    let note = owncoin.note;
+    let leaf_position = owncoin.leaf_position;
+    let merkle_path = state.tree.authentication_path(leaf_position).unwrap();
 
-    let builder = tx::TransactionBuilder {
+    let builder = TransactionBuilder {
         clear_inputs: vec![],
-        inputs: vec![tx::TransactionBuilderInputInfo {
+        inputs: vec![TransactionBuilderInputInfo {
             leaf_position,
             merkle_path,
             secret: keypair.secret,
-            note: *note,
+            note,
         }],
-        outputs: vec![tx::TransactionBuilderOutputInfo {
+        outputs: vec![TransactionBuilderOutputInfo {
             value: 110,
             token_id,
             public: keypair.public,
         }],
     };
 
-    let tx = builder.build(&mint_pk, &spend_pk)?;
+    let tx = builder.build(&mint_pk, &burn_pk)?;
 
     let update = state_transition(&state, tx)?;
     state.apply(update);