main.rs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. use async_std::sync::Arc;
  2. use log::{error, info};
  3. use pasta_curves::pallas;
  4. use structopt_toml::{serde::Deserialize, structopt::StructOpt, StructOptToml};
  5. use darkfi::{
  6. async_daemonize, cli_desc,
  7. consensus::coins,
  8. crypto::{
  9. lead_proof,
  10. proof::{ProvingKey, VerifyingKey},
  11. },
  12. node::Client,
  13. wallet::walletdb::init_wallet,
  14. zk::circuit::LeadContract,
  15. Result,
  16. };
  17. const CONFIG_FILE: &str = "crypsinous_playground_config.toml";
  18. const CONFIG_FILE_CONTENTS: &str = include_str!("../crypsinous_playground_config.toml");
  19. #[derive(Clone, Debug, Deserialize, StructOpt, StructOptToml)]
  20. #[serde(default)]
  21. #[structopt(name = "crypsinous_playground", about = cli_desc!())]
  22. struct Args {
  23. #[structopt(short, long)]
  24. /// Configuration file to use
  25. config: Option<String>,
  26. #[structopt(long, default_value = "~/.config/darkfi/crypsinous_playground/wallet.db")]
  27. /// Path to wallet database
  28. wallet_path: String,
  29. #[structopt(long, default_value = "changeme")]
  30. /// Password for the wallet database
  31. wallet_pass: String,
  32. #[structopt(short, default_value = "1")]
  33. /// How many epochs to simulate
  34. epochs: u64,
  35. #[structopt(short, parse(from_occurrences))]
  36. /// Increase verbosity (-vvv supported)
  37. verbose: u8,
  38. }
  39. // The porpuse of this script is to simulate a staker actions through an epoch.
  40. // Main focus is the crypsinous lottery mechanism and the leader proof creation and validation.
  41. // Other flows that happen through a slot, like broadcasting blocks or syncing are out of scope.
  42. async_daemonize!(realmain);
  43. async fn realmain(args: Args, _ex: Arc<smol::Executor<'_>>) -> Result<()> {
  44. // Epochs sanity check
  45. let epochs = args.epochs;
  46. if epochs < 1 {
  47. error!("Epochs must be a positive number.");
  48. return Ok(());
  49. }
  50. info!("Simulation epochs: {}", epochs);
  51. // Initialize wallet that holds coins for staking
  52. let wallet = init_wallet(&args.wallet_path, &args.wallet_pass).await?;
  53. // Initialize client
  54. let client = Arc::new(Client::new(wallet.clone()).await?);
  55. // Retrieving nodes wallet coins
  56. let mut owned = client.get_own_coins().await?;
  57. // If node holds no coins in its wallet, we generate some new staking coins
  58. if owned.is_empty() {
  59. info!("Node wallet is empty, generating new staking coins...");
  60. owned = coins::generate_staking_coins(&wallet).await?;
  61. }
  62. // If we want to test what will happen if node holds 0 coins, uncomment the below line
  63. // owned = vec![];
  64. info!("Node coins: {:?}", owned);
  65. // Generating leader proof keys
  66. let k: u32 = 13; // Proof rows number
  67. info!("Generating proof keys with k: {}", k);
  68. let proving_key = ProvingKey::build(k, &LeadContract::default());
  69. let verifying_key = VerifyingKey::build(k, &LeadContract::default());
  70. // Simulating epochs with 10 slots
  71. for epoch in 0..epochs {
  72. info!("Epoch {} started!", epoch);
  73. // Generating epoch coins
  74. // TODO: Retrieve previous lead proof
  75. let eta = pallas::Base::one();
  76. let epoch_coins = coins::create_epoch_coins(eta, &owned, epoch, 0);
  77. info!("Generated epoch_coins: {}", epoch_coins.len());
  78. for slot in 0..10 {
  79. // Checking if slot leader
  80. info!("Slot {} started!", slot);
  81. let (won, idx) = coins::is_leader(slot, &epoch_coins);
  82. info!("Lottery outcome: {}", won);
  83. if !won {
  84. continue
  85. }
  86. // TODO: Generate rewards transaction
  87. info!("Winning coin index: {}", idx);
  88. // Generating leader proof
  89. let coin = epoch_coins[slot as usize][idx];
  90. let proof = lead_proof::create_lead_proof(&proving_key, coin);
  91. if proof.is_err() {
  92. error!("Error during leader proof creation: {}", proof.err().unwrap());
  93. continue
  94. }
  95. //Verifying generated proof against winning coin public inputs
  96. info!("Leader proof generated successfully, veryfing...");
  97. match lead_proof::verify_lead_proof(&verifying_key, &proof.unwrap(), &coin.public_inputs()) {
  98. Ok(_) => info!("Proof veryfied succsessfully!"),
  99. Err(e) => error!("Error during leader proof verification: {}", e),
  100. }
  101. }
  102. }
  103. Ok(())
  104. }