harness.rs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2023 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public
  16. * License along with this program.
  17. * If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. use std::collections::HashMap;
  20. use darkfi::{
  21. consensus::{
  22. ValidatorState, ValidatorStatePtr, TESTNET_BOOTSTRAP_TIMESTAMP, TESTNET_GENESIS_HASH_BYTES,
  23. TESTNET_GENESIS_TIMESTAMP, TESTNET_INITIAL_DISTRIBUTION,
  24. },
  25. runtime::vm_runtime::SMART_CONTRACT_ZKAS_DB_NAME,
  26. tx::Transaction,
  27. wallet::{WalletDb, WalletPtr},
  28. zk::{empty_witnesses, halo2::Field, ProvingKey, ZkCircuit},
  29. zkas::ZkBinary,
  30. Result,
  31. };
  32. use darkfi_sdk::{
  33. crypto::{Keypair, MerkleTree, PublicKey, SecretKey, DARK_TOKEN_ID, MAP_CONTRACT_ID},
  34. pasta::pallas,
  35. ContractCall,
  36. };
  37. use darkfi_serial::{deserialize, serialize, Encodable};
  38. use log::info;
  39. use rand::rngs::OsRng;
  40. use darkfi_map_contract::{client::set_v1::SetCallBuilder, model::SetParamsV1, ContractFunction};
  41. pub const MAP_CONTRACT_ZKAS_SET_NS_V1: &str = "Set_V1";
  42. pub fn init_logger() {
  43. let mut cfg = simplelog::ConfigBuilder::new();
  44. cfg.add_filter_ignore("sled".to_string());
  45. cfg.add_filter_ignore("blockchain::contractstore".to_string());
  46. // We check this error so we can execute same file tests in parallel
  47. // otherwise second one fails to init logger here.
  48. if let Err(_) = simplelog::TermLogger::init(
  49. // simplelog::LevelFilter::Info,
  50. simplelog::LevelFilter::Debug,
  51. //simplelog::LevelFilter::Trace,
  52. cfg.build(),
  53. simplelog::TerminalMode::Mixed,
  54. simplelog::ColorChoice::Auto,
  55. ) {
  56. info!(target: "map_harness", "Logger already initialized");
  57. }
  58. }
  59. pub struct Wallet {
  60. pub keypair: Keypair,
  61. pub state: ValidatorStatePtr,
  62. pub merkle_tree: MerkleTree,
  63. pub wallet: WalletPtr,
  64. }
  65. impl Wallet {
  66. async fn new(keypair: Keypair, faucet_pubkeys: &[PublicKey]) -> Result<Self> {
  67. let wallet = WalletDb::new("sqlite::memory:", "foo").await?;
  68. let sled_db = sled::Config::new().temporary(true).open()?;
  69. let state = ValidatorState::new(
  70. &sled_db,
  71. *TESTNET_BOOTSTRAP_TIMESTAMP,
  72. *TESTNET_GENESIS_TIMESTAMP,
  73. *TESTNET_GENESIS_HASH_BYTES,
  74. *TESTNET_INITIAL_DISTRIBUTION,
  75. wallet.clone(),
  76. faucet_pubkeys.to_vec(),
  77. false,
  78. false,
  79. )
  80. .await?;
  81. let merkle_tree = MerkleTree::new(100);
  82. Ok(Self {
  83. keypair,
  84. state,
  85. merkle_tree,
  86. wallet,
  87. })
  88. }
  89. }
  90. pub struct MapTestHarness {
  91. pub faucet: Wallet,
  92. pub alice: Wallet,
  93. pub proving_keys: HashMap<&'static str, (ProvingKey, ZkBinary)>,
  94. }
  95. impl MapTestHarness {
  96. pub async fn new() -> Result<Self> {
  97. let faucet_kp = Keypair::random(&mut OsRng);
  98. let faucet_pubkeys = vec![faucet_kp.public];
  99. let faucet = Wallet::new(faucet_kp, &faucet_pubkeys).await?;
  100. let alice_kp = Keypair::random(&mut OsRng);
  101. let alice = Wallet::new(alice_kp, &faucet_pubkeys).await?;
  102. // Get the zkas circuits and build proving keys
  103. let alice_sled = alice.state.read().await.blockchain.sled_db.clone();
  104. let db_handle = alice.state.read().await.blockchain.contracts.lookup(
  105. &alice_sled,
  106. &MAP_CONTRACT_ID,
  107. SMART_CONTRACT_ZKAS_DB_NAME,
  108. )?;
  109. // build proving keys
  110. let mut proving_keys = HashMap::new();
  111. macro_rules! mkpk {
  112. ($ns:expr) => {
  113. let zkas_bytes = db_handle.get(&serialize(&$ns))?.unwrap();
  114. let (zkbin, _): (Vec<u8>, Vec<u8>) = deserialize(&zkas_bytes)?;
  115. let zkbin = ZkBinary::decode(&zkbin)?;
  116. let witnesses = empty_witnesses(&zkbin);
  117. let circuit = ZkCircuit::new(witnesses, zkbin.clone());
  118. let pk = ProvingKey::build(13, &circuit);
  119. proving_keys.insert($ns, (pk, zkbin));
  120. };
  121. }
  122. mkpk!(MAP_CONTRACT_ZKAS_SET_NS_V1);
  123. Ok(Self {
  124. faucet,
  125. alice,
  126. proving_keys,
  127. })
  128. }
  129. pub fn set(
  130. &self,
  131. secret: SecretKey,
  132. lock: pallas::Base,
  133. car: pallas::Base,
  134. key: pallas::Base,
  135. value: pallas::Base,
  136. ) -> Result<(Transaction, SetParamsV1)> {
  137. let (prove_key, zkbin) = self.proving_keys.get(&MAP_CONTRACT_ZKAS_SET_NS_V1).unwrap();
  138. let debris = SetCallBuilder {
  139. zkbin: zkbin.clone(),
  140. prove_key: prove_key.clone(),
  141. secret: secret.clone(),
  142. lock: lock.clone(),
  143. car: car.clone(),
  144. key: key.clone(),
  145. value: value.clone(),
  146. }
  147. .build()?;
  148. let mut data = vec![ContractFunction::Set as u8];
  149. debris.params.encode(&mut data)?;
  150. let calls = vec![ContractCall {
  151. contract_id: *MAP_CONTRACT_ID,
  152. data: data,
  153. }];
  154. let proofs = vec![debris.proofs];
  155. let mut tx = Transaction {
  156. calls,
  157. proofs,
  158. signatures: vec![],
  159. };
  160. let sigs = tx.create_sigs(&mut OsRng, &debris.signature_secrets)?;
  161. tx.signatures = vec![sigs];
  162. Ok((tx, debris.params))
  163. }
  164. }