Procházet zdrojové kódy

script/research/crypsinous_playground: retrieve owncoins from wallet

aggstam před 3 roky
rodič
revize
3c4770fe10

+ 16 - 3
script/research/crypsinous_playground/Cargo.toml

@@ -4,18 +4,31 @@ version = "0.1.0"
 edition = "2021"
 
 [dependencies]
-blake3 = "1.3.1"
-darkfi = {path = "../../../", features = ["crypto"]}
+darkfi = {path = "../../../", features = ["crypto", "node"]}
 darkfi-sdk = {path = "../../../src/sdk"}
 dashu = { version = "0.2.0", git = "https://github.com/ertosns/dashu" }
 halo2_gadgets = "0.2.0"
 halo2_proofs = "0.2.0"
 incrementalmerkletree = "0.3.0"
 pasta_curves = "0.4.0"
-rand = "0.8.5"
+
+# Async
+async-std = "1.12.0"
+async-trait = "0.1.57"
+ctrlc = { version = "3.2.3", features = ["termination"] }
+easy-parallel = "3.2.0"
+smol = "1.2.5"
+
+# Argument parsing
+serde = "1.0.145"
+serde_derive = "1.0.145"
+structopt = "0.3.26"
+structopt-toml = "0.5.1"
 
 # Misc
+blake3 = "1.3.1"
 log = "0.4.17"
 simplelog = "0.12.0"
+rand = "0.8.5"
 
 [workspace]

+ 13 - 0
script/research/crypsinous_playground/crypsinous_playground_config.toml

@@ -0,0 +1,13 @@
+## crypsinous_playground configuration file
+##
+## Please make sure you go through all the settings so you can configure
+## your daemon properly.
+##
+## The default values are left commented. They can be overridden either by
+## uncommenting, or by using the command-line.
+
+# Path to the wallet database
+#wallet_path = "~/.config/darkfi/crypsinous_playground/wallet.db"
+
+# Password for the wallet database
+#wallet_pass = "changeme"

+ 38 - 8
script/research/crypsinous_playground/src/coins.rs

@@ -7,16 +7,22 @@ use pasta_curves::{
     group::{ff::PrimeField, Curve},
     pallas,
 };
-use rand::{thread_rng, Rng};
+use rand::{thread_rng, Rng, rngs::OsRng};
 
-use darkfi::crypto::{
-    coin::OwnCoin,
-    keypair::{Keypair, SecretKey},
-    leadcoin::LeadCoin,
-    types::DrkValueBlind,
-    util::{mod_r_p, pedersen_commitment_base, pedersen_commitment_u64},
+use darkfi::{
+    crypto::{
+        coin::{Coin, OwnCoin},
+        keypair::{Keypair, SecretKey},
+        leadcoin::LeadCoin,
+        note::Note,
+        
+        types::{DrkCoinBlind, DrkSerial, DrkTokenId, DrkValueBlind},
+        util::{mod_r_p, pedersen_commitment_base, pedersen_commitment_u64, poseidon_hash},
+    },
+    wallet::walletdb::WalletDb,
+    Result,
 };
-use darkfi_sdk::crypto::{constants::MERKLE_DEPTH_ORCHARD, MerkleNode};
+use darkfi_sdk::crypto::{constants::MERKLE_DEPTH_ORCHARD, MerkleNode, Nullifier};
 
 use crate::utils::{Float10, fbig2base};
 
@@ -331,3 +337,27 @@ pub fn is_leader(slot: u64, epoch_coins: &Vec<Vec<LeadCoin>>) -> (bool, usize) {
     
     (won, highest_stake_idx)
 }
+
+/// Generate staking coins for provided wallet.
+pub async fn generate_staking_coins(wallet: &WalletDb) -> Result<Vec<OwnCoin>> {
+    let keypair = wallet.get_default_keypair().await?;
+    let token_id = DrkTokenId::random(&mut OsRng);
+    let value = 420;
+    let serial = DrkSerial::random(&mut OsRng);
+    let note = Note {
+        serial,
+        value,
+        token_id,
+        coin_blind: DrkCoinBlind::random(&mut OsRng),
+        value_blind: DrkValueBlind::random(&mut OsRng),
+        token_blind: DrkValueBlind::random(&mut OsRng),
+        memo: vec![],
+    };
+    let coin = Coin(pallas::Base::random(&mut OsRng));
+    let nullifier = Nullifier::from(poseidon_hash::<2>([keypair.secret.inner(), serial]));
+    let leaf_position: incrementalmerkletree::Position = 0.into();
+    let coin = OwnCoin { coin, note, secret: keypair.secret, nullifier, leaf_position };
+    wallet.put_own_coin(coin.clone()).await?;
+    
+    Ok(vec![coin])
+}

+ 57 - 17
script/research/crypsinous_playground/src/main.rs

@@ -1,30 +1,70 @@
+use async_std::sync::Arc;
 use log::{error, info};
-use simplelog::{ColorChoice, Config, LevelFilter, TermLogger, TerminalMode};
+use pasta_curves::pallas;
+use structopt_toml::{serde::Deserialize, structopt::StructOpt, StructOptToml};
 
 use darkfi::{
+    async_daemonize, cli_desc,
     crypto::{
         lead_proof,
         proof::{ProvingKey, VerifyingKey},
     },
+    node::Client,
+    wallet::walletdb::init_wallet,
     zk::circuit::LeadContract,
+    Result,
 };
 
 mod coins;
 mod utils;
 
-/// The porpuse of this script is to simulate a staker actions through an epoch.
-/// Main focus is the crypsinous lottery mechanism and the leader proof creation and validation.
-/// Other flows that happen through a slot, like broadcasting blocks or syncing are out of scope.
-fn main() {
-    // Initiate logger
-    TermLogger::init(
-        LevelFilter::Debug,
-        Config::default(),
-        TerminalMode::Mixed,
-        ColorChoice::Auto,
-    )
-    .unwrap();
+const CONFIG_FILE: &str = "crypsinous_playground_config.toml";
+const CONFIG_FILE_CONTENTS: &str = include_str!("../crypsinous_playground_config.toml");
+
+#[derive(Clone, Debug, Deserialize, StructOpt, StructOptToml)]
+#[serde(default)]
+#[structopt(name = "crypsinous_playground", about = cli_desc!())]
+struct Args {
+    #[structopt(short, long)]
+    /// Configuration file to use
+    config: Option<String>,
+
+    #[structopt(long, default_value = "~/.config/darkfi/crypsinous_playground/wallet.db")]
+    /// Path to wallet database
+    wallet_path: String,
+
+    #[structopt(long, default_value = "changeme")]
+    /// Password for the wallet database
+    wallet_pass: String,
+
+    #[structopt(short, parse(from_occurrences))]
+    /// Increase verbosity (-vvv supported)
+    verbose: u8,
+}
+
+// The porpuse of this script is to simulate a staker actions through an epoch.
+// Main focus is the crypsinous lottery mechanism and the leader proof creation and validation.
+// Other flows that happen through a slot, like broadcasting blocks or syncing are out of scope.
+async_daemonize!(realmain);
+async fn realmain(args: Args, _ex: Arc<smol::Executor<'_>>) -> Result<()>  {
+    
+    // Initialize wallet that holds coins for staking
+    let wallet = init_wallet(&args.wallet_path, &args.wallet_pass).await?;
+    
+    // Initialize client
+    let client = Arc::new(Client::new(wallet.clone()).await?);
     
+    // Retrieving nodes wallet coins
+    let mut owned = client.get_own_coins().await?;    
+    // If node holds no coins in its wallet, we generate some new staking coins
+    if owned.is_empty() {
+        info!("Node wallet is empty, generating new staking coins...");
+        owned = coins::generate_staking_coins(&wallet).await?;
+    }
+    // If we want to test what will happen if node holds 0 coins, uncomment the below line
+    // owned = vec![];
+    info!("Node coins: {:?}", owned);
+
     // Generating leader proof keys    
     let k: u32 = 13; // Proof rows number
     info!("Generating proof keys with k: {}", k);
@@ -37,10 +77,8 @@ fn main() {
     info!("Epoch {} started!", epoch);
     
     // Generating epoch coins
-    // TODO: Retrieve own coins
-    let owned = vec![];
     // TODO: Retrieve previous lead proof
-    let eta = utils::get_eta(blake3::hash(b"Erebus"));    
+    let eta = pallas::Base::one();
     let epoch_coins = coins::create_epoch_coins(eta, &owned, epoch, slot);
     info!("Generated epoch_coins: {}", epoch_coins.len());    
     for slot in 0..10 {
@@ -67,5 +105,7 @@ fn main() {
             Err(e) => error!("Error during leader proof verification: {}", e),
         }
         
-    }    
+    }
+    
+    Ok(()) 
 }