Kaynağa Gözat

faucetd: Working airdrops.

parazyd 3 yıl önce
ebeveyn
işleme
0dd901bd5e

+ 1 - 0
Cargo.lock

@@ -1751,6 +1751,7 @@ dependencies = [
  "async-std",
  "clap 4.0.25",
  "darkfi",
+ "darkfi-money-contract",
  "darkfi-sdk",
  "darkfi-serial",
  "libsqlite3-sys",

+ 1 - 0
bin/drk/Cargo.toml

@@ -15,6 +15,7 @@ clap = {version = "4.0.25", features = ["derive"]}
 darkfi = {path = "../../", features = ["rpc", "util", "wallet"]}
 darkfi-sdk = {path = "../../src/sdk"}
 darkfi-serial = {path = "../../src/serial", features = ["derive", "crypto"]}
+darkfi-money-contract = {path = "../../src/contract/money", features = ["no-entrypoint", "client"]}
 prettytable-rs = "0.9.0"
 rand = "0.8.5"
 serde_json = "1.0.87"

+ 5 - 34
bin/drk/src/rpc_wallet.rs

@@ -20,6 +20,11 @@ use std::collections::HashMap;
 
 use anyhow::{anyhow, Result};
 use darkfi::{rpc::jsonrpc::JsonRequest, util::parse::encode_base10, wallet::walletdb::QueryType};
+use darkfi_money_contract::client::{
+    MONEY_COINS_COL_IS_SPENT, MONEY_COINS_COL_TOKEN_ID, MONEY_COINS_COL_VALUE, MONEY_COINS_TABLE,
+    MONEY_KEYS_COL_IS_DEFAULT, MONEY_KEYS_COL_PUBLIC, MONEY_KEYS_COL_SECRET, MONEY_KEYS_TABLE,
+    MONEY_TREE_COL_TREE, MONEY_TREE_TABLE,
+};
 use darkfi_sdk::{
     crypto::{constants::MERKLE_DEPTH, Keypair, MerkleNode, PublicKey, TokenId},
     incrementalmerkletree::bridgetree::BridgeTree,
@@ -31,40 +36,6 @@ use serde_json::json;
 
 use super::Drk;
 
-// TODO: FIXME:
-// Find a way to have these constants be deterministic for the actual
-// contract. e.g. they could be prefixed with the contract_id in order
-// not to have collisions happen. This is because right now it's easy
-// to overwrite any table in the wallet if the developer doesn't take
-// care of it. The wallet's SQL schema comes from the money contract
-// and here we just hardcode it. There should be a nice way to parse
-// the schema and fill some map.
-//const MONEY_INFO_TABLE: &str = "money_info";
-//const MONEY_INFO_COL_LAST_SCANNED_SLOT: &str = "last_scanned_slot";
-
-const MONEY_TREE_TABLE: &str = "money_tree";
-const MONEY_TREE_COL_TREE: &str = "tree";
-
-const MONEY_KEYS_TABLE: &str = "money_keys";
-//const MONEY_KEYS_COL_KEY_ID: &str = "key_id";
-const MONEY_KEYS_COL_IS_DEFAULT: &str = "is_default";
-const MONEY_KEYS_COL_PUBLIC: &str = "public";
-const MONEY_KEYS_COL_SECRET: &str = "secret";
-
-const MONEY_COINS_TABLE: &str = "money_coins";
-//const MONEY_COINS_COL_COIN: &str = "coin";
-const MONEY_COINS_COL_IS_SPENT: &str = "is_spent";
-//const MONEY_COINS_COL_SERIAL: &str = "serial";
-const MONEY_COINS_COL_VALUE: &str = "value";
-const MONEY_COINS_COL_TOKEN_ID: &str = "token_id";
-//const MONEY_COINS_COL_COIN_BLIND: &str = "coin_blind";
-//const MONEY_COINS_COL_VALUE_BLIND: &str = "value_blind";
-//const MONEY_COINS_COL_TOKEN_BLIND: &str = "token_blind";
-//const MONEY_COINS_COL_SECRET: &str = "secret";
-//const MONEY_COINS_COL_NULLIFIER: &str = "nullifier";
-//const MONEY_COINS_COL_LEAF_POSITION: &str = "leaf_position";
-//const MONEY_COINS_COL_MEMO: &str = "memo";
-
 impl Drk {
     /// Initialize wallet with tables for the Money contract.
     /// This should be performed initially before doing other operations.

+ 17 - 17
bin/faucetd/src/main.rs

@@ -32,13 +32,10 @@ use darkfi_money_contract::{
         build_transfer_tx, MONEY_KEYS_COL_IS_DEFAULT, MONEY_KEYS_COL_PUBLIC, MONEY_KEYS_COL_SECRET,
         MONEY_KEYS_TABLE, MONEY_TREE_COL_TREE, MONEY_TREE_TABLE,
     },
-    ZKAS_BURN_NS, ZKAS_MINT_NS,
+    MoneyFunction, ZKAS_BURN_NS, ZKAS_MINT_NS,
 };
 use darkfi_sdk::{
-    crypto::{
-        constants::MERKLE_DEPTH, schnorr::SchnorrSecret, ContractId, Keypair, MerkleNode,
-        PublicKey, TokenId,
-    },
+    crypto::{constants::MERKLE_DEPTH, ContractId, Keypair, MerkleNode, PublicKey, TokenId},
     db::ZKAS_DB_NAME,
     incrementalmerkletree::bridgetree::BridgeTree,
     pasta::{group::ff::PrimeField, pallas},
@@ -167,7 +164,7 @@ struct Args {
 pub struct Faucetd {
     synced: Mutex<bool>, // AtomicBool is weird in Arc
     sync_p2p: P2pPtr,
-    _validator_state: ValidatorStatePtr,
+    validator_state: ValidatorStatePtr,
     keypair: Keypair,
     _wallet: WalletPtr,
     merkle_tree: BridgeTree<MerkleNode, MERKLE_DEPTH>,
@@ -255,7 +252,7 @@ impl Faucetd {
         let faucetd = Self {
             synced: Mutex::new(false),
             sync_p2p,
-            _validator_state: validator_state,
+            validator_state,
             keypair,
             _wallet: wallet,
             merkle_tree,
@@ -451,18 +448,21 @@ impl Faucetd {
         };
 
         // Build transaction
-        let calls = vec![ContractCall { contract_id: cid, data: serialize(&params) }];
+        let mut data = vec![MoneyFunction::Transfer as u8];
+        params.encode(&mut data).unwrap();
+        let calls = vec![ContractCall { contract_id: cid, data }];
         let proofs = vec![proofs];
-        let mut signatures = vec![];
-        let mut encoded_tx = vec![];
-        calls.encode(&mut encoded_tx).unwrap();
-        proofs.encode(&mut encoded_tx).unwrap();
-        for secret in secret_keys {
-            let signature = secret.sign(&mut OsRng, &encoded_tx);
-            signatures.push(signature);
-        }
+        let mut tx = Transaction { calls, proofs, signatures: vec![] };
+        let sigs = tx.create_sigs(&mut OsRng, &secret_keys).unwrap();
+        tx.signatures = vec![sigs];
 
-        let tx = Transaction { calls, proofs, signatures: vec![signatures] };
+        // Safety check to see if the transaction is actually valid.
+        if let Err(e) =
+            self.validator_state.read().await.verify_transactions(&[tx.clone()], false).await
+        {
+            error!("airdrop(): Failed to verify transaction before broadcasting: {}", e);
+            return JsonError::new(InternalError, None, id).into()
+        }
 
         // Broadcast transaction to the network.
         if let Err(e) = self.sync_p2p.broadcast(tx.clone()).await {

+ 0 - 1
src/contract/money/src/lib.rs

@@ -129,7 +129,6 @@ fn init_contract(cid: ContractId, ix: &[u8]) -> ContractResult {
             // Add a Merkle tree to the info db:
             let coin_tree = MerkleTree::new(100);
             let mut coin_tree_data = vec![];
-            // TODO: FIXME: What is this write_u32 doing here?
             coin_tree_data.write_u32(0)?;
             coin_tree.encode(&mut coin_tree_data)?;