darkfid.rs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. use drk::blockchain::{rocks::columns, Rocks, RocksColumn, Slab};
  2. use drk::cli::{Config, DarkfidCli, DarkfidConfig};
  3. use drk::cli::{TransferParams, WithdrawParams};
  4. use drk::crypto::{
  5. load_params,
  6. merkle::{CommitmentTree, IncrementalWitness},
  7. merkle_node::MerkleNode,
  8. note::{EncryptedNote, Note},
  9. nullifier::Nullifier,
  10. save_params, setup_mint_prover, setup_spend_prover,
  11. };
  12. use drk::rpc::adapter::RpcAdapter;
  13. use drk::rpc::jsonserver;
  14. use drk::serial::{deserialize, Decodable, Encodable};
  15. use drk::service::{CashierClient, GatewayClient, GatewaySlabsSubscriber};
  16. use drk::state::{state_transition, ProgramState, StateUpdate};
  17. use drk::util::join_config_path;
  18. use drk::wallet::{WalletDb, WalletPtr};
  19. use drk::{tx, Result};
  20. use async_executor::Executor;
  21. use bellman::groth16;
  22. use bls12_381::Bls12;
  23. use easy_parallel::Parallel;
  24. use ff::Field;
  25. use log::*;
  26. use rand::rngs::OsRng;
  27. use rusqlite::Connection;
  28. use async_std::sync::Arc;
  29. use futures::FutureExt;
  30. use std::net::SocketAddr;
  31. use std::path::Path;
  32. use std::path::PathBuf;
  33. use std::str::FromStr;
  34. pub struct State {
  35. // The entire merkle tree state
  36. tree: CommitmentTree<MerkleNode>,
  37. // List of all previous and the current merkle roots
  38. // This is the hashed value of all the children.
  39. merkle_roots: RocksColumn<columns::MerkleRoots>,
  40. // Nullifiers prevent double spending
  41. nullifiers: RocksColumn<columns::Nullifiers>,
  42. // Mint verifying key used by ZK
  43. mint_pvk: groth16::PreparedVerifyingKey<Bls12>,
  44. // Spend verifying key used by ZK
  45. spend_pvk: groth16::PreparedVerifyingKey<Bls12>,
  46. // Public key of the cashier
  47. // List of all our secret keys
  48. wallet: WalletPtr,
  49. }
  50. impl ProgramState for State {
  51. fn is_valid_cashier_public_key(&self, _public: &jubjub::SubgroupPoint) -> bool {
  52. let conn = Connection::open(&self.wallet.path).expect("Failed to connect to database");
  53. let mut stmt = conn
  54. .prepare("SELECT key_public FROM cashier WHERE key_public IN (SELECT key_public)")
  55. .expect("Cannot generate statement.");
  56. stmt.exists([1i32]).expect("Failed to read database")
  57. // do actual validity check
  58. }
  59. fn is_valid_merkle(&self, merkle_root: &MerkleNode) -> bool {
  60. self.merkle_roots
  61. .key_exist(*merkle_root)
  62. .expect("couldn't check if the merkle_root valid")
  63. }
  64. fn nullifier_exists(&self, nullifier: &Nullifier) -> bool {
  65. self.nullifiers
  66. .key_exist(nullifier.repr)
  67. .expect("couldn't check if nullifier exists")
  68. }
  69. // load from disk
  70. fn mint_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
  71. &self.mint_pvk
  72. }
  73. fn spend_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
  74. &self.spend_pvk
  75. }
  76. }
  77. impl State {
  78. async fn apply(&mut self, update: StateUpdate) -> Result<()> {
  79. // Extend our list of nullifiers with the ones from the update
  80. for nullifier in update.nullifiers {
  81. self.nullifiers.put(nullifier, vec![] as Vec<u8>)?;
  82. }
  83. // Update merkle tree and witnesses
  84. for (coin, enc_note) in update.coins.into_iter().zip(update.enc_notes.into_iter()) {
  85. // Add the new coins to the merkle tree
  86. let node = MerkleNode::from_coin(&coin);
  87. self.tree.append(node).expect("Append to merkle tree");
  88. // Keep track of all merkle roots that have existed
  89. self.merkle_roots.put(self.tree.root(), vec![] as Vec<u8>)?;
  90. // Also update all the coin witnesses
  91. for witness in self.wallet.witnesses.lock().await.iter_mut() {
  92. witness.append(node).expect("append to witness");
  93. }
  94. if let Some((note, secret)) = self.try_decrypt_note(enc_note).await {
  95. // We need to keep track of the witness for this coin.
  96. // This allows us to prove inclusion of the coin in the merkle tree with ZK.
  97. // Just as we update the merkle tree with every new coin, so we do the same with
  98. // the witness.
  99. // Derive the current witness from the current tree.
  100. // This is done right after we add our coin to the tree (but before any other
  101. // coins are added)
  102. // Make a new witness for this coin
  103. let witness = IncrementalWitness::from_tree(&self.tree);
  104. self.wallet
  105. .put_own_coins(coin.clone(), note.clone(), witness.clone(), secret)?;
  106. }
  107. }
  108. Ok(())
  109. }
  110. async fn try_decrypt_note(&self, ciphertext: EncryptedNote) -> Option<(Note, jubjub::Fr)> {
  111. let secret = self.wallet.get_private().ok()?;
  112. match ciphertext.decrypt(&secret) {
  113. Ok(note) => {
  114. // ... and return the decrypted note for this coin.
  115. return Some((note, secret.clone()));
  116. }
  117. Err(_) => {}
  118. }
  119. // We weren't able to decrypt the note with our key.
  120. None
  121. }
  122. }
  123. //pub async fn subscribe(
  124. // gateway_slabs_sub: GatewaySlabsSubscriber,
  125. // mut state: State,
  126. //) -> Result<()> {
  127. //}
  128. pub async fn futures_broker(
  129. client: &mut GatewayClient,
  130. cashier_client: &mut CashierClient,
  131. state: &mut State,
  132. secret: jubjub::Fr,
  133. mint_params: bellman::groth16::Parameters<Bls12>,
  134. spend_params: bellman::groth16::Parameters<Bls12>,
  135. gateway_slabs_sub: async_channel::Receiver<Slab>,
  136. deposit_recv: async_channel::Receiver<jubjub::SubgroupPoint>,
  137. cashier_deposit_addr_send: async_channel::Sender<Option<bitcoin::util::address::Address>>,
  138. withdraw_recv: async_channel::Receiver<WithdrawParams>,
  139. _cashier_withdraw_send: async_channel::Sender<jubjub::SubgroupPoint>,
  140. publish_tx_recv: async_channel::Receiver<TransferParams>,
  141. ) -> Result<()> {
  142. loop {
  143. futures::select! {
  144. slab = gateway_slabs_sub.recv().fuse() => {
  145. let slab = slab?;
  146. let tx = tx::Transaction::decode(&slab.get_payload()[..])?;
  147. let update = state_transition(state, tx)?;
  148. state.apply(update).await?;
  149. }
  150. deposit_addr = deposit_recv.recv().fuse() => {
  151. let cashier_public = cashier_client.get_address(deposit_addr?).await?;
  152. cashier_deposit_addr_send.send(cashier_public).await?;
  153. }
  154. withdraw_params = withdraw_recv.recv().fuse() => {
  155. let withdraw_params = withdraw_params?;
  156. let _btc_address = bitcoin::util::address::Address::from_str(&withdraw_params.pub_key);
  157. let _amount = withdraw_params.amount;
  158. // cashier_withdraw_send.send(address).await?;
  159. }
  160. transfer_params = publish_tx_recv.recv().fuse() => {
  161. let transfer_params = transfer_params?;
  162. let merkle_path = {
  163. let (_coin, _, _, witness) = &mut state.wallet.get_own_coins()?[0];
  164. let merkle_path = witness.path().unwrap();
  165. merkle_path
  166. };
  167. let address = bs58::decode(transfer_params.pub_key).into_vec()?;
  168. let address: jubjub::SubgroupPoint = deserialize(&address)?;
  169. // Make a spend tx
  170. // Construct a new tx spending the coin
  171. let builder = tx::TransactionBuilder {
  172. clear_inputs: vec![],
  173. inputs: vec![tx::TransactionBuilderInputInfo {
  174. merkle_path,
  175. secret: secret.clone(),
  176. note: state.wallet.get_own_coins()?[0].1.clone(),
  177. }],
  178. // We can add more outputs to this list.
  179. // The only constraint is that sum(value in) == sum(value out)
  180. outputs: vec![tx::TransactionBuilderOutputInfo {
  181. value: transfer_params.amount as u64,
  182. asset_id: 1,
  183. public: address,
  184. }],
  185. };
  186. // Build the tx
  187. let mut tx_data = vec![];
  188. {
  189. let tx = builder.build(&mint_params, &spend_params);
  190. tx.encode(&mut tx_data).expect("encode tx");
  191. }
  192. let slab = Slab::new(tx_data);
  193. client.put_slab(slab).await.expect("put slab");
  194. }
  195. }
  196. }
  197. }
  198. async fn start(executor: Arc<Executor<'_>>, config: Arc<&DarkfidConfig>) -> Result<()> {
  199. let connect_addr: SocketAddr = config.connect_url.parse()?;
  200. let sub_addr: SocketAddr = config.subscriber_url.parse()?;
  201. let cashier_addr: SocketAddr = config.cashier_url.parse()?;
  202. let database_path = config.database_path.clone();
  203. let walletdb_path = config.walletdb_path.clone();
  204. let database_path = join_config_path(&PathBuf::from(database_path))?;
  205. let walletdb_path = join_config_path(&PathBuf::from(walletdb_path))?;
  206. let rocks = Rocks::new(&database_path)?;
  207. let rocks2 = rocks.clone();
  208. let slabstore = RocksColumn::<columns::Slabs>::new(rocks2.clone());
  209. // Auto create trusted ceremony parameters if they don't exist
  210. if !Path::new("mint.params").exists() {
  211. let params = setup_mint_prover();
  212. save_params("mint.params", &params)?;
  213. }
  214. if !Path::new("spend.params").exists() {
  215. let params = setup_spend_prover();
  216. save_params("spend.params", &params)?;
  217. }
  218. // Load trusted setup parameters
  219. let (mint_params, mint_pvk) = load_params("mint.params")?;
  220. let (spend_params, spend_pvk) = load_params("spend.params")?;
  221. //let cashier_secret = jubjub::Fr::random(&mut OsRng);
  222. //let cashier_public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * cashier_secret;
  223. // wallet secret key
  224. let secret = jubjub::Fr::random(&mut OsRng);
  225. // wallet public key
  226. let _public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret;
  227. let merkle_roots = RocksColumn::<columns::MerkleRoots>::new(rocks.clone());
  228. let nullifiers = RocksColumn::<columns::Nullifiers>::new(rocks);
  229. let wallet = Arc::new(WalletDb::new(&walletdb_path, config.password.clone())?);
  230. let ex = executor.clone();
  231. let mut state = State {
  232. tree: CommitmentTree::empty(),
  233. merkle_roots,
  234. nullifiers,
  235. mint_pvk,
  236. spend_pvk,
  237. wallet: wallet.clone(),
  238. };
  239. // create gateway client
  240. debug!(target: "Client", "Creating client");
  241. let mut client = GatewayClient::new(connect_addr, slabstore)?;
  242. // create cashier client
  243. debug!(target: "Cashier Client", "Creating cashier client");
  244. let mut cashier_client = CashierClient::new(cashier_addr)?;
  245. debug!(target: "Gateway", "Start subscriber");
  246. // start subscribing
  247. let gateway_slabs_sub: GatewaySlabsSubscriber =
  248. client.start_subscriber(sub_addr, executor.clone()).await?;
  249. // channels to request transfer from adapter
  250. let (publish_tx_send, publish_tx_recv) = async_channel::unbounded::<TransferParams>();
  251. // channels to request deposit from adapter and receive cashier public key
  252. let (deposit_send, deposit_recv) = async_channel::unbounded::<jubjub::SubgroupPoint>();
  253. let (cashier_deposit_addr_send, cashier_deposit_addr_recv) =
  254. async_channel::unbounded::<Option<bitcoin::util::address::Address>>();
  255. // channel to request withdraw from adapter
  256. let (withdraw_send, withdraw_recv) = async_channel::unbounded::<WithdrawParams>();
  257. let (cashier_withdraw_send, cashier_withdraw_recv) =
  258. async_channel::unbounded::<jubjub::SubgroupPoint>();
  259. // start gateway client
  260. debug!(target: "fn::start client", "start() Client started");
  261. client.start().await?;
  262. cashier_client.start().await?;
  263. let futures_broker_task = executor.spawn(async move {
  264. futures_broker(
  265. &mut client,
  266. &mut cashier_client,
  267. &mut state,
  268. secret.clone(),
  269. mint_params.clone(),
  270. spend_params.clone(),
  271. gateway_slabs_sub.clone(),
  272. deposit_recv.clone(),
  273. cashier_deposit_addr_send.clone(),
  274. withdraw_recv.clone(),
  275. cashier_withdraw_send.clone(),
  276. publish_tx_recv.clone(),
  277. )
  278. .await?;
  279. Ok::<(), drk::Error>(())
  280. });
  281. let adapter = RpcAdapter::new(
  282. wallet.clone(),
  283. publish_tx_send,
  284. (deposit_send, cashier_deposit_addr_recv),
  285. (withdraw_send, cashier_withdraw_recv),
  286. )?;
  287. // start the rpc server
  288. jsonserver::start(ex.clone(), config.clone(), adapter).await?;
  289. futures_broker_task.cancel().await;
  290. Ok(())
  291. }
  292. fn main() -> Result<()> {
  293. let options = Arc::new(DarkfidCli::load()?);
  294. let config_path: PathBuf;
  295. match options.config.as_ref() {
  296. Some(path) => {
  297. config_path = path.to_owned();
  298. }
  299. None => {
  300. config_path = join_config_path(&PathBuf::from("darkfid.toml"))?;
  301. }
  302. }
  303. let config: DarkfidConfig = if Path::new(&config_path).exists() {
  304. Config::<DarkfidConfig>::load(config_path)?
  305. } else {
  306. Config::<DarkfidConfig>::load_default(config_path)?
  307. };
  308. let config_ptr = Arc::new(&config);
  309. let ex = Arc::new(Executor::new());
  310. let (signal, shutdown) = async_channel::unbounded::<()>();
  311. {
  312. use simplelog::*;
  313. let logger_config = ConfigBuilder::new().set_time_format_str("%T%.6f").build();
  314. let debug_level = if options.verbose {
  315. LevelFilter::Debug
  316. } else {
  317. LevelFilter::Off
  318. };
  319. let log_path = config.log_path.clone();
  320. CombinedLogger::init(vec![
  321. TermLogger::new(debug_level, logger_config, TerminalMode::Mixed).unwrap(),
  322. WriteLogger::new(
  323. LevelFilter::Debug,
  324. Config::default(),
  325. std::fs::File::create(log_path).unwrap(),
  326. ),
  327. ])
  328. .unwrap();
  329. }
  330. let ex2 = ex.clone();
  331. let (_, result) = Parallel::new()
  332. // Run four executor threads.
  333. .each(0..3, |_| smol::future::block_on(ex.run(shutdown.recv())))
  334. // Run the main future on the current thread.
  335. .finish(|| {
  336. smol::future::block_on(async move {
  337. start(ex2, config_ptr).await?;
  338. drop(signal);
  339. Ok::<(), drk::Error>(())
  340. })
  341. });
  342. result
  343. }