diff --git a/Cargo.lock b/Cargo.lock
index bde0c02..01ac7ed 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1572,7 +1572,7 @@ dependencies = [
[[package]]
name = "grin_wallet_api"
version = "5.1.0-alpha.1"
-source = "git+https://github.com/mimblewimble/grin-wallet#c424a0ed10b5b2565d9dbb5c222544ddd22c3167"
+source = "git+https://github.com/mimblewimble/grin-wallet?branch=master#cecb084753bb4cd545c11e4802f4e2f4b11b9213"
dependencies = [
"base64 0.12.3",
"chrono",
@@ -1596,7 +1596,7 @@ dependencies = [
[[package]]
name = "grin_wallet_config"
version = "5.1.0-alpha.1"
-source = "git+https://github.com/mimblewimble/grin-wallet#c424a0ed10b5b2565d9dbb5c222544ddd22c3167"
+source = "git+https://github.com/mimblewimble/grin-wallet?branch=master#cecb084753bb4cd545c11e4802f4e2f4b11b9213"
dependencies = [
"dirs",
"grin_wallet_util",
@@ -1609,7 +1609,7 @@ dependencies = [
[[package]]
name = "grin_wallet_impls"
version = "5.1.0-alpha.1"
-source = "git+https://github.com/mimblewimble/grin-wallet#c424a0ed10b5b2565d9dbb5c222544ddd22c3167"
+source = "git+https://github.com/mimblewimble/grin-wallet?branch=master#cecb084753bb4cd545c11e4802f4e2f4b11b9213"
dependencies = [
"base64 0.12.3",
"blake2-rfc",
@@ -1643,7 +1643,7 @@ dependencies = [
[[package]]
name = "grin_wallet_libwallet"
version = "5.1.0-alpha.1"
-source = "git+https://github.com/mimblewimble/grin-wallet#c424a0ed10b5b2565d9dbb5c222544ddd22c3167"
+source = "git+https://github.com/mimblewimble/grin-wallet?branch=master#cecb084753bb4cd545c11e4802f4e2f4b11b9213"
dependencies = [
"age",
"base64 0.9.3",
@@ -1676,7 +1676,7 @@ dependencies = [
[[package]]
name = "grin_wallet_util"
version = "5.1.0-alpha.1"
-source = "git+https://github.com/mimblewimble/grin-wallet#c424a0ed10b5b2565d9dbb5c222544ddd22c3167"
+source = "git+https://github.com/mimblewimble/grin-wallet?branch=master#cecb084753bb4cd545c11e4802f4e2f4b11b9213"
dependencies = [
"data-encoding",
"ed25519-dalek",
diff --git a/Cargo.toml b/Cargo.toml
index 2f9040f..761c92c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -35,6 +35,6 @@ grin_core = { git = "https://github.com/mimblewimble/grin", version = "5.2.0-alp
grin_chain = { git = "https://github.com/mimblewimble/grin", version = "5.2.0-alpha.1" }
grin_keychain = { git = "https://github.com/mimblewimble/grin", version = "5.2.0-alpha.1" }
grin_servers = { git = "https://github.com/mimblewimble/grin", version = "5.2.0-alpha.1" }
-grin_wallet_api = { git = "https://github.com/mimblewimble/grin-wallet", version = "5.1.0-alpha.1" }
-grin_wallet_impls = { git = "https://github.com/mimblewimble/grin-wallet", version = "5.1.0-alpha.1" }
-grin_wallet_libwallet = { git = "https://github.com/mimblewimble/grin-wallet", version = "5.1.0-alpha.1" }
\ No newline at end of file
+grin_wallet_api = { git = "https://github.com/mimblewimble/grin-wallet", branch = "master" }
+grin_wallet_impls = { git = "https://github.com/mimblewimble/grin-wallet", branch = "master" }
+grin_wallet_libwallet = { git = "https://github.com/mimblewimble/grin-wallet", branch = "master" }
\ No newline at end of file
diff --git a/README.md b/README.md
index 361d3c3..8db7fd4 100644
--- a/README.md
+++ b/README.md
@@ -11,12 +11,13 @@ The first CoinSwap server (n1) provides the `swap` API, publicly avai
**params:**
```
[{
- "comsig": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
- "msg": "00010203",
+ "comsig": "0835f4b8b9cd286c9e35475f575c3e4ae71ceb4ff36598504662627afd628a17d6ba7dedb1aa4c47f0fabad026b76fc86d06f3bef8d0621b8ac4601d4b1b98401586ca3374a401508f32049212478ae91cfa474dfaa5ef2c3dd559d5a292e02334",
"onion": {
- "commit": "0967593792bc958cd73848c0b948ecab2c6e996ab3c550d462fe41359e447b651f",
- "data": ["3719e5fba260c71a5a4bcf9d9caa58cd5dc49531388782fae7699c6fa6b30b09fe42"],
- "pubkey": "020dd38a220280f14515f6901a3a366cb7b87630814e4b68b3189a32df964961e5"
+ "commit": "099a8922343f242dd3da29935ba5bbc7e38bf68eccfb8c96aec87aec0535199139",
+ "data":[
+ "758bc7339edfe8a1f117ef2ef02de58b33d99e820ffd2c21a3d108f4cbdadfbcbc061b705fc351ae2fb34a855bb64180fe8b4913ea13b3bf826773e4b293166cdad1fdf59cadd7d33f73a8f3fc0f339a849f9c505c573d8cc2f006082d8f5bf2c2c84c18d5873a821d9f60bcdd44cf0566d04d761a1eda005cd19ab0b1c593da4656dd2a09322fe1d725f61e8855c927844ec9e80b9260a58012f7c519c5ca3d9b192ab1104d30ac09fb844bd7f692214e5cf0f6cdf1477c20708c2f3ecb098dce6be661907593918840b0fe8eb5043996dace45f2fb66e8f1e2a732035b4e6447b8904f313badebcba99f75c003e297d8dd815915f534dfa7ed416af0c415b60d2a0186752af6af33b781f31fdd3016aeee3bd2e47743fe2ce391b3354b9036b56ec38ed7539adafbc96bef1dbaf354a805b03ac0df7a0d32cff91716926bce68c8ccebb607340f2ffe09c08a9c9fd282ea19b33c69107ed5c54d4872eb0ed83c38d7e07606722069d7709fb914e1e02ea23323f3ae9252902dbfa6f15bd83a3f64587c9ae23aaf96b2a95e1341da12a6e423cf95375184752e10c1dd1a599db74ac0c3d74ec270c589f6a3bdd0877eb986d9a58a8548b917e22bfb93a4a06c36d7cad8d4a8791a8d1e1dc683429b440b136c43ad2f664dafc5156b808050a3c4d28771877d3f1d3a9daa2585eae259aaa64745c6cd260f577e538e27be3c985db41b7c456b63c5b18d7d17420a277d4abc04ae892ceb26940b09fb322445846c14898f5f59305490b1338c56384cd0c7bf5950a0a403aec4d2c2f5e2378b5eb7b1e7fcdbd8d6cc547f3b5a372b22e50e37d858bb197392a10fb9e6e292d6ed6bd8eab1fef7f2d069b6250a0e3e597ccf9a062e04b68821f5c57328ddab775d141147b71c1764c911bad03d8b88e2e62034bc899395514ecab4dec8ab341ba114f0a4e5d1dcfa182396c0e4826ddee187b07bb524dfeaa5297f7a5465f99eaaaa37f082c787b94811feb15b57d68369e6a7e3761d"
+ ],
+ "pubkey": "033946e6a495e7278027b38be3d500cfc23d3e0836f1b7e24513841437f316ccb0"
}
}]
```
diff --git a/src/config.rs b/src/config.rs
index 8da88bd..2369c88 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -15,7 +15,8 @@ use std::path::PathBuf;
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct ServerConfig {
pub key: SecretKey,
- pub addr: SocketAddr,
+ pub interval_s: u32,
+ pub addr: SocketAddr,
pub grin_node_url: SocketAddr,
pub wallet_owner_url: SocketAddr,
}
@@ -34,7 +35,6 @@ impl EncryptedServerKey {
password: &ZeroingString,
) -> Result {
let salt: [u8; 8] = thread_rng().gen();
- let nonce: [u8; 12] = thread_rng().gen();
let password = password.as_bytes();
let mut key = [0; 32];
ring::pbkdf2::derive(
@@ -49,6 +49,7 @@ impl EncryptedServerKey {
let unbound_key = aead::UnboundKey::new(&aead::CHACHA20_POLY1305, &key).unwrap();
let sealing_key: aead::LessSafeKey = aead::LessSafeKey::new(unbound_key);
+ let nonce: [u8; 12] = thread_rng().gen();
let aad = aead::Aad::from(&[]);
let _ = sealing_key.seal_in_place_append_tag(
aead::Nonce::assume_unique_for_key(nonce),
@@ -106,7 +107,8 @@ struct RawConfig {
pub encrypted_key: String,
pub salt: String,
pub nonce: String,
- pub addr: SocketAddr,
+ pub interval_s: u32,
+ pub addr: SocketAddr,
pub grin_node_url: SocketAddr,
pub wallet_owner_url: SocketAddr,
}
@@ -119,6 +121,7 @@ pub fn write_config(config_path: &PathBuf, server_config: &ServerConfig, passwo
encrypted_key: encrypted.encrypted_key,
salt: encrypted.salt,
nonce: encrypted.nonce,
+ interval_s: server_config.interval_s,
addr: server_config.addr,
grin_node_url: server_config.grin_node_url,
wallet_owner_url: server_config.wallet_owner_url,
@@ -146,6 +149,7 @@ pub fn load_config(config_path: &PathBuf, password: &ZeroingString) -> Result = std::result::Result;
+pub type StdResult = std::result::Result;
#[derive(Clone, Debug, Eq, Fail, PartialEq)]
/// MWixnet error types
pub enum ErrorKind {
- /// Unsupported payload version
- #[fail(display = "Unsupported Payload Version")]
- UnsupportedPayload,
/// Error from secp256k1-zkp library
#[fail(display = "Secp Error")]
SecpError,
@@ -29,23 +27,9 @@ pub enum ErrorKind {
String,
io::ErrorKind,
),
- /// Expected a given value that wasn't found
- #[fail(display = "UnexpectedData")]
- UnexpectedData {
- /// What we wanted
- expected: Vec,
- /// What we got
- received: Vec,
- },
/// Data wasn't in a consumable format
#[fail(display = "CorruptedData")]
CorruptedData,
- /// Incorrect number of elements (when deserializing a vec via read_multi say).
- #[fail(display = "CountError")]
- CountError,
- /// When asked to read too much data
- #[fail(display = "TooLargeReadErr")]
- TooLargeReadErr,
/// Error from grin's api crate
#[fail(display = "GRIN API Error")]
GrinApiError,
@@ -85,6 +69,14 @@ impl From for Error {
}
}
+impl From for Error {
+ fn from(_e: grin_core::ser::Error) -> Error {
+ Error {
+ inner: Context::new(ErrorKind::GrinCoreError),
+ }
+ }
+}
+
impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(&self.inner, f)
@@ -98,10 +90,6 @@ impl Error {
}
}
- pub fn kind(&self) -> ErrorKind {
- self.inner.get_context().clone()
- }
-
pub fn message(&self) -> String {
format!("{}", self).into()
}
diff --git a/src/main.rs b/src/main.rs
index 796c5b6..4704a92 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,11 +1,13 @@
use config::ServerConfig;
use error::{Error, ErrorKind};
-use wallet::Wallet;
+use node::HttpGrinNode;
+use wallet::HttpWallet;
use clap::App;
-use grin_util::ZeroingString;
+use grin_util::{StopState, ZeroingString};
use std::env;
use std::path::PathBuf;
+use std::sync::Arc;
#[macro_use]
extern crate lazy_static;
@@ -18,11 +20,12 @@ mod error;
mod node;
mod onion;
mod secp;
-mod ser;
mod server;
mod types;
mod wallet;
+const DEFAULT_INTERVAL: u32 = 12 * 60 * 60;
+
fn main() -> std::result::Result<(), Box> {
let yml = load_yaml!("../mwixnet.yml");
let args = App::from_yaml(yml).get_matches();
@@ -38,6 +41,7 @@ fn main() -> std::result::Result<(), Box> {
let password = args.value_of("pass").ok_or(Error::new(ErrorKind::LoadConfigError))?;
let password = ZeroingString::from(password);
+ let round_time = args.value_of("round_time").map(|t| t.parse::().unwrap() );
let bind_addr = args.value_of("bind_addr");
let grin_node_url = args.value_of("grin_node_url");
let wallet_owner_url = args.value_of("wallet_owner_url");
@@ -50,6 +54,7 @@ fn main() -> std::result::Result<(), Box> {
let server_config = ServerConfig {
key: secp::random_secret(),
+ interval_s: round_time.unwrap_or(DEFAULT_INTERVAL),
addr: bind_addr.unwrap_or("0.0.0.0:3000").parse()?,
grin_node_url: grin_node_url.unwrap_or("127.0.0.1:3413").parse()?,
wallet_owner_url: wallet_owner_url.unwrap_or("127.0.0.1:3420").parse()?,
@@ -79,13 +84,24 @@ fn main() -> std::result::Result<(), Box> {
// Open wallet
let wallet_pass = args.value_of("wallet_pass").ok_or(error::Error::new(error::ErrorKind::LoadConfigError))?;
let wallet_pass = grin_util::ZeroingString::from(wallet_pass);
- let wallet = Wallet::open_wallet(&server_config.wallet_owner_url, &wallet_pass)?;
+ let wallet = HttpWallet::open_wallet(&server_config.wallet_owner_url, &wallet_pass)?;
- let shutdown_signal = async move {
- // Wait for the CTRL+C signal
- tokio::signal::ctrl_c()
- .await
- .expect("failed to install CTRL+C signal handler");
- };
- server::listen(&server_config, &wallet, shutdown_signal)
+ // Create GrinNode
+ let node = HttpGrinNode::new(&server_config.grin_node_url, &None);
+
+ let stop_state = Arc::new(StopState::new());
+
+ let stop_state_clone = stop_state.clone();
+ std::thread::spawn(move || {
+ let shutdown_signal = async move {
+ // Wait for the CTRL+C signal
+ tokio::signal::ctrl_c()
+ .await
+ .expect("failed to install CTRL+C signal handler");
+ };
+ futures::executor::block_on(shutdown_signal);
+ stop_state_clone.stop();
+ });
+
+ server::listen(&server_config, Arc::new(wallet), Arc::new(node), &stop_state)
}
\ No newline at end of file
diff --git a/src/node.rs b/src/node.rs
index 5849263..fa02cc4 100644
--- a/src/node.rs
+++ b/src/node.rs
@@ -1,31 +1,85 @@
-use crate::config::ServerConfig;
use crate::error::{ErrorKind, Result};
use crate::secp::Commitment;
use grin_api::client;
use grin_api::json_rpc::{build_request, Request, Response};
-use grin_api::{BlockPrintable, LocatedTxKernel, OutputPrintable, OutputType, Tip};
+use grin_api::{OutputPrintable, OutputType, Tip};
use grin_core::consensus::COINBASE_MATURITY;
use grin_core::core::{Input, OutputFeatures, Transaction};
use grin_util::ToHex;
use serde_json::json;
+use std::collections::HashMap;
use std::net::SocketAddr;
+use std::sync::{Arc, RwLock};
-const ENDPOINT: &str = "/v2/foreign";
+pub trait GrinNode : Send + Sync {
+ /// Retrieves the unspent output with a matching commitment
+ fn get_utxo(&self, output_commit: &Commitment) -> Result