Browse Source

src/contract/money/tx_verification: completed tx_alice_to_alice_verification test

aggstam 3 years ago
parent
commit
2da7f5cdd9
1 changed files with 101 additions and 15 deletions
  1. 101 15
      src/contract/money/tests/tx_verification.rs

+ 101 - 15
src/contract/money/tests/tx_verification.rs

@@ -32,20 +32,27 @@ use darkfi::{
     Result,
     Result,
 };
 };
 use darkfi_sdk::{
 use darkfi_sdk::{
-    crypto::{constants::MERKLE_DEPTH, ContractId, Keypair, MerkleNode, PublicKey, TokenId},
+    crypto::{
+        constants::MERKLE_DEPTH, poseidon_hash, ContractId, Keypair, MerkleNode, Nullifier,
+        PublicKey, TokenId,
+    },
     db::ZKAS_DB_NAME,
     db::ZKAS_DB_NAME,
-    incrementalmerkletree::bridgetree::BridgeTree,
+    incrementalmerkletree::{bridgetree::BridgeTree, Tree},
     pasta::{
     pasta::{
         group::ff::{Field, PrimeField},
         group::ff::{Field, PrimeField},
         pallas,
         pallas,
     },
     },
     tx::ContractCall,
     tx::ContractCall,
 };
 };
-use darkfi_serial::{serialize, Encodable};
+use darkfi_serial::{deserialize, serialize, Encodable};
 use log::info;
 use log::info;
 use rand::rngs::OsRng;
 use rand::rngs::OsRng;
 
 
-use darkfi_money_contract::{client::build_transfer_tx, MoneyFunction, ZKAS_BURN_NS, ZKAS_MINT_NS};
+use darkfi_money_contract::{
+    client::{build_transfer_tx, Coin, EncryptedNote, OwnCoin},
+    state::MoneyTransferParams,
+    MoneyFunction, ZKAS_BURN_NS, ZKAS_MINT_NS,
+};
 
 
 /// Initialize log configuration
 /// Initialize log configuration
 fn init_logger() -> Result<()> {
 fn init_logger() -> Result<()> {
@@ -141,7 +148,7 @@ fn generate_airdrop_tx(
     mint_pk: &ProvingKey,
     mint_pk: &ProvingKey,
     burn_zkbin: &ZkBinary,
     burn_zkbin: &ZkBinary,
     burn_pk: &ProvingKey,
     burn_pk: &ProvingKey,
-) -> Result<Transaction> {
+) -> Result<(Transaction, MoneyTransferParams)> {
     let (params, proofs, secret_keys, _spent_coins) = build_transfer_tx(
     let (params, proofs, secret_keys, _spent_coins) = build_transfer_tx(
         sender_kp,
         sender_kp,
         receiver_pk,
         receiver_pk,
@@ -165,7 +172,7 @@ fn generate_airdrop_tx(
     let sigs = tx.create_sigs(&mut OsRng, &secret_keys)?;
     let sigs = tx.create_sigs(&mut OsRng, &secret_keys)?;
     tx.signatures = vec![sigs];
     tx.signatures = vec![sigs];
 
 
-    Ok(tx)
+    Ok((tx, params))
 }
 }
 
 
 /// Generate N faucet transactions
 /// Generate N faucet transactions
@@ -186,7 +193,7 @@ fn generate_faucet_airdrop_txs(
         let alice_kp = Keypair::random(&mut OsRng);
         let alice_kp = Keypair::random(&mut OsRng);
         let token_id = TokenId::from(pallas::Base::random(&mut OsRng));
         let token_id = TokenId::from(pallas::Base::random(&mut OsRng));
         let amount = decode_base10("42.69", 8, true)?;
         let amount = decode_base10("42.69", 8, true)?;
-        let tx = generate_airdrop_tx(
+        let (tx, _) = generate_airdrop_tx(
             faucet_kp,
             faucet_kp,
             faucet_merkle_tree,
             faucet_merkle_tree,
             &alice_kp.public,
             &alice_kp.public,
@@ -212,7 +219,7 @@ async fn tx_faucet_verification() -> Result<()> {
     // Test configuration
     // Test configuration
     let n = 10;
     let n = 10;
 
 
-    // We initialize the faucet that will generate the airdrop transactions.
+    // Initialize the faucet that will generate the airdrop transactions.
     // Faucet will also act as our transactions validator.
     // Faucet will also act as our transactions validator.
     let (
     let (
         faucet_state,
         faucet_state,
@@ -260,13 +267,14 @@ async fn tx_alice_to_alice_verification() -> Result<()> {
     init_logger()?;
     init_logger()?;
 
 
     // Test configuration
     // Test configuration
-    let _n = 10;
+    let n = 10;
 
 
-    // We initialize the faucet that will generate the airdrop transaction.
+    // Initialize the faucet that will generate the airdrop transaction.
+    // Faucet will also act as our transactions validator.
     let (
     let (
         faucet_state,
         faucet_state,
         faucet_kp,
         faucet_kp,
-        faucet_merkle_tree,
+        mut faucet_merkle_tree,
         contract_id,
         contract_id,
         mint_zkbin,
         mint_zkbin,
         mint_pk,
         mint_pk,
@@ -274,12 +282,27 @@ async fn tx_alice_to_alice_verification() -> Result<()> {
         burn_pk,
         burn_pk,
     ) = init_faucet().await?;
     ) = init_faucet().await?;
 
 
+    // Initialize Alice state
+    info!("Initializing Alice state");
+    let alice_kp = Keypair::random(&mut OsRng);
+    let alice_wallet = WalletDb::new("sqlite::memory:", "foo").await?;
+    let mut alice_merkle_tree = BridgeTree::<MerkleNode, MERKLE_DEPTH>::new(100);
+    let alice_sled_db = sled::Config::new().temporary(true).open()?;
+    let alice_state = ValidatorState::new(
+        &alice_sled_db,
+        *TESTNET_GENESIS_TIMESTAMP,
+        *TESTNET_GENESIS_HASH_BYTES,
+        alice_wallet,
+        vec![faucet_kp.public],
+        false,
+    )
+    .await?;
+
     // Generating airdrop transaction
     // Generating airdrop transaction
     info!("Generating faucet airdrop transaction");
     info!("Generating faucet airdrop transaction");
-    let alice_kp = Keypair::random(&mut OsRng);
     let token_id = TokenId::from(pallas::Base::random(&mut OsRng));
     let token_id = TokenId::from(pallas::Base::random(&mut OsRng));
     let amount = decode_base10("42.69", 8, true)?;
     let amount = decode_base10("42.69", 8, true)?;
-    let tx = generate_airdrop_tx(
+    let (tx, params) = generate_airdrop_tx(
         &faucet_kp,
         &faucet_kp,
         &faucet_merkle_tree,
         &faucet_merkle_tree,
         &alice_kp.public,
         &alice_kp.public,
@@ -294,11 +317,74 @@ async fn tx_alice_to_alice_verification() -> Result<()> {
 
 
     // Verifying airdrop transactions
     // Verifying airdrop transactions
     info!("Verifying faucet airdrop transaction...");
     info!("Verifying faucet airdrop transaction...");
+    // Executing airdrop transaction on the faucet's blockchain db
+    faucet_state.read().await.verify_transactions(&[tx.clone()], true).await?;
+    faucet_merkle_tree.append(&MerkleNode::from(params.outputs[0].coin));
+
+    // Executing airdrop transaction on Alice's blockchain db
+    alice_state.read().await.verify_transactions(&[tx.clone()], true).await?;
+    alice_merkle_tree.append(&MerkleNode::from(params.outputs[0].coin));
+
+    // Generating N Alice to Alice transactions
+    let mut txs = vec![];
+    let mut tx = tx;
     let init = Timestamp::current_time();
     let init = Timestamp::current_time();
-    faucet_state.read().await.verify_transactions(&[tx], true).await?;
+    for i in 0..n {
+        info!("Building transfer tx for Alice from Alice number {}", i);
+        let leaf_position = alice_merkle_tree.witness().unwrap();
+        let params: MoneyTransferParams = deserialize(&tx.calls[0].data[1..])?;
+        let output = &params.outputs[0];
+        let encrypted_note = EncryptedNote {
+            ciphertext: output.ciphertext.clone(),
+            ephem_public: output.ephem_public,
+        };
+        let note = encrypted_note.decrypt(&alice_kp.secret)?;
+        let owncoin = OwnCoin {
+            coin: Coin::from(output.coin),
+            note: note.clone(),
+            secret: alice_kp.secret,
+            nullifier: Nullifier::from(poseidon_hash([alice_kp.secret.inner(), note.serial])),
+            leaf_position,
+        };
+
+        let (params, proofs, secret_keys, _spent_coins) = build_transfer_tx(
+            &alice_kp,
+            &alice_kp.public,
+            amount,
+            token_id,
+            &[owncoin],
+            &alice_merkle_tree,
+            &mint_zkbin,
+            &mint_pk,
+            &burn_zkbin,
+            &burn_pk,
+            false,
+        )?;
+
+        // Build transaction
+        let mut data = vec![MoneyFunction::Transfer as u8];
+        params.encode(&mut data)?;
+        let calls = vec![ContractCall { contract_id, data }];
+        let proofs = vec![proofs];
+        tx = Transaction { calls, proofs, signatures: vec![] };
+        let sigs = tx.create_sigs(&mut OsRng, &secret_keys)?;
+        tx.signatures = vec![sigs];
+
+        alice_merkle_tree.append(&MerkleNode::from(params.outputs[0].coin));
+
+        txs.push(tx.clone());
+    }
+    let generation_elapsed_time = init.elapsed();
+    assert_eq!(txs.len(), n as usize);
+
+    // Verifying transaction
+    info!("Verifying Alice to Alice transactions...");
+    let init = Timestamp::current_time();
+    faucet_state.read().await.verify_transactions(&txs, true).await?;
     let verification_elapsed_time = init.elapsed();
     let verification_elapsed_time = init.elapsed();
 
 
-    info!("Processing time of faucet airdrop transaction(in sec):");
+    info!("Processing time of {} Alice to Alice transactions(in sec):", n);
+    info!("\tGeneration -> {}", generation_elapsed_time);
     info!("\tVerification -> {}", verification_elapsed_time);
     info!("\tVerification -> {}", verification_elapsed_time);
 
 
     Ok(())
     Ok(())