V2 slate versioning enablement (#85)

* fix for command line listener port override

* reduce parameter query size

* Add slate versioning

* rustfmt

* bump version number

* Add tests for slate version conversion

* rustfmt

* Updates and test addition based on bdap's review

* rustfmt
This commit is contained in:
Yeastplume
2019-04-23 11:29:59 +01:00
committed by GitHub
parent 54bd364f06
commit 47ee03cadd
17 changed files with 3787 additions and 278 deletions
Generated
+222 -221
View File
File diff suppressed because it is too large Load Diff
+7 -7
View File
@@ -1,6 +1,6 @@
[package]
name = "grin_wallet"
version = "1.1.0-beta.1"
version = "1.1.0-beta.2"
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
description = "Simple, private and scalable cryptocurrency implementation based on the MimbleWimble chain format."
license = "Apache-2.0"
@@ -29,13 +29,13 @@ prettytable-rs = "0.7"
log = "0.4"
linefeed = "0.5"
grin_wallet_api = { path = "./api", version = "1.1.0-beta.1" }
grin_wallet_impls = { path = "./impls", version = "1.1.0-beta.1" }
grin_wallet_libwallet = { path = "./libwallet", version = "1.1.0-beta.1" }
grin_wallet_controller = { path = "./controller", version = "1.1.0-beta.1" }
grin_wallet_config = { path = "./config", version = "1.1.0-beta.1" }
grin_wallet_api = { path = "./api", version = "1.1.0-beta.2" }
grin_wallet_impls = { path = "./impls", version = "1.1.0-beta.2" }
grin_wallet_libwallet = { path = "./libwallet", version = "1.1.0-beta.2" }
grin_wallet_controller = { path = "./controller", version = "1.1.0-beta.2" }
grin_wallet_config = { path = "./config", version = "1.1.0-beta.2" }
grin_wallet_util = { path = "./util", version = "1.1.0-beta.1" }
grin_wallet_util = { path = "./util", version = "1.1.0-beta.2" }
[build-dependencies]
built = "0.3"
+5 -5
View File
@@ -1,6 +1,6 @@
[package]
name = "grin_wallet_api"
version = "1.1.0-beta.1"
version = "1.1.0-beta.2"
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
description = "Grin Wallet API"
license = "Apache-2.0"
@@ -18,11 +18,11 @@ serde_json = "1"
easy-jsonrpc = "0.4.1"
chrono = { version = "0.4.4", features = ["serde"] }
grin_wallet_libwallet = { path = "../libwallet", version = "1.1.0-beta.1" }
grin_wallet_config = { path = "../config", version = "1.1.0-beta.1" }
grin_wallet_impls = { path = "../impls", version = "1.1.0-beta.1" }
grin_wallet_libwallet = { path = "../libwallet", version = "1.1.0-beta.2" }
grin_wallet_config = { path = "../config", version = "1.1.0-beta.2" }
grin_wallet_impls = { path = "../impls", version = "1.1.0-beta.2" }
grin_wallet_util = { path = "../util", version = "1.1.0-beta.1" }
grin_wallet_util = { path = "../util", version = "1.1.0-beta.2" }
[dev-dependencies]
serde_json = "1"
+9 -6
View File
@@ -15,9 +15,9 @@
//! JSON-RPC Stub generation for the Foreign API
use crate::keychain::Keychain;
use crate::libwallet::slate::Slate;
use crate::libwallet::types::{BlockFees, CbData, InitTxArgs, NodeClient, WalletBackend};
use crate::libwallet::ErrorKind;
use crate::libwallet::{Slate, VersionedSlate};
use crate::Foreign;
use easy_jsonrpc;
@@ -310,10 +310,10 @@ pub trait ForeignRpc {
*/
fn receive_tx(
&self,
slate: Slate,
slate: VersionedSlate,
dest_acct_name: Option<String>,
message: Option<String>,
) -> Result<Slate, ErrorKind>;
) -> Result<VersionedSlate, ErrorKind>;
}
impl<W: ?Sized, C, K> ForeignRpc for Foreign<W, C, K>
@@ -332,10 +332,12 @@ where
fn receive_tx(
&self,
slate: Slate,
slate: VersionedSlate,
dest_acct_name: Option<String>,
message: Option<String>,
) -> Result<Slate, ErrorKind> {
) -> Result<VersionedSlate, ErrorKind> {
let version = slate.version();
let slate: Slate = slate.into();
let slate = Foreign::receive_tx(
self,
&slate,
@@ -343,7 +345,8 @@ where
message,
)
.map_err(|e| e.kind())?;
Ok(slate)
Ok(VersionedSlate::into_version(slate, version))
}
}
+1
View File
@@ -43,5 +43,6 @@ pub use crate::foreign_rpc::ForeignRpc;
pub use crate::owner::Owner;
pub use crate::owner_rpc::OwnerRpc;
pub use crate::foreign_rpc::foreign_rpc as foreign_rpc_client;
pub use crate::foreign_rpc::run_doctest_foreign;
pub use crate::owner_rpc::run_doctest_owner;
+131
View File
@@ -0,0 +1,131 @@
// Copyright 2019 The Grin Developers
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! core::libtx specific tests
use grin_wallet_api::foreign_rpc_client;
use grin_wallet_api::run_doctest_foreign;
use grin_wallet_libwallet::{Slate, SlateVersion, VersionedSlate};
use serde_json;
use serde_json::Value;
use tempfile::tempdir;
//use grin_wallet_libwallet::slate_versions::v1::SlateV1;
//use grin_wallet_libwallet::slate_versions::v2::SlateV2;
// test all slate conversions
#[test]
fn receive_versioned_slate() {
// as in doctests, except exercising versioning functionality
// by accepting and responding with a V1 slate
let dir = tempdir().map_err(|e| format!("{:#?}", e)).unwrap();
let dir = dir
.path()
.to_str()
.ok_or("Failed to convert tmpdir path to string.".to_owned())
.unwrap();
let v1_req = include_str!("slates/v1_req.slate");
let v1_resp = include_str!("slates/v1_res.slate");
// leave here for the ability to create earlier slate versions
// for test input
/*let v: Value = serde_json::from_str(v1_req).unwrap();
let v2_slate = v["params"][0].clone();
println!("{}", v2_slate);
let v2_slate_str = v2_slate.to_string();
println!("{}", v2_slate_str);
let v2: SlateV2 = serde_json::from_str(&v2_slate.to_string()).unwrap();
let v1 = SlateV1::from(v2);
let v1_str = serde_json::to_string_pretty(&v1).unwrap();
panic!("{}", v1_str);*/
let request_val: Value = serde_json::from_str(v1_req).unwrap();
let expected_response: Value = serde_json::from_str(v1_resp).unwrap();
let response = run_doctest_foreign(request_val, dir, 5, true)
.unwrap()
.unwrap();
if response != expected_response {
panic!(
"(left != right) \nleft: {}\nright: {}",
serde_json::to_string_pretty(&response).unwrap(),
serde_json::to_string_pretty(&expected_response).unwrap()
);
}
}
/// call ForeignRpc::receive_tx on vs and return the result
fn receive_tx(vs: VersionedSlate) -> VersionedSlate {
let dir = tempdir().map_err(|e| format!("{:#?}", e)).unwrap();
let dir = dir
.path()
.to_str()
.ok_or("Failed to convert tmpdir path to string.".to_owned())
.unwrap();
let bound_method = foreign_rpc_client::receive_tx(
vs,
None,
Some("Thanks for saving my dog from that tree, bddap.".into()),
)
.unwrap();
let (call, tracker) = bound_method.call();
let json_response = run_doctest_foreign(call.as_request(), dir, 5, false)
.unwrap()
.unwrap();
let mut response = easy_jsonrpc::Response::from_json_response(json_response).unwrap();
tracker.get_return(&mut response).unwrap().unwrap()
}
#[test]
fn version_unchanged() {
let req: Value = serde_json::from_str(include_str!("slates/v1_req.slate")).unwrap();
let slate: VersionedSlate = serde_json::from_value(req["params"][0].clone()).unwrap();
let slate_req: Slate = slate.into();
assert_eq!(
receive_tx(VersionedSlate::into_version(
slate_req.clone(),
SlateVersion::V0
))
.version(),
SlateVersion::V0
);
assert_eq!(
receive_tx(VersionedSlate::into_version(
slate_req.clone(),
SlateVersion::V1
))
.version(),
SlateVersion::V1
);
assert_eq!(
receive_tx(VersionedSlate::into_version(
slate_req.clone(),
SlateVersion::V2
))
.version(),
SlateVersion::V2
);
// compile time test will remind us to update these tests when updating slate format
fn _all_versions_tested(vs: VersionedSlate) {
match vs {
VersionedSlate::V0(_) => (),
VersionedSlate::V1(_) => (),
VersionedSlate::V2(_) => (),
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "grin_wallet_config"
version = "1.1.0-beta.1"
version = "1.1.0-beta.2"
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
description = "Configuration for grin wallet , a simple, private and scalable cryptocurrency implementation based on the MimbleWimble chain format."
license = "Apache-2.0"
@@ -16,7 +16,7 @@ serde_derive = "1"
toml = "0.4"
dirs = "1.0.3"
grin_wallet_util = { path = "../util", version = "1.1.0-beta.1" }
grin_wallet_util = { path = "../util", version = "1.1.0-beta.2" }
[dev-dependencies]
pretty_assertions = "0.5.1"
+6 -6
View File
@@ -1,6 +1,6 @@
[package]
name = "grin_wallet_controller"
version = "1.1.0-beta.1"
version = "1.1.0-beta.2"
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
description = "Controllers for grin wallet instantiation"
license = "Apache-2.0"
@@ -32,9 +32,9 @@ chrono = { version = "0.4.4", features = ["serde"] }
easy-jsonrpc = "0.4.1"
lazy_static = "1"
grin_wallet_util = { path = "../util", version = "1.1.0-beta.1" }
grin_wallet_util = { path = "../util", version = "1.1.0-beta.2" }
grin_wallet_api = { path = "../api", version = "1.1.0-beta.1" }
grin_wallet_impls = { path = "../impls", version = "1.1.0-beta.1" }
grin_wallet_libwallet = { path = "../libwallet", version = "1.1.0-beta.1" }
grin_wallet_config = { path = "../config", version = "1.1.0-beta.1" }
grin_wallet_api = { path = "../api", version = "1.1.0-beta.2" }
grin_wallet_impls = { path = "../impls", version = "1.1.0-beta.2" }
grin_wallet_libwallet = { path = "../libwallet", version = "1.1.0-beta.2" }
grin_wallet_config = { path = "../config", version = "1.1.0-beta.2" }
+4 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "grin_wallet_impls"
version = "1.1.0-beta.1"
version = "1.1.0-beta.2"
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
description = "Concrete types derived from libwallet traits"
license = "Apache-2.0"
@@ -26,7 +26,7 @@ tokio-retry = "0.1"
uuid = { version = "0.7", features = ["serde", "v4"] }
chrono = { version = "0.4.4", features = ["serde"] }
grin_wallet_util = { path = "../util", version = "1.1.0-beta.1" }
grin_wallet_util = { path = "../util", version = "1.1.0-beta.2" }
grin_wallet_libwallet = { path = "../libwallet", version = "1.1.0-beta.1" }
grin_wallet_config = { path = "../config", version = "1.1.0-beta.1" }
grin_wallet_libwallet = { path = "../libwallet", version = "1.1.0-beta.2" }
grin_wallet_config = { path = "../config", version = "1.1.0-beta.2" }
+3
View File
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//TODO: Update to V2 API when after Hard fork
/// HTTP Wallet 'plugin' implementation
use crate::api;
use crate::libwallet::slate::Slate;
@@ -48,6 +50,7 @@ impl WalletCommAdapter for HTTPWalletCommAdapter {
}
let url = format!("{}/v1/wallet/foreign/receive_tx", dest);
debug!("Posting transaction slate to {}", url);
//TODO: Use VersionedSlate when converting to V2 API
let slate = slate.serialize_to_version(Some(slate.version_info.orig_version))?;
// For compatibility with older clients
let res: Slate = {
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "grin_wallet_libwallet"
version = "1.1.0-beta.1"
version = "1.1.0-beta.2"
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
description = "Simple, private and scalable cryptocurrency implementation based on the MimbleWimble chain format."
license = "Apache-2.0"
@@ -23,7 +23,7 @@ uuid = { version = "0.7", features = ["serde", "v4"] }
chrono = { version = "0.4.4", features = ["serde"] }
lazy_static = "1"
grin_wallet_util = { path = "../util", version = "1.1.0-beta.1" }
grin_wallet_util = { path = "../util", version = "1.1.0-beta.2" }
[dev-dependencies]
grin_wallet_config = { path = "../config", version = "1.1.0-beta.1" }
grin_wallet_config = { path = "../config", version = "1.1.0-beta.2" }
+2
View File
@@ -47,4 +47,6 @@ pub mod slate_versions;
pub mod types;
pub use crate::error::{Error, ErrorKind};
pub use crate::slate::Slate;
pub use crate::slate_versions::{SlateVersion, VersionedSlate};
pub use internal::restore::{check_repair, restore};
+298 -5
View File
@@ -20,10 +20,12 @@ use crate::error::{Error, ErrorKind};
use crate::grin_core::core::amount_to_hr_string;
use crate::grin_core::core::committed::Committed;
use crate::grin_core::core::transaction::{
kernel_features, kernel_sig_msg, Transaction, Weighting,
kernel_features, kernel_sig_msg, Input, Output, Transaction, TransactionBody, TxKernel,
Weighting,
};
use crate::grin_core::core::verifier_cache::LruVerifierCache;
use crate::grin_core::libtx::{aggsig, build, secp_ser, tx_fee};
use crate::grin_core::map_vec;
use crate::grin_keychain::{BlindSum, BlindingFactor, Keychain};
use crate::grin_util::secp;
use crate::grin_util::secp::key::{PublicKey, SecretKey};
@@ -38,12 +40,13 @@ use uuid::Uuid;
use crate::slate_versions::v0::SlateV0;
use crate::slate_versions::v1::SlateV1;
use crate::slate_versions::v2::SlateV2;
const CURRENT_SLATE_VERSION: u16 = 2;
use crate::slate_versions::v2::{
InputV2, OutputV2, ParticipantDataV2, SlateV2, TransactionBodyV2, TransactionV2, TxKernelV2,
VersionCompatInfoV2,
};
use crate::slate_versions::CURRENT_SLATE_VERSION;
/// Public data for each participant in the slate
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ParticipantData {
/// Id of participant in the transaction. (For now, 0=sender, 1=rec)
@@ -661,3 +664,293 @@ impl Slate {
Ok(())
}
}
// Current slate version to versioned conversions
// Slate to versioned
impl From<Slate> for SlateV2 {
fn from(slate: Slate) -> SlateV2 {
let Slate {
num_participants,
id,
tx,
amount,
fee,
height,
lock_height,
participant_data,
version_info,
} = slate;
let participant_data = map_vec!(participant_data, |data| ParticipantDataV2::from(data));
let version_info = VersionCompatInfoV2::from(&version_info);
let tx = TransactionV2::from(tx);
SlateV2 {
num_participants,
id,
tx,
amount,
fee,
height,
lock_height,
participant_data,
version_info,
}
}
}
impl From<&ParticipantData> for ParticipantDataV2 {
fn from(data: &ParticipantData) -> ParticipantDataV2 {
let ParticipantData {
id,
public_blind_excess,
public_nonce,
part_sig,
message,
message_sig,
} = data;
let id = *id;
let public_blind_excess = *public_blind_excess;
let public_nonce = *public_nonce;
let part_sig = *part_sig;
let message: Option<String> = message.as_ref().map(|t| String::from(&**t));
let message_sig = *message_sig;
ParticipantDataV2 {
id,
public_blind_excess,
public_nonce,
part_sig,
message,
message_sig,
}
}
}
impl From<&VersionCompatInfo> for VersionCompatInfoV2 {
fn from(data: &VersionCompatInfo) -> VersionCompatInfoV2 {
let VersionCompatInfo {
version,
orig_version,
min_compat_version,
} = data;
let version = *version;
let orig_version = *orig_version;
let min_compat_version = *min_compat_version;
VersionCompatInfoV2 {
version,
orig_version,
min_compat_version,
}
}
}
impl From<Transaction> for TransactionV2 {
fn from(tx: Transaction) -> TransactionV2 {
let Transaction { offset, body } = tx;
let body = TransactionBodyV2::from(&body);
TransactionV2 { offset, body }
}
}
impl From<&TransactionBody> for TransactionBodyV2 {
fn from(body: &TransactionBody) -> TransactionBodyV2 {
let TransactionBody {
inputs,
outputs,
kernels,
} = body;
let inputs = map_vec!(inputs, |inp| InputV2::from(inp));
let outputs = map_vec!(outputs, |out| OutputV2::from(out));
let kernels = map_vec!(kernels, |kern| TxKernelV2::from(kern));
TransactionBodyV2 {
inputs,
outputs,
kernels,
}
}
}
impl From<&Input> for InputV2 {
fn from(input: &Input) -> InputV2 {
let Input { features, commit } = *input;
InputV2 { features, commit }
}
}
impl From<&Output> for OutputV2 {
fn from(output: &Output) -> OutputV2 {
let Output {
features,
commit,
proof,
} = *output;
OutputV2 {
features,
commit,
proof,
}
}
}
impl From<&TxKernel> for TxKernelV2 {
fn from(kernel: &TxKernel) -> TxKernelV2 {
let TxKernel {
features,
fee,
lock_height,
excess,
excess_sig,
} = *kernel;
TxKernelV2 {
features,
fee,
lock_height,
excess,
excess_sig,
}
}
}
// Versioned to current slate
impl From<SlateV2> for Slate {
fn from(slate: SlateV2) -> Slate {
let SlateV2 {
num_participants,
id,
tx,
amount,
fee,
height,
lock_height,
participant_data,
version_info,
} = slate;
let participant_data = map_vec!(participant_data, |data| ParticipantData::from(data));
let version_info = VersionCompatInfo::from(&version_info);
let tx = Transaction::from(tx);
Slate {
num_participants,
id,
tx,
amount,
fee,
height,
lock_height,
participant_data,
version_info,
}
}
}
impl From<&ParticipantDataV2> for ParticipantData {
fn from(data: &ParticipantDataV2) -> ParticipantData {
let ParticipantDataV2 {
id,
public_blind_excess,
public_nonce,
part_sig,
message,
message_sig,
} = data;
let id = *id;
let public_blind_excess = *public_blind_excess;
let public_nonce = *public_nonce;
let part_sig = *part_sig;
let message: Option<String> = message.as_ref().map(|t| String::from(&**t));
let message_sig = *message_sig;
ParticipantData {
id,
public_blind_excess,
public_nonce,
part_sig,
message,
message_sig,
}
}
}
impl From<&VersionCompatInfoV2> for VersionCompatInfo {
fn from(data: &VersionCompatInfoV2) -> VersionCompatInfo {
let VersionCompatInfoV2 {
version,
orig_version,
min_compat_version,
} = data;
let version = *version;
let orig_version = *orig_version;
let min_compat_version = *min_compat_version;
VersionCompatInfo {
version,
orig_version,
min_compat_version,
}
}
}
impl From<TransactionV2> for Transaction {
fn from(tx: TransactionV2) -> Transaction {
let TransactionV2 { offset, body } = tx;
let body = TransactionBody::from(&body);
Transaction { offset, body }
}
}
impl From<&TransactionBodyV2> for TransactionBody {
fn from(body: &TransactionBodyV2) -> TransactionBody {
let TransactionBodyV2 {
inputs,
outputs,
kernels,
} = body;
let inputs = map_vec!(inputs, |inp| Input::from(inp));
let outputs = map_vec!(outputs, |out| Output::from(out));
let kernels = map_vec!(kernels, |kern| TxKernel::from(kern));
TransactionBody {
inputs,
outputs,
kernels,
}
}
}
impl From<&InputV2> for Input {
fn from(input: &InputV2) -> Input {
let InputV2 { features, commit } = *input;
Input { features, commit }
}
}
impl From<&OutputV2> for Output {
fn from(output: &OutputV2) -> Output {
let OutputV2 {
features,
commit,
proof,
} = *output;
Output {
features,
commit,
proof,
}
}
}
impl From<&TxKernelV2> for TxKernel {
fn from(kernel: &TxKernelV2) -> TxKernel {
let TxKernelV2 {
features,
fee,
lock_height,
excess,
excess_sig,
} = *kernel;
TxKernel {
features,
fee,
lock_height,
excess,
excess_sig,
}
}
}
+83
View File
@@ -14,9 +14,92 @@
//! This module contains old slate versions and conversions to the newest slate version
//! Used for serialization and deserialization of slates in a backwards compatible way.
use crate::slate::Slate;
use crate::slate_versions::v0::SlateV0;
use crate::slate_versions::v1::SlateV1;
use crate::slate_versions::v2::SlateV2;
#[allow(missing_docs)]
pub mod v0;
#[allow(missing_docs)]
pub mod v1;
#[allow(missing_docs)]
pub mod v2;
/// The most recent version of the slate
pub const CURRENT_SLATE_VERSION: u16 = 2;
/// Existing versions of the slate
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord)]
pub enum SlateVersion {
/// V0
V0,
/// V1
V1,
/// V2 (most current)
V2,
}
#[derive(Serialize, Deserialize)]
#[serde(untagged)]
/// Versions are ordered newest to oldest so serde attempts to
/// deserialize newer versions first, then falls back to older versions.
pub enum VersionedSlate {
/// Current
V2(SlateV2),
/// V1 - Grin 1.0.1 - 1.0.3)
V1(SlateV1),
/// V0 - Grin 1.0.0
V0(SlateV0),
}
impl VersionedSlate {
/// Return slate version
pub fn version(&self) -> SlateVersion {
match *self {
VersionedSlate::V2(_) => SlateVersion::V2,
VersionedSlate::V1(_) => SlateVersion::V1,
VersionedSlate::V0(_) => SlateVersion::V0,
}
}
/// convert this slate type to a specified older version
pub fn into_version(slate: Slate, version: SlateVersion) -> VersionedSlate {
match version {
SlateVersion::V2 => VersionedSlate::V2(slate.into()),
SlateVersion::V1 => {
let s = SlateV2::from(slate);
let s = SlateV1::from(s);
VersionedSlate::V1(s)
}
SlateVersion::V0 => {
let s = SlateV2::from(slate);
let s = SlateV1::from(s);
let s = SlateV0::from(s);
VersionedSlate::V0(s)
}
}
}
}
impl From<VersionedSlate> for Slate {
fn from(slate: VersionedSlate) -> Slate {
match slate {
VersionedSlate::V2(s) => {
let s = SlateV2::from(s);
Slate::from(s)
}
VersionedSlate::V1(s) => {
let s = SlateV1::from(s);
let s = SlateV2::from(s);
Slate::from(s)
}
VersionedSlate::V0(s) => {
let s = SlateV0::from(s);
let s = SlateV1::from(s);
let s = SlateV2::from(s);
Slate::from(s)
}
}
}
}
+19 -19
View File
@@ -1,6 +1,6 @@
[package]
name = "grin_wallet_util"
version = "1.1.0-beta.1"
version = "1.1.0-beta.2"
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
description = "Util, for generic utilities and to re-export grin crates"
license = "Apache-2.0"
@@ -17,28 +17,28 @@ toml = "0.4"
dirs = "1.0.3"
# For Release
grin_core = "1.1.0-beta.1"
grin_keychain = "1.1.0-beta.1"
grin_chain = "1.1.0-beta.1"
grin_util = "1.1.0-beta.1"
grin_api = "1.1.0-beta.1"
grin_store = "1.1.0-beta.1"
#grin_core = "1.1.0-beta.1"
#grin_keychain = "1.1.0-beta.1"
#grin_chain = "1.1.0-beta.1"
#grin_util = "1.1.0-beta.1"
#grin_api = "1.1.0-beta.1"
#grin_store = "1.1.0-beta.1"
# For bleeding edge
#grin_core = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" }
#grin_keychain = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" }
#grin_chain = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" }
#grin_util = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" }
#grin_api = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" }
#grin_store = { git = "https://github.com/mimblewimble/grin", branch = "milestone/1.1.0" }
grin_core = { git = "https://github.com/mimblewimble/grin", branch = "master" }
grin_keychain = { git = "https://github.com/mimblewimble/grin", branch = "master" }
grin_chain = { git = "https://github.com/mimblewimble/grin", branch = "master" }
grin_util = { git = "https://github.com/mimblewimble/grin", branch = "master" }
grin_api = { git = "https://github.com/mimblewimble/grin", branch = "master" }
grin_store = { git = "https://github.com/mimblewimble/grin", branch = "master" }
# For local testing
#grin_core = { path = "../../grin/core", version= "1.1.0"}
#grin_keychain = { path = "../../grin/keychain", version= "1.1.0"}
#grin_chain = { path = "../../grin/chain", version= "1.1.0"}
#grin_util = { path = "../../grin/util", version= "1.1.0"}
#grin_api = { path = "../../grin/api", version= "1.1.0"}
#grin_store = { path = "../../grin/store", version= "1.1.0"}
#grin_core = { path = "../../grin/core", version= "1.1.0-beta.2"}
#grin_keychain = { path = "../../grin/keychain", version= "1.1.0-beta.2"}
#grin_chain = { path = "../../grin/chain", version= "1.1.0-beta.2"}
#grin_util = { path = "../../grin/util", version= "1.1.0-beta.2"}
#grin_api = { path = "../../grin/api", version= "1.1.0-beta.2"}
#grin_store = { path = "../../grin/store", version= "1.1.0-beta.2"}
[dev-dependencies]
pretty_assertions = "0.5.1"