From 1058a9cc13fb244d6c0c357ee5268f193e439c8e Mon Sep 17 00:00:00 2001 From: Janus Date: Sun, 27 Jun 2021 21:12:21 -0400 Subject: [PATCH 01/20] Add bitcoin --- Cargo.lock | 42 ++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 5 +++-- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 919e6c9a3..78f395399 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -401,6 +401,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "bech32" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dabbe35f96fb9507f7330793dc490461b2962659ac5d427181e451a623751d1" + [[package]] name = "bellman" version = "0.8.1" @@ -446,6 +452,23 @@ dependencies = [ "shlex", ] +[[package]] +name = "bitcoin" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6742ec672d3f12506f4ac5c0d853926ff1f94e675f60ffd3224039972bf663f1" +dependencies = [ + "bech32", + "bitcoin_hashes", + "secp256k1", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ce18265ec2324ad075345d5814fbeed4f41f0a660055dc78840b74d19b874b1" + [[package]] name = "bitflags" version = "1.2.1" @@ -961,6 +984,7 @@ dependencies = [ "async-trait", "bellman", "bimap", + "bitcoin", "bitvec", "blake2b_simd", "blake2s_simd", @@ -2426,6 +2450,24 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "secp256k1" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "827cb7cce42533829c792fc51b82fbf18b125b45a702ef2c8be77fce65463a7b" +dependencies = [ + "cc", +] + [[package]] name = "security-framework" version = "2.3.1" diff --git a/Cargo.toml b/Cargo.toml index bf55586b5..fed669afc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ bls12_381 = "0.3.1" jubjub = "0.5.1" zcash_primitives = "0.5.0" -zcash_proofs = "0.5.0" +zcash_proofs = "0.5.0" # zcash_primitives = { git = "https://github.com/zcash/librustzcash" } #zcash_proofs = { git = "https://github.com/zcash/librustzcash" } #zcash_proofs = { git = "https://github.com/narodnik/librustzcash" } @@ -77,6 +77,8 @@ bytes = "1.0.1" rocksdb = "0.16.0" dirs = "3.0.2" +bitcoin = "0.26.2" + [dependencies.rusqlite] version = "0.25.1" features = ["bundled", "sqlcipher"] @@ -118,4 +120,3 @@ path = "src/bin/drk.rs" [profile.release] debug = 1 - From 4b6f7427f677d8b111ffde61fdc81cf95f4ef41b Mon Sep 17 00:00:00 2001 From: Janus Date: Mon, 5 Jul 2021 14:21:19 -0500 Subject: [PATCH 02/20] Add secp256k1 --- Cargo.lock | 1 + Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 78f395399..19eff76ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1017,6 +1017,7 @@ dependencies = [ "rocksdb", "rusqlite", "serde", + "secp256k1", "serde_json", "sha2", "signal-hook", diff --git a/Cargo.toml b/Cargo.toml index fed669afc..4d25fa4e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,6 +78,7 @@ rocksdb = "0.16.0" dirs = "3.0.2" bitcoin = "0.26.2" +secp256k1 = "0.20.3" [dependencies.rusqlite] version = "0.25.1" From 17f2afa5fd686c49b4ee8f3a32104dfd0564ce28 Mon Sep 17 00:00:00 2001 From: Janus Date: Thu, 8 Jul 2021 16:56:01 -0500 Subject: [PATCH 03/20] Initial CashierService --- src/service/bitcoin_bridge.rs | 139 ++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 src/service/bitcoin_bridge.rs diff --git a/src/service/bitcoin_bridge.rs b/src/service/bitcoin_bridge.rs new file mode 100644 index 000000000..2fc136d03 --- /dev/null +++ b/src/service/bitcoin_bridge.rs @@ -0,0 +1,139 @@ +use secp256k1::key::SecretKey; +use bitcoin::util::{ecdsa::PrivateKey, address::Address}; +use super::reqrep::{PeerId, RepProtocol, Reply, ReqProtocol, Request}; +use std::net::SocketAddr; +use async_std::sync::Arc; +use async_executor::Executor; + +pub struct BitcoinAddr { + secret_key: PrivateKey, + pub_address: Address +} +impl BitcoinAddr { + pub fn new( + ) -> Result> { + let secret_key = SecretKey::new(); + + } +} + +pub struct CashierService { + addr: SocketAddr, + pub_addr: SocketAddr, +} + +impl CashierService { + pub fn new( + addr: SocketAddr, + pub_addr: SocketAddr, + )-> Result> { + + Ok(Arc::new(CashierService { + addr, + pub_addr, + })) + } + pub async fn start(self: Arc, executor: Arc>) -> Result<()> { + let service_name = String::from("CASHIER DAEMON"); + + let mut protocol = RepProtocol::new(self.addr.clone(), service_name.clone()); + + let (send, recv) = protocol.start().await?; + + let handle_request_task = executor.spawn(self.handle_request_loop( + send.clone(), + recv.clone(), + executor.clone(), + )); + + protocol.run(executor.clone()).await?; + + let _ = handle_request_task.cancel().await; + Ok(()) + } + + async fn handle_request_loop( + self: Arc, + send_queue: async_channel::Sender<(PeerId, Reply)>, + recv_queue: async_channel::Receiver<(PeerId, Request)>, + executor: Arc>, + ) -> Result<()> { + loop { + match recv_queue.recv().await { + Ok(msg) => { + let slabstore = self.slabstore.clone(); + let _ = executor + .spawn(Self::handle_request( + msg, + slabstore, + send_queue.clone(), + )) + .detach(); + } + Err(_) => { + break; + } + } + } + Ok(()) + } + async fn handle_request( + msg: (PeerId, Request), + slabstore: Arc, + send_queue: async_channel::Sender<(PeerId, Reply)>, + ) -> Result<()> { + let request = msg.1; + let peer = msg.0; + match request.get_command() { + 0 => { + // PUTSLAB + + let slab = request.get_payload(); + + // add to slabstore + let error = slabstore.put(deserialize(&slab)?)?; + + let mut reply = Reply::from(&request, GatewayError::NoError as u32, vec![]); + + if let None = error { + reply.set_error(GatewayError::UpdateIndex as u32); + } + + // send reply + send_queue.send((peer, reply)).await?; + + info!("Received putslab msg"); + } + 1 => { + let index = request.get_payload(); + let slab = slabstore.get(index)?; + + let mut reply = Reply::from(&request, GatewayError::NoError as u32, vec![]); + + if let Some(payload) = slab { + reply.set_payload(payload); + } else { + reply.set_error(GatewayError::IndexNotExist as u32); + } + + send_queue.send((peer, reply)).await?; + + // GETSLAB + info!("Received getslab msg"); + } + 2 => { + let index = slabstore.get_last_index_as_bytes()?; + + let reply = Reply::from(&request, GatewayError::NoError as u32, index); + send_queue.send((peer, reply)).await?; + + // GETLASTINDEX + info!("Received getlastindex msg"); + } + _ => { + return Err(Error::ServicesError("received wrong command")); + } + } + Ok(()) + } +} From 8ff94791b57feaadb2cf5dcde7a0211f30d30e15 Mon Sep 17 00:00:00 2001 From: Janus Date: Fri, 9 Jul 2021 11:30:14 -0500 Subject: [PATCH 04/20] Remove copied handle_request results --- src/service/bitcoin_bridge.rs | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/src/service/bitcoin_bridge.rs b/src/service/bitcoin_bridge.rs index 2fc136d03..7545b45e1 100644 --- a/src/service/bitcoin_bridge.rs +++ b/src/service/bitcoin_bridge.rs @@ -86,49 +86,14 @@ impl CashierService { let peer = msg.0; match request.get_command() { 0 => { - // PUTSLAB - let slab = request.get_payload(); - // add to slabstore - let error = slabstore.put(deserialize(&slab)?)?; - - let mut reply = Reply::from(&request, GatewayError::NoError as u32, vec![]); - - if let None = error { - reply.set_error(GatewayError::UpdateIndex as u32); - } - - // send reply - send_queue.send((peer, reply)).await?; - - info!("Received putslab msg"); } 1 => { - let index = request.get_payload(); - let slab = slabstore.get(index)?; - let mut reply = Reply::from(&request, GatewayError::NoError as u32, vec![]); - - if let Some(payload) = slab { - reply.set_payload(payload); - } else { - reply.set_error(GatewayError::IndexNotExist as u32); - } - - send_queue.send((peer, reply)).await?; - - // GETSLAB - info!("Received getslab msg"); } 2 => { - let index = slabstore.get_last_index_as_bytes()?; - let reply = Reply::from(&request, GatewayError::NoError as u32, index); - send_queue.send((peer, reply)).await?; - - // GETLASTINDEX - info!("Received getlastindex msg"); } _ => { return Err(Error::ServicesError("received wrong command")); From ceb6618e181a3c7898d414262a6c1d564d0c10c6 Mon Sep 17 00:00:00 2001 From: Janus Date: Mon, 12 Jul 2021 01:15:56 -0500 Subject: [PATCH 05/20] Add bitcoin key derivation to Bitcoin obj --- src/service/bitcoin_bridge.rs | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/service/bitcoin_bridge.rs b/src/service/bitcoin_bridge.rs index 7545b45e1..be9b5d9a7 100644 --- a/src/service/bitcoin_bridge.rs +++ b/src/service/bitcoin_bridge.rs @@ -1,19 +1,37 @@ -use secp256k1::key::SecretKey; -use bitcoin::util::{ecdsa::PrivateKey, address::Address}; +use secp256k1::key::{SecretKey, PublicKey}; +use bitcoin::util::{ecdsa::PrivateKey, ecdsa::PublicKey, address::Payload, address::Address}; +// Use p2sh for 1st iteration +use bitcoin::hash_types::ScriptHash; +use bitcoin::network::constants::Network; use super::reqrep::{PeerId, RepProtocol, Reply, ReqProtocol, Request}; use std::net::SocketAddr; use async_std::sync::Arc; use async_executor::Executor; -pub struct BitcoinAddr { - secret_key: PrivateKey, - pub_address: Address +pub struct BitcoinAddress { + secret_key: SecretKey, + private_key: ecdsa::PrivateKey, + public_key: ecdsa::PublicKey, + pub_address: Address, } -impl BitcoinAddr { +impl BitcoinAddress { pub fn new( - ) -> Result> { - let secret_key = SecretKey::new(); + secret_key: SecretKey, + ) -> Result> { + // Use mainnet + let private_key = PrivateKey::new(secret_key, Network::Bitcoin); + + let public_key = PublicKey::new(secret_key); + + //let pub_address = Address::new(); + + Ok(Arc::new(BitcoinAddress { + secret_key, + private_key, + public_key, + pub_address, + })) } } From 815a9d780c41c20e256f993b391e2d24608757d1 Mon Sep 17 00:00:00 2001 From: Janus Date: Mon, 12 Jul 2021 06:30:20 -0400 Subject: [PATCH 06/20] Create a temp bitcoin address in obj --- src/service/bitcoin_bridge.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/service/bitcoin_bridge.rs b/src/service/bitcoin_bridge.rs index be9b5d9a7..45001286b 100644 --- a/src/service/bitcoin_bridge.rs +++ b/src/service/bitcoin_bridge.rs @@ -1,7 +1,7 @@ use secp256k1::key::{SecretKey, PublicKey}; -use bitcoin::util::{ecdsa::PrivateKey, ecdsa::PublicKey, address::Payload, address::Address}; -// Use p2sh for 1st iteration -use bitcoin::hash_types::ScriptHash; +use bitcoin::util::{ecdsa::PrivateKey, ecdsa::PublicKey as BitcoinPubKey, address::Payload, address::Address}; +// Use p2pkh for 1st iteration +use bitcoin::hash_types::PubkeyHash; use bitcoin::network::constants::Network; use super::reqrep::{PeerId, RepProtocol, Reply, ReqProtocol, Request}; use std::net::SocketAddr; @@ -11,7 +11,7 @@ use async_executor::Executor; pub struct BitcoinAddress { secret_key: SecretKey, private_key: ecdsa::PrivateKey, - public_key: ecdsa::PublicKey, + public_key: BitcoinPubKey, pub_address: Address, } impl BitcoinAddress { @@ -22,9 +22,9 @@ impl BitcoinAddress { // Use mainnet let private_key = PrivateKey::new(secret_key, Network::Bitcoin); - let public_key = PublicKey::new(secret_key); + let public_key = BitcoinPubKey::from_private_key(private_key); - //let pub_address = Address::new(); + let pub_address = Address::p2sh(&public_key, Network::Bitcoin); Ok(Arc::new(BitcoinAddress { secret_key, From d7f9ccd4b0c9732e215dc8f303b1f707bcc4d121 Mon Sep 17 00:00:00 2001 From: Janus Date: Mon, 12 Jul 2021 06:35:17 -0400 Subject: [PATCH 07/20] Remove code --- src/service/bitcoin_bridge.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/service/bitcoin_bridge.rs b/src/service/bitcoin_bridge.rs index 45001286b..6489842f8 100644 --- a/src/service/bitcoin_bridge.rs +++ b/src/service/bitcoin_bridge.rs @@ -79,11 +79,9 @@ impl CashierService { loop { match recv_queue.recv().await { Ok(msg) => { - let slabstore = self.slabstore.clone(); let _ = executor .spawn(Self::handle_request( msg, - slabstore, send_queue.clone(), )) .detach(); @@ -97,7 +95,6 @@ impl CashierService { } async fn handle_request( msg: (PeerId, Request), - slabstore: Arc, send_queue: async_channel::Sender<(PeerId, Reply)>, ) -> Result<()> { let request = msg.1; From bee4a6faea793e8754cb0a058d1e6488d4b86262 Mon Sep 17 00:00:00 2001 From: Janus Date: Mon, 12 Jul 2021 08:51:50 -0400 Subject: [PATCH 08/20] Properly derive a p2pkh from rand --- src/service/bitcoin_bridge.rs | 33 +++++++++++++++++++++++---------- src/service/mod.rs | 3 +++ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/service/bitcoin_bridge.rs b/src/service/bitcoin_bridge.rs index 6489842f8..3d6b85159 100644 --- a/src/service/bitcoin_bridge.rs +++ b/src/service/bitcoin_bridge.rs @@ -1,35 +1,48 @@ +use rand::{thread_rng, Rng}; use secp256k1::key::{SecretKey, PublicKey}; -use bitcoin::util::{ecdsa::PrivateKey, ecdsa::PublicKey as BitcoinPubKey, address::Payload, address::Address}; +use bitcoin::util::ecdsa::{PrivateKey, PublicKey as BitcoinPubKey}; +use bitcoin::util::{address::Payload, address::Address}; // Use p2pkh for 1st iteration use bitcoin::hash_types::PubkeyHash; use bitcoin::network::constants::Network; use super::reqrep::{PeerId, RepProtocol, Reply, ReqProtocol, Request}; +use crate::{serial::deserialize, serial::serialize, Error, Result}; use std::net::SocketAddr; use async_std::sync::Arc; use async_executor::Executor; pub struct BitcoinAddress { secret_key: SecretKey, - private_key: ecdsa::PrivateKey, - public_key: BitcoinPubKey, - pub_address: Address, + bitcoin_private_key: PrivateKey, + pub bitcoin_public_key: BitcoinPubKey, + pub pub_address: Address, } impl BitcoinAddress { pub fn new( - secret_key: SecretKey, + ) -> Result> { + let context = secp256k1::Secp256k1::new(); + + //Generate simple byte array + let mut data_slice = [0_u8; 64]; + thread_rng().fill(&mut data_slice[..]); + + let secret_key = SecretKey::from_slice(&hex::decode(&data_slice).unwrap()).unwrap(); + + //let public_key = PublicKey::from_secret_key(&context, &secret_key); + // Use mainnet - let private_key = PrivateKey::new(secret_key, Network::Bitcoin); + let bitcoin_private_key = PrivateKey::new(secret_key, Network::Bitcoin); - let public_key = BitcoinPubKey::from_private_key(private_key); + let bitcoin_public_key = BitcoinPubKey::from_private_key(&context, &bitcoin_private_key); - let pub_address = Address::p2sh(&public_key, Network::Bitcoin); + let pub_address = Address::p2pkh(&bitcoin_public_key, Network::Bitcoin); Ok(Arc::new(BitcoinAddress { secret_key, - private_key, - public_key, + bitcoin_private_key, + bitcoin_public_key, pub_address, })) } diff --git a/src/service/mod.rs b/src/service/mod.rs index 211a8b687..5669eec60 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -1,4 +1,7 @@ pub mod gateway; pub mod reqrep; +pub mod bitcoin_bridge; pub use gateway::{GatewayClient, GatewayService, GatewaySlabsSubscriber}; + +pub use bitcoin_bridge::{BitcoinAddress, CashierService}; From a96b7425fc27ebf18e2e7b00c5d4fceac4992a3f Mon Sep 17 00:00:00 2001 From: Janus Date: Mon, 12 Jul 2021 09:36:06 -0400 Subject: [PATCH 09/20] Add cashierd --- Cargo.lock | 2 +- Cargo.toml | 5 +++ src/bin/cashierd.rs | 79 +++++++++++++++++++++++++++++++++++ src/service/bitcoin_bridge.rs | 6 +-- 4 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 src/bin/cashierd.rs diff --git a/Cargo.lock b/Cargo.lock index 19eff76ab..84ddd6ccf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1016,8 +1016,8 @@ dependencies = [ "regex", "rocksdb", "rusqlite", - "serde", "secp256k1", + "serde", "serde_json", "sha2", "signal-hook", diff --git a/Cargo.toml b/Cargo.toml index 4d25fa4e6..3bef959ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -112,9 +112,14 @@ path = "src/bin/tx.rs" name = "gatewayd" path = "src/bin/gatewayd.rs" +[[bin]] +name = "cashierd" +path = "src/bin/cashierd.rs" + [[bin]] name = "darkfid" path = "src/bin/darkfid.rs" + [[bin]] name = "drk" path = "src/bin/drk.rs" diff --git a/src/bin/cashierd.rs b/src/bin/cashierd.rs new file mode 100644 index 000000000..6d9f793d7 --- /dev/null +++ b/src/bin/cashierd.rs @@ -0,0 +1,79 @@ +use std::net::SocketAddr; +use std::sync::Arc; + +use drk::cli::ServiceCli; +use drk::service::CashierService; +use drk::service::BitcoinAddress; +use drk::Result; + +use async_executor::Executor; +use easy_parallel::Parallel; + +fn setup_addr(address: Option, default: SocketAddr) -> SocketAddr { + match address { + Some(addr) => addr, + None => default, + } +} + +async fn start(executor: Arc>, options: ServiceCli) -> Result<()> { + let accept_addr: SocketAddr = setup_addr(options.accept_addr, "127.0.0.1:7777".parse()?); + //let pub_addr: SocketAddr = setup_addr(options.pub_addr, "127.0.0.1:8888".parse()?); + //let database_path = options.database_path.clone(); + + //let database_path = join_config_path(&(*database_path))?; + //let rocks = Rocks::new(&database_path)?; + //let rocks_slabstore_column = RocksColumn::::new(rocks); + + let cashier = CashierService::new(accept_addr)?; + + cashier.start(executor.clone()).await?; + Ok(()) +} + + +fn main() -> Result<()> { + + let btc = BitcoinAddress::new(); + + use simplelog::*; + + let ex = Arc::new(Executor::new()); + let (signal, shutdown) = async_channel::unbounded::<()>(); + + let options = ServiceCli::load()?; + + let logger_config = ConfigBuilder::new().set_time_format_str("%T%.6f").build(); + + let debug_level = if options.verbose { + LevelFilter::Debug + } else { + LevelFilter::Off + }; + + CombinedLogger::init(vec![ + TermLogger::new(debug_level, logger_config, TerminalMode::Mixed).unwrap(), + WriteLogger::new( + LevelFilter::Debug, + Config::default(), + std::fs::File::create(options.log_path.as_path()).unwrap(), + ), + ]) + .unwrap(); + + let ex2 = ex.clone(); + + let (_, result) = Parallel::new() + // Run four executor threads. + .each(0..3, |_| smol::future::block_on(ex.run(shutdown.recv()))) + // Run the main future on the current thread. + .finish(|| { + smol::future::block_on(async move { + start(ex2, options).await?; + drop(signal); + Ok::<(), drk::Error>(()) + }) + }); + + result +} diff --git a/src/service/bitcoin_bridge.rs b/src/service/bitcoin_bridge.rs index 3d6b85159..42b0403bf 100644 --- a/src/service/bitcoin_bridge.rs +++ b/src/service/bitcoin_bridge.rs @@ -46,22 +46,22 @@ impl BitcoinAddress { pub_address, })) } + // pub fn get_deposit_address(&self) -> BitcoinAddress::pub_address { + // &Self {pub_address} + // } } pub struct CashierService { addr: SocketAddr, - pub_addr: SocketAddr, } impl CashierService { pub fn new( addr: SocketAddr, - pub_addr: SocketAddr, )-> Result> { Ok(Arc::new(CashierService { addr, - pub_addr, })) } pub async fn start(self: Arc, executor: Arc>) -> Result<()> { From 19fb4c40f5d07cf0df56c3f52365ad2886510b9a Mon Sep 17 00:00:00 2001 From: Janus Date: Mon, 12 Jul 2021 10:52:50 -0400 Subject: [PATCH 10/20] Fix rand for secret_key --- src/service/bitcoin_bridge.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/service/bitcoin_bridge.rs b/src/service/bitcoin_bridge.rs index 42b0403bf..7eef791a4 100644 --- a/src/service/bitcoin_bridge.rs +++ b/src/service/bitcoin_bridge.rs @@ -1,4 +1,5 @@ use rand::{thread_rng, Rng}; +use rand::distributions::Alphanumeric; use secp256k1::key::{SecretKey, PublicKey}; use bitcoin::util::ecdsa::{PrivateKey, PublicKey as BitcoinPubKey}; use bitcoin::util::{address::Payload, address::Address}; @@ -24,11 +25,19 @@ impl BitcoinAddress { let context = secp256k1::Secp256k1::new(); - //Generate simple byte array - let mut data_slice = [0_u8; 64]; - thread_rng().fill(&mut data_slice[..]); - let secret_key = SecretKey::from_slice(&hex::decode(&data_slice).unwrap()).unwrap(); + let rand: String = thread_rng() + .sample_iter(&Alphanumeric) + .take(32) + .map(char::from) + .collect(); + + let rand_hex = hex::encode(rand); + + //Generate simple byte array from rand + let data_slice: &[u8] = rand_hex.as_bytes(); + + let secret_key = SecretKey::from_slice(&hex::decode(data_slice).unwrap()).unwrap(); //let public_key = PublicKey::from_secret_key(&context, &secret_key); From c3cda6acd778dfc21b61a14e1ab065ecb670ac57 Mon Sep 17 00:00:00 2001 From: Janus Date: Mon, 12 Jul 2021 11:10:19 -0400 Subject: [PATCH 11/20] Add comment --- src/service/bitcoin_bridge.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service/bitcoin_bridge.rs b/src/service/bitcoin_bridge.rs index 7eef791a4..84ee5ea92 100644 --- a/src/service/bitcoin_bridge.rs +++ b/src/service/bitcoin_bridge.rs @@ -12,6 +12,7 @@ use std::net::SocketAddr; use async_std::sync::Arc; use async_executor::Executor; +// Struct needs to attach to drk key stored in db pub struct BitcoinAddress { secret_key: SecretKey, bitcoin_private_key: PrivateKey, @@ -25,7 +26,6 @@ impl BitcoinAddress { let context = secp256k1::Secp256k1::new(); - let rand: String = thread_rng() .sample_iter(&Alphanumeric) .take(32) From a807faf4a4b9c8678490dfca6984d7ddc7079c5e Mon Sep 17 00:00:00 2001 From: Janus Date: Mon, 12 Jul 2021 13:36:22 -0400 Subject: [PATCH 12/20] Add method get_deposit_address --- src/bin/cashierd.rs | 4 +++- src/service/bitcoin_bridge.rs | 15 ++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/bin/cashierd.rs b/src/bin/cashierd.rs index 6d9f793d7..181d47e02 100644 --- a/src/bin/cashierd.rs +++ b/src/bin/cashierd.rs @@ -34,7 +34,9 @@ async fn start(executor: Arc>, options: ServiceCli) -> Result<()> { fn main() -> Result<()> { - let btc = BitcoinAddress::new(); + let btc = BitcoinAddress::new().unwrap(); + let deposit = btc.get_deposit_address(); + println!("{:?}", deposit); use simplelog::*; diff --git a/src/service/bitcoin_bridge.rs b/src/service/bitcoin_bridge.rs index 84ee5ea92..5436fabc2 100644 --- a/src/service/bitcoin_bridge.rs +++ b/src/service/bitcoin_bridge.rs @@ -12,7 +12,7 @@ use std::net::SocketAddr; use async_std::sync::Arc; use async_executor::Executor; -// Struct needs to attach to drk key stored in db +// Struct still needs to attach to drk key stored in db pub struct BitcoinAddress { secret_key: SecretKey, bitcoin_private_key: PrivateKey, @@ -22,10 +22,11 @@ pub struct BitcoinAddress { impl BitcoinAddress { pub fn new( - ) -> Result> { + ) -> Result { let context = secp256k1::Secp256k1::new(); + // Probably not good enough for release let rand: String = thread_rng() .sample_iter(&Alphanumeric) .take(32) @@ -48,16 +49,16 @@ impl BitcoinAddress { let pub_address = Address::p2pkh(&bitcoin_public_key, Network::Bitcoin); - Ok(Arc::new(BitcoinAddress { + Ok(BitcoinAddress { secret_key, bitcoin_private_key, bitcoin_public_key, pub_address, - })) + }) + } + pub fn get_deposit_address(&self) -> &Address { + &self.pub_address } - // pub fn get_deposit_address(&self) -> BitcoinAddress::pub_address { - // &Self {pub_address} - // } } pub struct CashierService { From 14e8a5a9408d16709c2a18a5540cf553240f2c39 Mon Sep 17 00:00:00 2001 From: Janus Date: Tue, 13 Jul 2021 00:14:04 -0400 Subject: [PATCH 13/20] Start zkpubkey -> btc addr exchange --- src/bin/cashierd.rs | 9 ++++++--- src/rpc/adapter.rs | 2 +- src/service/bitcoin_bridge.rs | 13 ++++++++----- src/service/mod.rs | 2 +- src/wallet/walletdb.rs | 2 +- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/bin/cashierd.rs b/src/bin/cashierd.rs index 181d47e02..4599c0f17 100644 --- a/src/bin/cashierd.rs +++ b/src/bin/cashierd.rs @@ -3,7 +3,8 @@ use std::sync::Arc; use drk::cli::ServiceCli; use drk::service::CashierService; -use drk::service::BitcoinAddress; +// Testing only +use drk::service::CashierKeys; use drk::Result; use async_executor::Executor; @@ -24,8 +25,10 @@ async fn start(executor: Arc>, options: ServiceCli) -> Result<()> { //let database_path = join_config_path(&(*database_path))?; //let rocks = Rocks::new(&database_path)?; //let rocks_slabstore_column = RocksColumn::::new(rocks); + // Use pw: PASSWORD for now + let cashier_wallet = Arc::new(WalletDB::new("cashier.db", "PASSWORD")?); - let cashier = CashierService::new(accept_addr)?; + let cashier = CashierService::new(accept_addr, cashier_wallet)?; cashier.start(executor.clone()).await?; Ok(()) @@ -34,7 +37,7 @@ async fn start(executor: Arc>, options: ServiceCli) -> Result<()> { fn main() -> Result<()> { - let btc = BitcoinAddress::new().unwrap(); + let btc = CashierKeys::new().unwrap(); let deposit = btc.get_deposit_address(); println!("{:?}", deposit); diff --git a/src/rpc/adapter.rs b/src/rpc/adapter.rs index 280f3f533..926c5259c 100644 --- a/src/rpc/adapter.rs +++ b/src/rpc/adapter.rs @@ -39,7 +39,7 @@ impl RpcAdapter { pub fn cash_key_gen(&self) -> Result<()> { debug!(target: "adapter", "key_gen() [START]"); - let (public, private) = self.wallet.key_gen(); + let (public, private) = self.wallet.cash_key_gen(); self.wallet.put_keypair(public, private)?; Ok(()) } diff --git a/src/service/bitcoin_bridge.rs b/src/service/bitcoin_bridge.rs index 5436fabc2..575c5ce2e 100644 --- a/src/service/bitcoin_bridge.rs +++ b/src/service/bitcoin_bridge.rs @@ -12,17 +12,19 @@ use std::net::SocketAddr; use async_std::sync::Arc; use async_executor::Executor; + // Struct still needs to attach to drk key stored in db -pub struct BitcoinAddress { +pub struct CashierKeys { + zk_pubkey: jubjub::SubgroupPoint, secret_key: SecretKey, bitcoin_private_key: PrivateKey, pub bitcoin_public_key: BitcoinPubKey, pub pub_address: Address, } -impl BitcoinAddress { +impl CashierKeys { pub fn new( - ) -> Result { + ) -> Result { let context = secp256k1::Secp256k1::new(); @@ -35,7 +37,7 @@ impl BitcoinAddress { let rand_hex = hex::encode(rand); - //Generate simple byte array from rand + // Generate simple byte array from rand let data_slice: &[u8] = rand_hex.as_bytes(); let secret_key = SecretKey::from_slice(&hex::decode(data_slice).unwrap()).unwrap(); @@ -49,7 +51,7 @@ impl BitcoinAddress { let pub_address = Address::p2pkh(&bitcoin_public_key, Network::Bitcoin); - Ok(BitcoinAddress { + Ok(Self { secret_key, bitcoin_private_key, bitcoin_public_key, @@ -63,6 +65,7 @@ impl BitcoinAddress { pub struct CashierService { addr: SocketAddr, + cashierstore: Arc, } impl CashierService { diff --git a/src/service/mod.rs b/src/service/mod.rs index 5669eec60..59e589735 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -4,4 +4,4 @@ pub mod bitcoin_bridge; pub use gateway::{GatewayClient, GatewayService, GatewaySlabsSubscriber}; -pub use bitcoin_bridge::{BitcoinAddress, CashierService}; +pub use bitcoin_bridge::{CashierKeys, CashierService}; diff --git a/src/wallet/walletdb.rs b/src/wallet/walletdb.rs index 0df7a724f..d43f4a14b 100644 --- a/src/wallet/walletdb.rs +++ b/src/wallet/walletdb.rs @@ -68,7 +68,7 @@ impl WalletDb { pub fn init_cashier_db(&self) -> Result<()> { let conn = Connection::open(&self.path)?; - debug!(target: "walletdb", "OPENED CONNECTION AT PATH {:?}", self.path); + debug!(target: "cashierdb", "OPENED CONNECTION AT PATH {:?}", self.path); let contents = include_str!("../../res/schema.sql"); conn.execute_batch(&contents)?; Ok(()) From b6fb3a486a9cca48fabdd377459b23d4e5457696 Mon Sep 17 00:00:00 2001 From: Janus Date: Tue, 13 Jul 2021 13:13:48 -0400 Subject: [PATCH 14/20] Add RocksColumn CashierKeys --- src/blockchain/rocks.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/blockchain/rocks.rs b/src/blockchain/rocks.rs index 54357d809..9c52ce43a 100644 --- a/src/blockchain/rocks.rs +++ b/src/blockchain/rocks.rs @@ -20,6 +20,7 @@ pub mod columns { pub struct Slabs; pub struct Nullifiers; pub struct MerkleRoots; + pub struct CashierKeys; } impl Column for columns::Slabs { @@ -33,7 +34,9 @@ impl Column for columns::Nullifiers { impl Column for columns::MerkleRoots { const NAME: &'static str = "merkleroots"; } - +impl Column for columns::CashierKeys { + const NAME: &'static str = "cashierkeys"; +} pub struct Rocks { db: DB, } @@ -52,9 +55,11 @@ impl Rocks { let nullifiers_cf = ColumnFamilyDescriptor::new(columns::Nullifiers::NAME, cf_opts.clone()); // merkleroots column family let merkleroots_cf = ColumnFamilyDescriptor::new(columns::MerkleRoots::NAME, cf_opts); + // cashierkeypair column family + let cashierkeys_cf = ColumnFamilyDescriptor::new(columns::CashierKeys::NAME, cf_opts); // column families - let cfs = vec![default_cf, slab_cf, nullifiers_cf, merkleroots_cf]; + let cfs = vec![default_cf, slab_cf, nullifiers_cf, merkleroots_cf, cashierkeys_cf]; // database options let mut opt = Options::default(); From 516f1f3be6acf07d4f7270db62f691053e0d4e6a Mon Sep 17 00:00:00 2001 From: Janus Date: Tue, 13 Jul 2021 14:04:02 -0400 Subject: [PATCH 15/20] Prepare db --- src/bin/cashierd.rs | 20 +++++------ src/blockchain/cashier_keypair.rs | 44 +++++++++++++++++++++++++ src/blockchain/cashierstore.rs | 55 +++++++++++++++++++++++++++++++ src/blockchain/mod.rs | 4 +++ src/blockchain/rocks.rs | 2 +- src/service/bitcoin_bridge.rs | 9 +++-- 6 files changed, 119 insertions(+), 15 deletions(-) create mode 100644 src/blockchain/cashier_keypair.rs create mode 100644 src/blockchain/cashierstore.rs diff --git a/src/bin/cashierd.rs b/src/bin/cashierd.rs index 4599c0f17..06407dc15 100644 --- a/src/bin/cashierd.rs +++ b/src/bin/cashierd.rs @@ -1,10 +1,11 @@ use std::net::SocketAddr; use std::sync::Arc; +use drk::blockchain::{rocks::columns, Rocks, RocksColumn}; use drk::cli::ServiceCli; use drk::service::CashierService; // Testing only -use drk::service::CashierKeys; +use drk::util::join_config_path; use drk::Result; use async_executor::Executor; @@ -20,15 +21,15 @@ fn setup_addr(address: Option, default: SocketAddr) -> SocketAddr { async fn start(executor: Arc>, options: ServiceCli) -> Result<()> { let accept_addr: SocketAddr = setup_addr(options.accept_addr, "127.0.0.1:7777".parse()?); //let pub_addr: SocketAddr = setup_addr(options.pub_addr, "127.0.0.1:8888".parse()?); - //let database_path = options.database_path.clone(); + let database_path = options.database_path.clone(); - //let database_path = join_config_path(&(*database_path))?; - //let rocks = Rocks::new(&database_path)?; - //let rocks_slabstore_column = RocksColumn::::new(rocks); + let database_path = join_config_path(&(*database_path))?; + let rocks = Rocks::new(&database_path)?; + let rocks_cashierstore_column = RocksColumn::::new(rocks); // Use pw: PASSWORD for now - let cashier_wallet = Arc::new(WalletDB::new("cashier.db", "PASSWORD")?); + //let cashier_wallet = Arc::new(WalletDB::new("cashier.db", "PASSWORD")?); - let cashier = CashierService::new(accept_addr, cashier_wallet)?; + let cashier = CashierService::new(accept_addr, rocks_cashierstore_column)?; cashier.start(executor.clone()).await?; Ok(()) @@ -36,11 +37,6 @@ async fn start(executor: Arc>, options: ServiceCli) -> Result<()> { fn main() -> Result<()> { - - let btc = CashierKeys::new().unwrap(); - let deposit = btc.get_deposit_address(); - println!("{:?}", deposit); - use simplelog::*; let ex = Arc::new(Executor::new()); diff --git a/src/blockchain/cashier_keypair.rs b/src/blockchain/cashier_keypair.rs new file mode 100644 index 000000000..2e08b6951 --- /dev/null +++ b/src/blockchain/cashier_keypair.rs @@ -0,0 +1,44 @@ +use crate::serial::{Decodable, Encodable}; +use crate::Result; + +#[derive(Clone, Debug)] +pub struct CashierKeypair { + zk_public: jubjub::SubgroupPoint, + payload: Vec, +} + +impl CashierKeypair { + pub fn new(zk_public: jubjub::SubgroupPoint, payload: Vec) -> Self { + CashierKeypair { zk_public, payload } + } + + pub fn set_index(&mut self, index: jubjub::SubgroupPoint) { + self.zk_public = index; + } + + pub fn get_index(&self) -> jubjub::SubgroupPoint { + self.zk_public + } + + pub fn get_payload(&self) -> Vec { + self.payload.clone() + } +} + +impl Encodable for CashierKeypair { + fn encode(&self, mut s: S) -> Result { + let mut len = 0; + len += self.zk_public.encode(&mut s)?; + len += self.payload.encode(&mut s)?; + Ok(len) + } +} + +impl Decodable for CashierKeypair { + fn decode(mut d: D) -> Result { + Ok(Self { + zk_public: Decodable::decode(&mut d)?, + payload: Decodable::decode(&mut d)?, + }) + } +} diff --git a/src/blockchain/cashierstore.rs b/src/blockchain/cashierstore.rs new file mode 100644 index 000000000..efb708ca8 --- /dev/null +++ b/src/blockchain/cashierstore.rs @@ -0,0 +1,55 @@ +use std::sync::Arc; + +use crate::serial::{deserialize, serialize}; +use crate::Result; + +use super::rocks::{columns, IteratorMode, RocksColumn}; +use super::cashier_keypair::CashierKeypair; + +pub struct CashierStore { + rocks: RocksColumn, +} + +impl CashierStore { + pub fn new(rocks: RocksColumn) -> Result> { + Ok(Arc::new(CashierStore { rocks })) + } + + pub fn get(&self, key: jubjub::SubgroupPoint) -> Result>> { + let value = self.rocks.get(key)?; + Ok(value) + } + + pub fn put(&self, keypair: CashierKeypair) -> Result> { + + let index = keypair.get_index(); + let check = self.get(index); + match self.get(index) { + Ok(_v) => Ok(None), + Err(_e) => { + self.rocks.put(index.clone(), keypair)?; + Ok(Some(index)) + }, + } + } + + pub fn get_value_deserialized(&self, key: Vec) -> Result> { + self.rocks.get_value_deserialized::(key) + } + // Fix this + // pub fn get_last_index(&self) -> Result { + // let last_index = self.rocks.iterator(IteratorMode::End)?.next(); + // match last_index { + // Some((index, _)) => Ok(deserialize(&index)?), + // None => Ok() + // } + // } + + pub fn get_last_index_as_bytes(&self) -> Result> { + let last_index = self.rocks.iterator(IteratorMode::End)?.next(); + match last_index { + Some((index, _)) => Ok(index.to_vec()), + None => Ok(serialize::(&0)), + } + } +} diff --git a/src/blockchain/mod.rs b/src/blockchain/mod.rs index afb35e3e2..dff76bd55 100644 --- a/src/blockchain/mod.rs +++ b/src/blockchain/mod.rs @@ -1,7 +1,11 @@ pub mod rocks; pub mod slab; pub mod slabstore; +pub mod cashier_keypair; +pub mod cashierstore; pub use rocks::{Rocks, RocksColumn}; pub use slab::Slab; pub use slabstore::SlabStore; +pub use cashier_keypair::CashierKeypair; +pub use cashierstore::CashierStore; diff --git a/src/blockchain/rocks.rs b/src/blockchain/rocks.rs index 9c52ce43a..87025101d 100644 --- a/src/blockchain/rocks.rs +++ b/src/blockchain/rocks.rs @@ -54,7 +54,7 @@ impl Rocks { // nullifiers column family let nullifiers_cf = ColumnFamilyDescriptor::new(columns::Nullifiers::NAME, cf_opts.clone()); // merkleroots column family - let merkleroots_cf = ColumnFamilyDescriptor::new(columns::MerkleRoots::NAME, cf_opts); + let merkleroots_cf = ColumnFamilyDescriptor::new(columns::MerkleRoots::NAME, cf_opts.clone()); // cashierkeypair column family let cashierkeys_cf = ColumnFamilyDescriptor::new(columns::CashierKeys::NAME, cf_opts); diff --git a/src/service/bitcoin_bridge.rs b/src/service/bitcoin_bridge.rs index 575c5ce2e..247ff47e6 100644 --- a/src/service/bitcoin_bridge.rs +++ b/src/service/bitcoin_bridge.rs @@ -7,15 +7,14 @@ use bitcoin::util::{address::Payload, address::Address}; use bitcoin::hash_types::PubkeyHash; use bitcoin::network::constants::Network; use super::reqrep::{PeerId, RepProtocol, Reply, ReqProtocol, Request}; +use crate::blockchain::{rocks::columns, RocksColumn, CashierKeypair, CashierStore}; use crate::{serial::deserialize, serial::serialize, Error, Result}; use std::net::SocketAddr; use async_std::sync::Arc; use async_executor::Executor; -// Struct still needs to attach to drk key stored in db pub struct CashierKeys { - zk_pubkey: jubjub::SubgroupPoint, secret_key: SecretKey, bitcoin_private_key: PrivateKey, pub bitcoin_public_key: BitcoinPubKey, @@ -71,9 +70,12 @@ pub struct CashierService { impl CashierService { pub fn new( addr: SocketAddr, + rocks: RocksColumn, )-> Result> { + let cashierstore = CashierStore::new(rocks)?; Ok(Arc::new(CashierService { + cashierstore, addr, })) } @@ -105,9 +107,11 @@ impl CashierService { loop { match recv_queue.recv().await { Ok(msg) => { + let cashierstore = self.cashierstore.clone(); let _ = executor .spawn(Self::handle_request( msg, + cashierstore, send_queue.clone(), )) .detach(); @@ -121,6 +125,7 @@ impl CashierService { } async fn handle_request( msg: (PeerId, Request), + cashierstore: Arc, send_queue: async_channel::Sender<(PeerId, Reply)>, ) -> Result<()> { let request = msg.1; From ce41e1d864b506715e2a524785d8d40f04da4de7 Mon Sep 17 00:00:00 2001 From: Janus Date: Wed, 14 Jul 2021 23:29:44 -0400 Subject: [PATCH 16/20] Initial Req client for cashier --- src/service/bitcoin_bridge.rs | 85 ++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/src/service/bitcoin_bridge.rs b/src/service/bitcoin_bridge.rs index 247ff47e6..0da04f0ac 100644 --- a/src/service/bitcoin_bridge.rs +++ b/src/service/bitcoin_bridge.rs @@ -132,14 +132,11 @@ impl CashierService { let peer = msg.0; match request.get_command() { 0 => { - + // Exchange zk_pubkey for bitcoin address } 1 => { - - } - 2 => { - + // Withdraw } _ => { return Err(Error::ServicesError("received wrong command")); @@ -148,3 +145,81 @@ impl CashierService { Ok(()) } } + +pub struct CashierClient { + protocol: ReqProtocol, + cashierstore: Arc, +} + +impl CashierClient { + pub fn new(addr: SocketAddr, rocks: RocksColumn) -> Result { + let protocol = ReqProtocol::new(addr, String::from("CASHIER CLIENT")); + + let cashierstore = CashierStore::new(rocks)?; + + Ok(CashierClient { + protocol, + cashierstore, + }) + } + + pub async fn start(&mut self) -> Result<()> { + self.protocol.start().await?; + self.sync().await?; + + Ok(()) + } + + pub async fn get_keys(&mut self, index: u64) -> Result> { + let rep = self + .protocol + .request( + //CashierCommand::GetKeys as u8, + serialize(&index), + &handle_error, + ) + .await?; + + if let Some(keys) = rep { + let keys: CashierKeys = deserialize(&keys)?; + //self.gateway_slabs_sub_s.send(slab.clone()).await?; + self.cashierstore.put(keys.clone())?; + return Ok(Some(keys)); + } + Ok(None) + } + + pub async fn put_keys(&mut self, mut keys: CashierKeys) -> Result<()> { + loop { + let last_index = self.sync().await?; + //keys.set_index(last_index + 1); + let keys = serialize(&keys); + + let rep = self + .protocol + .request(GatewayCommand::PutSlab as u8, slab.clone(), &handle_error) + .await?; + + if let Some(_) = rep { + break; + } + } + Ok(()) + } + + pub async fn get_last_index(&mut self) -> Result { + let rep = self + .protocol + .request(CashierCommand::GetLastIndex as u8, vec![], &handle_error) + .await?; + if let Some(index) = rep { + return Ok(deserialize(&index)?); + } + Ok(0) + } + + pub fn get_cashierstore(&self) -> Arc { + self.cashierstore.clone() + } + +} From ff341ead9aee7d415ed3fdbaad54c5aefb4a7039 Mon Sep 17 00:00:00 2001 From: Janus Date: Thu, 15 Jul 2021 15:01:06 -0500 Subject: [PATCH 17/20] Add proper messaging between CashierClient and CashierService --- src/service/bitcoin_bridge.rs | 87 ++++++++++++++++++++++------------- src/service/mod.rs | 2 +- 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/src/service/bitcoin_bridge.rs b/src/service/bitcoin_bridge.rs index 0da04f0ac..159d4727c 100644 --- a/src/service/bitcoin_bridge.rs +++ b/src/service/bitcoin_bridge.rs @@ -12,7 +12,19 @@ use crate::{serial::deserialize, serial::serialize, Error, Result}; use std::net::SocketAddr; use async_std::sync::Arc; use async_executor::Executor; +use log::*; +#[repr(u8)] +enum CashierError { + NoError, + UpdateIndex, +} + +#[repr(u8)] +enum CashierCommand { + GetDBTC, + GetBTC, +} pub struct CashierKeys { secret_key: SecretKey, @@ -133,6 +145,18 @@ impl CashierService { match request.get_command() { 0 => { // Exchange zk_pubkey for bitcoin address + let zkpub = request.get_payload(); + + // Generate bitcoin Address + let btc_keys = CashierKeys::new().unwrap(); + let deposit_address = btc_keys.get_deposit_address(); + + let mut reply = Reply::from(&request, CashierError::NoError as u32, vec![]); + //if let None = error { + // reply.set_error(CashierError::UpdateIndex as u32); + //} + // send reply + send_queue.send((peer, reply)).await?; } 1 => { @@ -165,23 +189,23 @@ impl CashierClient { pub async fn start(&mut self) -> Result<()> { self.protocol.start().await?; - self.sync().await?; + //self.sync().await?; Ok(()) } - pub async fn get_keys(&mut self, index: u64) -> Result> { + pub async fn get_keys(&mut self, index: jubjub::SubgroupPoint) -> Result> { let rep = self .protocol .request( - //CashierCommand::GetKeys as u8, + CashierCommand::GetDBTC as u8, serialize(&index), &handle_error, ) .await?; if let Some(keys) = rep { - let keys: CashierKeys = deserialize(&keys)?; + let keys: CashierKeypair = deserialize(&keys)?; //self.gateway_slabs_sub_s.send(slab.clone()).await?; self.cashierstore.put(keys.clone())?; return Ok(Some(keys)); @@ -189,37 +213,38 @@ impl CashierClient { Ok(None) } - pub async fn put_keys(&mut self, mut keys: CashierKeys) -> Result<()> { - loop { - let last_index = self.sync().await?; - //keys.set_index(last_index + 1); - let keys = serialize(&keys); + // pub async fn put_keys(&mut self, mut keys: CashierKeys) -> Result<()> { + // loop { + // let last_index = self.sync().await?; + // //keys.set_index(last_index + 1); + // let keys = serialize(&keys); - let rep = self - .protocol - .request(GatewayCommand::PutSlab as u8, slab.clone(), &handle_error) - .await?; + // let rep = self + // .protocol + // .request(CashierCommand::PutSlab as u8, slab.clone(), &handle_error) + // .await?; - if let Some(_) = rep { - break; - } - } - Ok(()) - } + // if let Some(_) = rep { + // break; + // } + // } + // Ok(()) + // } - pub async fn get_last_index(&mut self) -> Result { - let rep = self - .protocol - .request(CashierCommand::GetLastIndex as u8, vec![], &handle_error) - .await?; - if let Some(index) = rep { - return Ok(deserialize(&index)?); - } - Ok(0) - } - - pub fn get_cashierstore(&self) -> Arc { + pub fn get_cashierstore(&self) -> Arc { self.cashierstore.clone() } } + +fn handle_error(status_code: u32) { + match status_code { + 1 => { + warn!("Reply has an Error: Index is not updated"); + } + 2 => { + warn!("Reply has an Error: Index Not Exist"); + } + _ => {} + } +} diff --git a/src/service/mod.rs b/src/service/mod.rs index 59e589735..64e593676 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -4,4 +4,4 @@ pub mod bitcoin_bridge; pub use gateway::{GatewayClient, GatewayService, GatewaySlabsSubscriber}; -pub use bitcoin_bridge::{CashierKeys, CashierService}; +pub use bitcoin_bridge::{CashierKeys, CashierService, CashierClient}; From fded8de2700302b754cd99d1780a04e9470480ad Mon Sep 17 00:00:00 2001 From: Janus Date: Fri, 16 Jul 2021 00:34:43 -0400 Subject: [PATCH 18/20] Update cashierd to reflect new toml config options --- src/bin/cashierd.rs | 63 +++++++++++-- src/cli/client_cli/cli_config.rs | 146 +++++++++++++++++++++++++++++++ src/cli/mod.rs | 2 +- 3 files changed, 201 insertions(+), 10 deletions(-) create mode 100644 src/cli/client_cli/cli_config.rs diff --git a/src/bin/cashierd.rs b/src/bin/cashierd.rs index 06407dc15..ed8122435 100644 --- a/src/bin/cashierd.rs +++ b/src/bin/cashierd.rs @@ -1,10 +1,16 @@ use std::net::SocketAddr; +use std::str; use std::sync::Arc; +use std::fs::OpenOptions; +use std::io::Read; +use std::{fs, path::PathBuf}; +use toml; + use drk::blockchain::{rocks::columns, Rocks, RocksColumn}; -use drk::cli::ServiceCli; +use drk::cli::{ServiceCli, CashierdConfig}; use drk::service::CashierService; -// Testing only + use drk::util::join_config_path; use drk::Result; @@ -18,13 +24,15 @@ fn setup_addr(address: Option, default: SocketAddr) -> SocketAddr { } } -async fn start(executor: Arc>, options: ServiceCli) -> Result<()> { - let accept_addr: SocketAddr = setup_addr(options.accept_addr, "127.0.0.1:7777".parse()?); - //let pub_addr: SocketAddr = setup_addr(options.pub_addr, "127.0.0.1:8888".parse()?); - let database_path = options.database_path.clone(); +async fn start(executor: Arc>, config: Arc<&CashierdConfig>) -> Result<()> { + let accept_addr: SocketAddr = config.accept_url.parse()?; + + let database_path = config.database_path.clone(); + + let database_path = join_config_path(&PathBuf::from(database_path))?; - let database_path = join_config_path(&(*database_path))?; let rocks = Rocks::new(&database_path)?; + let rocks_cashierstore_column = RocksColumn::::new(rocks); // Use pw: PASSWORD for now //let cashier_wallet = Arc::new(WalletDB::new("cashier.db", "PASSWORD")?); @@ -35,6 +43,14 @@ async fn start(executor: Arc>, options: ServiceCli) -> Result<()> { Ok(()) } +fn set_default() -> Result { + let config_file = CashierdConfig { + accept_url: String::from("127.0.0.1:7777"), + database_path: String::from("cashierd.db"), + log_path: String::from("/tmp/cashierd.log"), + }; + Ok(config_file) +} fn main() -> Result<()> { use simplelog::*; @@ -42,6 +58,33 @@ fn main() -> Result<()> { let ex = Arc::new(Executor::new()); let (signal, shutdown) = async_channel::unbounded::<()>(); + let config_path = PathBuf::from("cashierd.toml"); + let path = join_config_path(&config_path).unwrap(); + + let mut file = OpenOptions::new() + .read(true) + .write(true) + .create(true) + .open(&path)?; + + let mut buffer: Vec = vec![]; + file.read_to_end(&mut buffer)?; + + if buffer.is_empty() { + // set the default setting + let config_file = set_default()?; + let config_file = toml::to_string(&config_file)?; + fs::write(&path, &config_file)?; + } + + // reload the config + let toml = fs::read(&path)?; + let str_buff = str::from_utf8(&toml)?; + + // read from config file + let config: CashierdConfig = toml::from_str(str_buff)?; + let config_pointer = Arc::new(&config); + let options = ServiceCli::load()?; let logger_config = ConfigBuilder::new().set_time_format_str("%T%.6f").build(); @@ -52,12 +95,14 @@ fn main() -> Result<()> { LevelFilter::Off }; + let log_path = config.log_path.clone(); + CombinedLogger::init(vec![ TermLogger::new(debug_level, logger_config, TerminalMode::Mixed).unwrap(), WriteLogger::new( LevelFilter::Debug, Config::default(), - std::fs::File::create(options.log_path.as_path()).unwrap(), + std::fs::File::create(log_path).unwrap(), ), ]) .unwrap(); @@ -70,7 +115,7 @@ fn main() -> Result<()> { // Run the main future on the current thread. .finish(|| { smol::future::block_on(async move { - start(ex2, options).await?; + start(ex2, config_pointer).await?; drop(signal); Ok::<(), drk::Error>(()) }) diff --git a/src/cli/client_cli/cli_config.rs b/src/cli/client_cli/cli_config.rs new file mode 100644 index 000000000..86d55bf2c --- /dev/null +++ b/src/cli/client_cli/cli_config.rs @@ -0,0 +1,146 @@ +//use crate::serial::{deserialize, serialize, Decodable, Encodable}; +//use toml::{map::Map, Value}; +use crate::util::join_config_path; +//use crate::Result; + +use serde::{Deserialize, Serialize}; +//use log::*; + +use std::{fs::OpenOptions, io::prelude::*, path::PathBuf}; + +//pub trait ClientConfig: Default + Deserialize { +// fn load(path: PathBuf) -> Result { +// let path = join_config_path(&path)?; +// let mut file = OpenOptions::new() +// .read(true) +// .write(true) +// .create(true) +// .open(path)?; +// +// //let mut toml_map = Map::new(); +// let mut buffer = String::new(); +// file.read_to_string(&mut buffer)?; +// //let buffer: &'static str = buffer; +// +// //let tomlstring = toml::to_string(&file).expect("Could not encode TTOML value"); +// if !buffer.is_empty() { +// let config: Self = toml::from_str(&buffer)?; +// //let config = toml::to_string(&buffer).unwrap(); +// //let config: Self = deserialize(&buffer)?; +// //Ok(config) +// Ok(config) +// } else { +// Ok(Self::default()) +// } +// } +// fn save(&self, path: PathBuf) -> Result<()> { +// //let path = join_config_path(&path)?; +// //let mut file = OpenOptions::new().write(true).create(true).open(&path)?; +// //let serialized = serialize(self); +// //file.write_all(&serialized)?; +// Ok(()) +// } +//} +// +//impl ClientConfig for DrkConfig {} +//impl ClientConfig for DarkfidConfig {} + +#[derive(Serialize, Default, Deserialize, Debug)] +pub struct DrkConfig { + #[serde(rename = "rpc_url")] + pub rpc_url: String, + + #[serde(rename = "log_path")] + pub log_path: String, +} + +#[derive(Serialize, Default, Deserialize, Debug)] +pub struct DarkfidConfig { + #[serde(rename = "connect_url")] + pub connect_url: String, + + #[serde(rename = "subscriber_url")] + pub subscriber_url: String, + + #[serde(rename = "rpc_url")] + pub rpc_url: String, + + #[serde(rename = "database_path")] + pub database_path: String, + + #[serde(rename = "log_path")] + pub log_path: String, + + #[serde(rename = "password")] + pub password: String, +} + + +#[derive(Serialize, Default, Deserialize, Debug)] +pub struct GatewaydConfig { + #[serde(rename = "connect_url")] + pub accept_url: String, + + #[serde(rename = "subscriber_url")] + pub publisher_url: String, + + #[serde(rename = "database_path")] + pub database_path: String, + + #[serde(rename = "log_path")] + pub log_path: String, +} +#[derive(Serialize, Default, Deserialize, Debug)] +pub struct CashierdConfig { + #[serde(rename = "connect_url")] + pub accept_url: String, + + #[serde(rename = "database_path")] + pub database_path: String, + + #[serde(rename = "log_path")] + pub log_path: String, +} +//impl Default for DrkCliConfig { +// // default toml file +// fn default() -> Self { +// let rpc_url = String::from("http://127.0.0.1:8000"); +// let log_path = String::from("/tmp/drk_cli.log"); +// Self { +// rpc_url, +// log_path, +// } +// } +//} + +//impl Default for DarkfidCliConfig { +// // create default config file +// fn default() -> Self { +// //toml::toml! { +// // connect-url = "127.0.0.1:3333" +// //}; +// let connect_url = String::from("127.0.0.1:3333"); +// let subscriber_url = String::from("127.0.0.1:4444"); +// let rpc_url = String::from("127.0.0.1:8000"); +// +// let database_path = String::from("database_client.db"); +// let database_path = join_config_path(&PathBuf::from(database_path)) +// .expect("error during join database_path to config path"); +// let database_path = String::from( +// database_path +// .to_str() +// .expect("error convert Path to String"), +// ); +// let log_path = String::from("/tmp/darkfid_service_daemon.log"); +// +// let password = String::new(); +// Self { +// connect_url, +// subscriber_url, +// rpc_url, +// database_path, +// log_path, +// password, +// } +// } +//} diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 68495ef84..7ef7be044 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -3,7 +3,7 @@ pub mod darkfid_cli; pub mod drk_cli; pub mod gatewayd_cli; -pub use cli_config::{DarkfidConfig, DrkConfig, GatewaydConfig}; +pub use cli_config::{DarkfidConfig, DrkConfig, CashierdConfig, GatewaydConfig}; pub use darkfid_cli::DarkfidCli; pub use drk_cli::DrkCli; pub use drk_cli::Transfer; From 878f3eb1dc4cbc9ed051885a2fdfe3edc9519b6e Mon Sep 17 00:00:00 2001 From: Janus Date: Mon, 19 Jul 2021 13:33:01 -0500 Subject: [PATCH 19/20] Update cashierd configs and options --- src/bin/cashierd.rs | 52 +++++++++-------------------------- src/cli/cashierd_cli.rs | 23 ++++++++++++++++ src/cli/cli_config.rs | 40 +++++++++++++++++++++++++++ src/cli/mod.rs | 2 ++ src/service/bitcoin_bridge.rs | 20 +++++++------- src/service/mod.rs | 2 +- 6 files changed, 89 insertions(+), 50 deletions(-) create mode 100644 src/cli/cashierd_cli.rs diff --git a/src/bin/cashierd.rs b/src/bin/cashierd.rs index ed8122435..62ca64fd2 100644 --- a/src/bin/cashierd.rs +++ b/src/bin/cashierd.rs @@ -4,11 +4,11 @@ use std::sync::Arc; use std::fs::OpenOptions; use std::io::Read; -use std::{fs, path::PathBuf}; +use std::{fs, path::Path, path::PathBuf}; use toml; use drk::blockchain::{rocks::columns, Rocks, RocksColumn}; -use drk::cli::{ServiceCli, CashierdConfig}; +use drk::cli::{CashierdCli, CashierdConfig}; use drk::service::CashierService; use drk::util::join_config_path; @@ -43,49 +43,23 @@ async fn start(executor: Arc>, config: Arc<&CashierdConfig>) -> Res Ok(()) } -fn set_default() -> Result { - let config_file = CashierdConfig { - accept_url: String::from("127.0.0.1:7777"), - database_path: String::from("cashierd.db"), - log_path: String::from("/tmp/cashierd.log"), - }; - Ok(config_file) -} - fn main() -> Result<()> { use simplelog::*; let ex = Arc::new(Executor::new()); let (signal, shutdown) = async_channel::unbounded::<()>(); - let config_path = PathBuf::from("cashierd.toml"); - let path = join_config_path(&config_path).unwrap(); + let path = join_config_path(&PathBuf::from("cashierd.toml")).unwrap(); - let mut file = OpenOptions::new() - .read(true) - .write(true) - .create(true) - .open(&path)?; + let config: CashierdConfig = if Path::new(&path).exists() { + CashierdConfig::load(path)? + } else { + CashierdConfig::load_default(path)? + }; - let mut buffer: Vec = vec![]; - file.read_to_end(&mut buffer)?; + let config_ptr = Arc::new(&config); - if buffer.is_empty() { - // set the default setting - let config_file = set_default()?; - let config_file = toml::to_string(&config_file)?; - fs::write(&path, &config_file)?; - } - - // reload the config - let toml = fs::read(&path)?; - let str_buff = str::from_utf8(&toml)?; - - // read from config file - let config: CashierdConfig = toml::from_str(str_buff)?; - let config_pointer = Arc::new(&config); - - let options = ServiceCli::load()?; + let options = CashierdCli::load()?; let logger_config = ConfigBuilder::new().set_time_format_str("%T%.6f").build(); @@ -96,7 +70,6 @@ fn main() -> Result<()> { }; let log_path = config.log_path.clone(); - CombinedLogger::init(vec![ TermLogger::new(debug_level, logger_config, TerminalMode::Mixed).unwrap(), WriteLogger::new( @@ -105,7 +78,8 @@ fn main() -> Result<()> { std::fs::File::create(log_path).unwrap(), ), ]) - .unwrap(); + .unwrap(); + let ex2 = ex.clone(); @@ -115,7 +89,7 @@ fn main() -> Result<()> { // Run the main future on the current thread. .finish(|| { smol::future::block_on(async move { - start(ex2, config_pointer).await?; + start(ex2, config_ptr).await?; drop(signal); Ok::<(), drk::Error>(()) }) diff --git a/src/cli/cashierd_cli.rs b/src/cli/cashierd_cli.rs new file mode 100644 index 000000000..e63a25460 --- /dev/null +++ b/src/cli/cashierd_cli.rs @@ -0,0 +1,23 @@ +use crate::Result; + +pub struct CashierdCli { + pub verbose: bool, +} + +impl CashierdCli { + pub fn load() -> Result { + let app = clap_app!(dfi => + (version: "0.1.0") + (author: "Amir Taaki ") + (about: "run service daemon") + (@arg VERBOSE: -v --verbose "Increase verbosity") + ) + .get_matches(); + + let verbose = app.is_present("VERBOSE"); + + Ok(Self { + verbose, + }) + } +} diff --git a/src/cli/cli_config.rs b/src/cli/cli_config.rs index e62974ec7..925f98f19 100644 --- a/src/cli/cli_config.rs +++ b/src/cli/cli_config.rs @@ -160,3 +160,43 @@ impl Default for GatewaydConfig { } } } + +#[derive(Serialize, Deserialize, Debug)] +pub struct CashierdConfig { + #[serde(default)] + #[serde(rename = "connect_url")] + pub accept_url: String, + + #[serde(default)] + #[serde(rename = "database_path")] + pub database_path: String, + + #[serde(default)] + #[serde(rename = "log_path")] + pub log_path: String, +} + +impl CashierdConfig { + pub fn load(path: PathBuf) -> Result { + let toml = fs::read(&path)?; + let str_buff = str::from_utf8(&toml)?; + let config: Self = toml::from_str(str_buff)?; + Ok(config) + } + pub fn load_default(path: PathBuf) -> Result { + let toml = Self::default(); + let config_file = toml::to_string(&toml)?; + fs::write(&path, &config_file)?; + let config = Self::load(path)?; + Ok(config) + } +} + +impl Default for CashierdConfig { + fn default() -> Self { + let accept_url = String::from("127.0.0.1:7777"); + let database_path = String::from("cashierd.db"); + let log_path = String::from("/tmp/cashierd.log"); + Self { accept_url, database_path, log_path } + } +} diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 7ef7be044..c564f5932 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -2,9 +2,11 @@ pub mod cli_config; pub mod darkfid_cli; pub mod drk_cli; pub mod gatewayd_cli; +pub mod cashierd_cli; pub use cli_config::{DarkfidConfig, DrkConfig, CashierdConfig, GatewaydConfig}; pub use darkfid_cli::DarkfidCli; pub use drk_cli::DrkCli; pub use drk_cli::Transfer; pub use gatewayd_cli::GatewaydCli; +pub use cashierd_cli::CashierdCli; diff --git a/src/service/bitcoin_bridge.rs b/src/service/bitcoin_bridge.rs index 159d4727c..5a55082c9 100644 --- a/src/service/bitcoin_bridge.rs +++ b/src/service/bitcoin_bridge.rs @@ -26,16 +26,16 @@ enum CashierCommand { GetBTC, } -pub struct CashierKeys { +pub struct BitcoinKeys { secret_key: SecretKey, bitcoin_private_key: PrivateKey, pub bitcoin_public_key: BitcoinPubKey, pub pub_address: Address, } -impl CashierKeys { +impl BitcoinKeys { pub fn new( - ) -> Result { + ) -> Result { let context = secp256k1::Secp256k1::new(); @@ -55,12 +55,12 @@ impl CashierKeys { //let public_key = PublicKey::from_secret_key(&context, &secret_key); - // Use mainnet - let bitcoin_private_key = PrivateKey::new(secret_key, Network::Bitcoin); + // Use Testnet + let bitcoin_private_key = PrivateKey::new(secret_key, Network::Testnet); let bitcoin_public_key = BitcoinPubKey::from_private_key(&context, &bitcoin_private_key); - let pub_address = Address::p2pkh(&bitcoin_public_key, Network::Bitcoin); + let pub_address = Address::p2pkh(&bitcoin_public_key, Network::Testnet); Ok(Self { secret_key, @@ -148,13 +148,13 @@ impl CashierService { let zkpub = request.get_payload(); // Generate bitcoin Address - let btc_keys = CashierKeys::new().unwrap(); + let btc_keys = BitcoinKeys::new().unwrap(); let deposit_address = btc_keys.get_deposit_address(); let mut reply = Reply::from(&request, CashierError::NoError as u32, vec![]); - //if let None = error { - // reply.set_error(CashierError::UpdateIndex as u32); - //} + // if let None = error { + // reply.set_error(CashierError::UpdateIndex as u32); + // } // send reply send_queue.send((peer, reply)).await?; diff --git a/src/service/mod.rs b/src/service/mod.rs index 64e593676..708c1341d 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -4,4 +4,4 @@ pub mod bitcoin_bridge; pub use gateway::{GatewayClient, GatewayService, GatewaySlabsSubscriber}; -pub use bitcoin_bridge::{CashierKeys, CashierService, CashierClient}; +pub use bitcoin_bridge::{BitcoinKeys, CashierService, CashierClient}; From 9c6c8d0e8270e1765c7c225e5432d00921918166 Mon Sep 17 00:00:00 2001 From: Janus Date: Tue, 20 Jul 2021 10:12:51 -0500 Subject: [PATCH 20/20] Add WalletDb to CashierService --- src/bin/cashierd.rs | 4 +++- src/cli/cli_config.rs | 7 ++++++- src/service/bitcoin_bridge.rs | 4 ++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/bin/cashierd.rs b/src/bin/cashierd.rs index 62ca64fd2..e85abfedb 100644 --- a/src/bin/cashierd.rs +++ b/src/bin/cashierd.rs @@ -9,6 +9,7 @@ use toml; use drk::blockchain::{rocks::columns, Rocks, RocksColumn}; use drk::cli::{CashierdCli, CashierdConfig}; +use drk::wallet::{WalletDb, WalletPtr}; use drk::service::CashierService; use drk::util::join_config_path; @@ -36,8 +37,9 @@ async fn start(executor: Arc>, config: Arc<&CashierdConfig>) -> Res let rocks_cashierstore_column = RocksColumn::::new(rocks); // Use pw: PASSWORD for now //let cashier_wallet = Arc::new(WalletDB::new("cashier.db", "PASSWORD")?); + let wallet = Arc::new(WalletDb::new("cashier.db", config.password.clone())?); - let cashier = CashierService::new(accept_addr, rocks_cashierstore_column)?; + let cashier = CashierService::new(accept_addr, rocks_cashierstore_column, wallet)?; cashier.start(executor.clone()).await?; Ok(()) diff --git a/src/cli/cli_config.rs b/src/cli/cli_config.rs index 925f98f19..27a27fcbd 100644 --- a/src/cli/cli_config.rs +++ b/src/cli/cli_config.rs @@ -174,6 +174,10 @@ pub struct CashierdConfig { #[serde(default)] #[serde(rename = "log_path")] pub log_path: String, + + #[serde(default)] + #[serde(rename = "password")] + pub password: String, } impl CashierdConfig { @@ -197,6 +201,7 @@ impl Default for CashierdConfig { let accept_url = String::from("127.0.0.1:7777"); let database_path = String::from("cashierd.db"); let log_path = String::from("/tmp/cashierd.log"); - Self { accept_url, database_path, log_path } + let password = String::new(); + Self { accept_url, database_path, log_path, password } } } diff --git a/src/service/bitcoin_bridge.rs b/src/service/bitcoin_bridge.rs index 5a55082c9..132ac33fa 100644 --- a/src/service/bitcoin_bridge.rs +++ b/src/service/bitcoin_bridge.rs @@ -9,6 +9,7 @@ use bitcoin::network::constants::Network; use super::reqrep::{PeerId, RepProtocol, Reply, ReqProtocol, Request}; use crate::blockchain::{rocks::columns, RocksColumn, CashierKeypair, CashierStore}; use crate::{serial::deserialize, serial::serialize, Error, Result}; +use crate::wallet::{WalletDb, WalletPtr}; use std::net::SocketAddr; use async_std::sync::Arc; use async_executor::Executor; @@ -77,18 +78,21 @@ impl BitcoinKeys { pub struct CashierService { addr: SocketAddr, cashierstore: Arc, + wallet: Arc, } impl CashierService { pub fn new( addr: SocketAddr, rocks: RocksColumn, + wallet: Arc, )-> Result> { let cashierstore = CashierStore::new(rocks)?; Ok(Arc::new(CashierService { cashierstore, addr, + wallet, })) } pub async fn start(self: Arc, executor: Arc>) -> Result<()> {