harness.rs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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,
  23. ValidatorStatePtr,
  24. TESTNET_BOOTSTRAP_TIMESTAMP,
  25. TESTNET_GENESIS_HASH_BYTES,
  26. TESTNET_GENESIS_TIMESTAMP,
  27. TESTNET_INITIAL_DISTRIBUTION,
  28. },
  29. runtime::vm_runtime::SMART_CONTRACT_ZKAS_DB_NAME,
  30. tx::Transaction,
  31. wallet::{WalletDb, WalletPtr},
  32. zk::{empty_witnesses, halo2::Field, ProvingKey, ZkCircuit},
  33. zkas::ZkBinary,
  34. Result,
  35. };
  36. use darkfi_sdk::{
  37. crypto::{
  38. Keypair,
  39. MerkleTree,
  40. PublicKey,
  41. SecretKey,
  42. DARK_TOKEN_ID,
  43. MAP_CONTRACT_ID
  44. },
  45. pasta::pallas,
  46. ContractCall,
  47. };
  48. use darkfi_serial::{deserialize, serialize, Encodable};
  49. use log::info;
  50. use rand::rngs::OsRng;
  51. use darkfi_map_contract::{
  52. model::SetParamsV1,
  53. client::set_v1::SetCallBuilder,
  54. ContractFunction,
  55. };
  56. pub const MAP_CONTRACT_ZKAS_SET_NS_V1: &str = "Set_V1";
  57. pub fn init_logger() {
  58. let mut cfg = simplelog::ConfigBuilder::new();
  59. cfg.add_filter_ignore("sled".to_string());
  60. cfg.add_filter_ignore("blockchain::contractstore".to_string());
  61. // We check this error so we can execute same file tests in parallel
  62. // otherwise second one fails to init logger here.
  63. if let Err(_) = simplelog::TermLogger::init(
  64. // simplelog::LevelFilter::Info,
  65. simplelog::LevelFilter::Debug,
  66. //simplelog::LevelFilter::Trace,
  67. cfg.build(),
  68. simplelog::TerminalMode::Mixed,
  69. simplelog::ColorChoice::Auto,
  70. ) {
  71. info!(target: "map_harness", "Logger already initialized");
  72. }
  73. }
  74. pub struct Wallet {
  75. pub keypair: Keypair,
  76. pub state: ValidatorStatePtr,
  77. pub merkle_tree: MerkleTree,
  78. pub wallet: WalletPtr,
  79. }
  80. impl Wallet {
  81. async fn new(
  82. keypair: Keypair,
  83. faucet_pubkeys: &[PublicKey]
  84. ) -> Result<Self> {
  85. let wallet = WalletDb::new("sqlite::memory:", "foo").await?;
  86. let sled_db = sled::Config::new().temporary(true).open()?;
  87. let state = ValidatorState::new(
  88. &sled_db,
  89. *TESTNET_BOOTSTRAP_TIMESTAMP,
  90. *TESTNET_GENESIS_TIMESTAMP,
  91. *TESTNET_GENESIS_HASH_BYTES,
  92. *TESTNET_INITIAL_DISTRIBUTION,
  93. wallet.clone(),
  94. faucet_pubkeys.to_vec(),
  95. false,
  96. false,
  97. )
  98. .await?;
  99. let merkle_tree = MerkleTree::new(100);
  100. Ok(Self { keypair, state, merkle_tree, wallet, })
  101. }
  102. }
  103. pub struct MapTestHarness {
  104. pub faucet: Wallet,
  105. pub alice: Wallet,
  106. pub proving_keys: HashMap<&'static str, (ProvingKey, ZkBinary)>,
  107. }
  108. impl MapTestHarness {
  109. pub async fn new() -> Result<Self> {
  110. let faucet_kp = Keypair::random(&mut OsRng);
  111. let faucet_pubkeys = vec![faucet_kp.public];
  112. let faucet = Wallet::new(faucet_kp, &faucet_pubkeys).await?;
  113. let alice_kp = Keypair::random(&mut OsRng);
  114. let alice = Wallet::new(alice_kp, &faucet_pubkeys).await?;
  115. // Get the zkas circuits and build proving keys
  116. let alice_sled =
  117. alice.state.read().await.blockchain.sled_db.clone();
  118. let db_handle =
  119. alice.state.read().await.blockchain.contracts.lookup(
  120. &alice_sled,
  121. &MAP_CONTRACT_ID,
  122. SMART_CONTRACT_ZKAS_DB_NAME,
  123. )?;
  124. // build proving keys
  125. let mut proving_keys = HashMap::new();
  126. macro_rules! mkpk {
  127. ($ns:expr) => {
  128. let zkas_bytes =
  129. db_handle.get(&serialize(&$ns))?.unwrap();
  130. let (zkbin, _): (Vec<u8>, Vec<u8>) =
  131. deserialize(&zkas_bytes)?;
  132. let zkbin = ZkBinary::decode(&zkbin)?;
  133. let witnesses = empty_witnesses(&zkbin);
  134. let circuit = ZkCircuit::new(witnesses, zkbin.clone());
  135. let pk = ProvingKey::build(13, &circuit);
  136. proving_keys.insert($ns, (pk, zkbin));
  137. };
  138. }
  139. mkpk!(MAP_CONTRACT_ZKAS_SET_NS_V1);
  140. Ok(Self { faucet, alice, proving_keys })
  141. }
  142. pub fn set(
  143. &self,
  144. secret: SecretKey,
  145. lock: pallas::Base,
  146. car: pallas::Base,
  147. key: pallas::Base,
  148. value: pallas::Base,
  149. ) -> Result<(Transaction, SetParamsV1)> {
  150. let (prove_key, zkbin) =
  151. self.proving_keys.get(
  152. &MAP_CONTRACT_ZKAS_SET_NS_V1
  153. ).unwrap();
  154. let debris = SetCallBuilder {
  155. zkbin: zkbin.clone(),
  156. prove_key: prove_key.clone(),
  157. secret: secret.clone(),
  158. lock: lock.clone(),
  159. car: car.clone(),
  160. key: key.clone(),
  161. value: value.clone()
  162. }.build()?;
  163. let mut data = vec![ContractFunction::Set as u8];
  164. debris.params.encode(&mut data)?;
  165. let calls = vec![
  166. ContractCall { contract_id: *MAP_CONTRACT_ID, data: data }
  167. ];
  168. let proofs = vec![debris.proofs];
  169. let mut tx = Transaction { calls, proofs, signatures: vec![] };
  170. let sigs = tx.create_sigs(&mut OsRng, &debris.signature_secrets)?;
  171. tx.signatures = vec![sigs];
  172. Ok((tx, debris.params))
  173. }
  174. }