HF2 Slate Changes (#258)

* Update slate version to V3, define PaymentInfoV3 and add needed serialization

* rustfmt

* add ttl and payment proof info to slate

* rustfmt

* add documentation for updated fields

* doc test fixes
This commit is contained in:
Yeastplume 2019-11-20 11:01:38 +00:00 committed by GitHub
parent e74c0e2571
commit 9c2177e3d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 470 additions and 200 deletions

1
Cargo.lock generated
View file

@ -1022,6 +1022,7 @@ version = "3.0.0-alpha.1"
dependencies = [ dependencies = [
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
"ed25519-dalek 1.0.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"grin_wallet_config 3.0.0-alpha.1", "grin_wallet_config 3.0.0-alpha.1",

View file

@ -53,7 +53,7 @@ pub trait ForeignRpc {
"Ok": { "Ok": {
"foreign_api_version": 2, "foreign_api_version": 2,
"supported_slate_versions": [ "supported_slate_versions": [
"V2" "V3"
] ]
} }
} }
@ -133,6 +133,8 @@ pub trait ForeignRpc {
"height": "4", "height": "4",
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "4", "lock_height": "4",
"ttl_cutoff_height": "0",
"payment_proof": null,
"num_participants": 2, "num_participants": 2,
"participant_data": [ "participant_data": [
{ {
@ -251,6 +253,8 @@ pub trait ForeignRpc {
"fee": "7000000", "fee": "7000000",
"height": "5", "height": "5",
"lock_height": "0", "lock_height": "0",
"ttl_cutoff_height": "0",
"payment_proof": null,
"participant_data": [ "participant_data": [
{ {
"id": "0", "id": "0",
@ -279,6 +283,8 @@ pub trait ForeignRpc {
"height": "5", "height": "5",
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "0", "lock_height": "0",
"ttl_cutoff_height": "0",
"payment_proof": null,
"num_participants": 2, "num_participants": 2,
"participant_data": [ "participant_data": [
{ {
@ -414,6 +420,8 @@ pub trait ForeignRpc {
"fee": "7000000", "fee": "7000000",
"height": "5", "height": "5",
"lock_height": "0", "lock_height": "0",
"ttl_cutoff_height": "0",
"payment_proof": null,
"participant_data": [ "participant_data": [
{ {
"id": "1", "id": "1",
@ -447,6 +455,8 @@ pub trait ForeignRpc {
"height": "5", "height": "5",
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "0", "lock_height": "0",
"ttl_cutoff_height": "0",
"payment_proof": null,
"num_participants": 2, "num_participants": 2,
"participant_data": [ "participant_data": [
{ {
@ -529,7 +539,7 @@ where
fn build_coinbase(&self, block_fees: &BlockFees) -> Result<VersionedCoinbase, ErrorKind> { fn build_coinbase(&self, block_fees: &BlockFees) -> Result<VersionedCoinbase, ErrorKind> {
let cb: CbData = Foreign::build_coinbase(self, block_fees).map_err(|e| e.kind())?; let cb: CbData = Foreign::build_coinbase(self, block_fees).map_err(|e| e.kind())?;
Ok(VersionedCoinbase::into_version(cb, SlateVersion::V2)) Ok(VersionedCoinbase::into_version(cb, SlateVersion::V3))
} }
fn verify_slate_messages(&self, slate: VersionedSlate) -> Result<(), ErrorKind> { fn verify_slate_messages(&self, slate: VersionedSlate) -> Result<(), ErrorKind> {

View file

@ -17,7 +17,7 @@ use uuid::Uuid;
use crate::core::core::Transaction; use crate::core::core::Transaction;
use crate::keychain::{Identifier, Keychain}; use crate::keychain::{Identifier, Keychain};
use crate::libwallet::slate_versions::v2::TransactionV2; use crate::libwallet::slate_versions::v3::TransactionV3;
use crate::libwallet::{ use crate::libwallet::{
AcctPathMapping, ErrorKind, InitTxArgs, IssueInvoiceTxArgs, NodeClient, NodeHeightResult, AcctPathMapping, ErrorKind, InitTxArgs, IssueInvoiceTxArgs, NodeClient, NodeHeightResult,
OutputCommitMapping, Slate, SlateVersion, TxLogEntry, VersionedSlate, WalletInfo, OutputCommitMapping, Slate, SlateVersion, TxLogEntry, VersionedSlate, WalletInfo,
@ -358,6 +358,8 @@ pub trait OwnerRpc: Sync + Send {
"height": "4", "height": "4",
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "0", "lock_height": "0",
"ttl_cutoff_height": "0",
"payment_proof": null,
"num_participants": 2, "num_participants": 2,
"participant_data": [ "participant_data": [
{ {
@ -397,8 +399,8 @@ pub trait OwnerRpc: Sync + Send {
"offset": "d202964900000000d302964900000000d402964900000000d502964900000000" "offset": "d202964900000000d302964900000000d402964900000000d502964900000000"
}, },
"version_info": { "version_info": {
"orig_version": 2, "orig_version": 3,
"version": 2, "version": 3,
"block_header_version": 1 "block_header_version": 1
} }
} }
@ -443,6 +445,8 @@ pub trait OwnerRpc: Sync + Send {
"height": "4", "height": "4",
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "0", "lock_height": "0",
"ttl_cutoff_height": "0",
"payment_proof": null,
"num_participants": 2, "num_participants": 2,
"participant_data": [ "participant_data": [
{ {
@ -477,8 +481,8 @@ pub trait OwnerRpc: Sync + Send {
"offset": "d202964900000000d302964900000000d402964900000000d502964900000000" "offset": "d202964900000000d302964900000000d402964900000000d502964900000000"
}, },
"version_info": { "version_info": {
"orig_version": 2, "orig_version": 3,
"version": 2, "version": 3,
"block_header_version": 1 "block_header_version": 1
} }
} }
@ -507,6 +511,8 @@ pub trait OwnerRpc: Sync + Send {
"height": "4", "height": "4",
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "0", "lock_height": "0",
"ttl_cutoff_height": "0",
"payment_proof": null,
"num_participants": 2, "num_participants": 2,
"participant_data": [ "participant_data": [
{ {
@ -541,8 +547,8 @@ pub trait OwnerRpc: Sync + Send {
"offset": "d202964900000000d302964900000000d402964900000000d502964900000000" "offset": "d202964900000000d302964900000000d402964900000000d502964900000000"
}, },
"version_info": { "version_info": {
"orig_version": 2, "orig_version": 3,
"version": 2, "version": 3,
"block_header_version": 2 "block_header_version": 2
} }
}, },
@ -573,6 +579,8 @@ pub trait OwnerRpc: Sync + Send {
"height": "4", "height": "4",
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "0", "lock_height": "0",
"ttl_cutoff_height": "0",
"payment_proof": null,
"num_participants": 2, "num_participants": 2,
"participant_data": [ "participant_data": [
{ {
@ -625,8 +633,8 @@ pub trait OwnerRpc: Sync + Send {
"offset": "d202964900000000d302964900000000d402964900000000d502964900000000" "offset": "d202964900000000d302964900000000d402964900000000d502964900000000"
}, },
"version_info": { "version_info": {
"orig_version": 2, "orig_version": 3,
"version": 2, "version": 3,
"block_header_version": 2 "block_header_version": 2
} }
} }
@ -659,6 +667,8 @@ pub trait OwnerRpc: Sync + Send {
"height": "4", "height": "4",
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "4", "lock_height": "4",
"ttl_cutoff_height": "0",
"payment_proof": null,
"num_participants": 2, "num_participants": 2,
"participant_data": [ "participant_data": [
{ {
@ -698,8 +708,8 @@ pub trait OwnerRpc: Sync + Send {
"offset": "d202964900000000d302964900000000d402964900000000d502964900000000" "offset": "d202964900000000d302964900000000d402964900000000d502964900000000"
}, },
"version_info": { "version_info": {
"orig_version": 2, "orig_version": 3,
"version": 2, "version": 3,
"block_header_version": 2 "block_header_version": 2
} }
}, },
@ -740,12 +750,14 @@ pub trait OwnerRpc: Sync + Send {
"params": [ "params": [
{ {
"version_info": { "version_info": {
"version": 2, "version": 3,
"orig_version": 2, "orig_version": 3,
"block_header_version": 2 "block_header_version": 2
}, },
"num_participants": 2, "num_participants": 2,
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"ttl_cutoff_height": "0",
"payment_proof": null,
"tx": { "tx": {
"offset": "d202964900000000d302964900000000d402964900000000d502964900000000", "offset": "d202964900000000d302964900000000d402964900000000d502964900000000",
"body": { "body": {
@ -819,6 +831,8 @@ pub trait OwnerRpc: Sync + Send {
"fee": "7000000", "fee": "7000000",
"height": "5", "height": "5",
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"ttl_cutoff_height": "0",
"payment_proof": null,
"lock_height": "0", "lock_height": "0",
"num_participants": 2, "num_participants": 2,
"participant_data": [ "participant_data": [
@ -876,8 +890,8 @@ pub trait OwnerRpc: Sync + Send {
"offset": "d202964900000000d302964900000000d402964900000000d502964900000000" "offset": "d202964900000000d302964900000000d402964900000000d502964900000000"
}, },
"version_info": { "version_info": {
"orig_version": 2, "orig_version": 3,
"version": 2, "version": 3,
"block_header_version": 2 "block_header_version": 2
} }
} }
@ -954,7 +968,7 @@ pub trait OwnerRpc: Sync + Send {
``` ```
*/ */
fn post_tx(&self, tx: TransactionV2, fluff: bool) -> Result<(), ErrorKind>; fn post_tx(&self, tx: TransactionV3, fluff: bool) -> Result<(), ErrorKind>;
/** /**
Networked version of [Owner::cancel_tx](struct.Owner.html#method.cancel_tx). Networked version of [Owner::cancel_tx](struct.Owner.html#method.cancel_tx).
@ -1080,7 +1094,7 @@ pub trait OwnerRpc: Sync + Send {
# , false, 5, true, true, false); # , false, 5, true, true, false);
``` ```
*/ */
fn get_stored_tx(&self, tx: &TxLogEntry) -> Result<Option<TransactionV2>, ErrorKind>; fn get_stored_tx(&self, tx: &TxLogEntry) -> Result<Option<TransactionV3>, ErrorKind>;
/** /**
Networked version of [Owner::verify_slate_messages](struct.Owner.html#method.verify_slate_messages). Networked version of [Owner::verify_slate_messages](struct.Owner.html#method.verify_slate_messages).
@ -1098,6 +1112,8 @@ pub trait OwnerRpc: Sync + Send {
"height": "4", "height": "4",
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "4", "lock_height": "4",
"ttl_cutoff_height": "0",
"payment_proof": null,
"num_participants": 2, "num_participants": 2,
"participant_data": [ "participant_data": [
{ {
@ -1137,8 +1153,8 @@ pub trait OwnerRpc: Sync + Send {
"offset": "d202964900000000d302964900000000d402964900000000d502964900000000" "offset": "d202964900000000d302964900000000d402964900000000d502964900000000"
}, },
"version_info": { "version_info": {
"orig_version": 2, "orig_version": 3,
"version": 2, "version": 3,
"block_header_version": 2 "block_header_version": 2
} }
} }
@ -1271,13 +1287,13 @@ where
fn init_send_tx(&self, args: InitTxArgs) -> Result<VersionedSlate, ErrorKind> { fn init_send_tx(&self, args: InitTxArgs) -> Result<VersionedSlate, ErrorKind> {
let slate = Owner::init_send_tx(self, None, args).map_err(|e| e.kind())?; let slate = Owner::init_send_tx(self, None, args).map_err(|e| e.kind())?;
let version = SlateVersion::V2; let version = SlateVersion::V3;
Ok(VersionedSlate::into_version(slate, version)) Ok(VersionedSlate::into_version(slate, version))
} }
fn issue_invoice_tx(&self, args: IssueInvoiceTxArgs) -> Result<VersionedSlate, ErrorKind> { fn issue_invoice_tx(&self, args: IssueInvoiceTxArgs) -> Result<VersionedSlate, ErrorKind> {
let slate = Owner::issue_invoice_tx(self, None, args).map_err(|e| e.kind())?; let slate = Owner::issue_invoice_tx(self, None, args).map_err(|e| e.kind())?;
let version = SlateVersion::V2; let version = SlateVersion::V3;
Ok(VersionedSlate::into_version(slate, version)) Ok(VersionedSlate::into_version(slate, version))
} }
@ -1288,14 +1304,14 @@ where
) -> Result<VersionedSlate, ErrorKind> { ) -> Result<VersionedSlate, ErrorKind> {
let out_slate = Owner::process_invoice_tx(self, None, &Slate::from(in_slate), args) let out_slate = Owner::process_invoice_tx(self, None, &Slate::from(in_slate), args)
.map_err(|e| e.kind())?; .map_err(|e| e.kind())?;
let version = SlateVersion::V2; let version = SlateVersion::V3;
Ok(VersionedSlate::into_version(out_slate, version)) Ok(VersionedSlate::into_version(out_slate, version))
} }
fn finalize_tx(&self, in_slate: VersionedSlate) -> Result<VersionedSlate, ErrorKind> { fn finalize_tx(&self, in_slate: VersionedSlate) -> Result<VersionedSlate, ErrorKind> {
let out_slate = let out_slate =
Owner::finalize_tx(self, None, &Slate::from(in_slate)).map_err(|e| e.kind())?; Owner::finalize_tx(self, None, &Slate::from(in_slate)).map_err(|e| e.kind())?;
let version = SlateVersion::V2; let version = SlateVersion::V3;
Ok(VersionedSlate::into_version(out_slate, version)) Ok(VersionedSlate::into_version(out_slate, version))
} }
@ -1312,13 +1328,13 @@ where
Owner::cancel_tx(self, None, tx_id, tx_slate_id).map_err(|e| e.kind()) Owner::cancel_tx(self, None, tx_id, tx_slate_id).map_err(|e| e.kind())
} }
fn get_stored_tx(&self, tx: &TxLogEntry) -> Result<Option<TransactionV2>, ErrorKind> { fn get_stored_tx(&self, tx: &TxLogEntry) -> Result<Option<TransactionV3>, ErrorKind> {
Owner::get_stored_tx(self, None, tx) Owner::get_stored_tx(self, None, tx)
.map(|x| x.map(|y| TransactionV2::from(y))) .map(|x| x.map(|y| TransactionV3::from(y)))
.map_err(|e| e.kind()) .map_err(|e| e.kind())
} }
fn post_tx(&self, tx: TransactionV2, fluff: bool) -> Result<(), ErrorKind> { fn post_tx(&self, tx: TransactionV3, fluff: bool) -> Result<(), ErrorKind> {
Owner::post_tx(self, None, &Transaction::from(tx), fluff).map_err(|e| e.kind()) Owner::post_tx(self, None, &Transaction::from(tx), fluff).map_err(|e| e.kind())
} }

View file

@ -19,7 +19,7 @@ use crate::config::{TorConfig, WalletConfig};
use crate::core::core::Transaction; use crate::core::core::Transaction;
use crate::core::global; use crate::core::global;
use crate::keychain::{Identifier, Keychain}; use crate::keychain::{Identifier, Keychain};
use crate::libwallet::slate_versions::v2::TransactionV2; use crate::libwallet::slate_versions::v3::TransactionV3;
use crate::libwallet::{ use crate::libwallet::{
AcctPathMapping, ErrorKind, InitTxArgs, IssueInvoiceTxArgs, NodeClient, NodeHeightResult, AcctPathMapping, ErrorKind, InitTxArgs, IssueInvoiceTxArgs, NodeClient, NodeHeightResult,
OutputCommitMapping, Slate, SlateVersion, StatusMessage, TxLogEntry, VersionedSlate, OutputCommitMapping, Slate, SlateVersion, StatusMessage, TxLogEntry, VersionedSlate,
@ -389,7 +389,9 @@ pub trait OwnerRpcS {
"height": "4", "height": "4",
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "0", "lock_height": "0",
"ttl_cutoff_height": "0",
"num_participants": 2, "num_participants": 2,
"payment_proof": null,
"participant_data": [ "participant_data": [
{ {
"id": "0", "id": "0",
@ -428,8 +430,8 @@ pub trait OwnerRpcS {
"offset": "d202964900000000d302964900000000d402964900000000d502964900000000" "offset": "d202964900000000d302964900000000d402964900000000d502964900000000"
}, },
"version_info": { "version_info": {
"orig_version": 2, "orig_version": 3,
"version": 2, "version": 3,
"block_header_version": 1 "block_header_version": 1
} }
} }
@ -475,7 +477,9 @@ pub trait OwnerRpcS {
"height": "4", "height": "4",
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "0", "lock_height": "0",
"ttl_cutoff_height": "0",
"num_participants": 2, "num_participants": 2,
"payment_proof": null,
"participant_data": [ "participant_data": [
{ {
"id": "1", "id": "1",
@ -509,8 +513,8 @@ pub trait OwnerRpcS {
"offset": "d202964900000000d302964900000000d402964900000000d502964900000000" "offset": "d202964900000000d302964900000000d402964900000000d502964900000000"
}, },
"version_info": { "version_info": {
"orig_version": 2, "orig_version": 3,
"version": 2, "version": 3,
"block_header_version": 1 "block_header_version": 1
} }
} }
@ -544,7 +548,9 @@ pub trait OwnerRpcS {
"height": "4", "height": "4",
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "0", "lock_height": "0",
"ttl_cutoff_height": "0",
"num_participants": 2, "num_participants": 2,
"payment_proof": null,
"participant_data": [ "participant_data": [
{ {
"id": "1", "id": "1",
@ -578,8 +584,8 @@ pub trait OwnerRpcS {
"offset": "d202964900000000d302964900000000d402964900000000d502964900000000" "offset": "d202964900000000d302964900000000d402964900000000d502964900000000"
}, },
"version_info": { "version_info": {
"orig_version": 2, "orig_version": 3,
"version": 2, "version": 3,
"block_header_version": 2 "block_header_version": 2
} }
}, },
@ -610,7 +616,9 @@ pub trait OwnerRpcS {
"height": "4", "height": "4",
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "0", "lock_height": "0",
"ttl_cutoff_height": "0",
"num_participants": 2, "num_participants": 2,
"payment_proof": null,
"participant_data": [ "participant_data": [
{ {
"id": "1", "id": "1",
@ -662,8 +670,8 @@ pub trait OwnerRpcS {
"offset": "d202964900000000d302964900000000d402964900000000d502964900000000" "offset": "d202964900000000d302964900000000d402964900000000d502964900000000"
}, },
"version_info": { "version_info": {
"orig_version": 2, "orig_version": 3,
"version": 2, "version": 3,
"block_header_version": 2 "block_header_version": 2
} }
} }
@ -699,7 +707,9 @@ pub trait OwnerRpcS {
"height": "4", "height": "4",
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "4", "lock_height": "4",
"ttl_cutoff_height": "0",
"num_participants": 2, "num_participants": 2,
"payment_proof": null,
"participant_data": [ "participant_data": [
{ {
"id": "0", "id": "0",
@ -738,8 +748,8 @@ pub trait OwnerRpcS {
"offset": "d202964900000000d302964900000000d402964900000000d502964900000000" "offset": "d202964900000000d302964900000000d402964900000000d502964900000000"
}, },
"version_info": { "version_info": {
"orig_version": 2, "orig_version": 3,
"version": 2, "version": 3,
"block_header_version": 2 "block_header_version": 2
} }
}, },
@ -782,12 +792,13 @@ pub trait OwnerRpcS {
"token": "d202964900000000d302964900000000d402964900000000d502964900000000", "token": "d202964900000000d302964900000000d402964900000000d502964900000000",
"slate": { "slate": {
"version_info": { "version_info": {
"version": 2, "version": 3,
"orig_version": 2, "orig_version": 3,
"block_header_version": 2 "block_header_version": 2
}, },
"num_participants": 2, "num_participants": 2,
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"payment_proof": null,
"tx": { "tx": {
"offset": "d202964900000000d302964900000000d402964900000000d502964900000000", "offset": "d202964900000000d302964900000000d402964900000000d502964900000000",
"body": { "body": {
@ -828,6 +839,7 @@ pub trait OwnerRpcS {
"fee": "7000000", "fee": "7000000",
"height": "5", "height": "5",
"lock_height": "0", "lock_height": "0",
"ttl_cutoff_height": "0",
"participant_data": [ "participant_data": [
{ {
"id": "0", "id": "0",
@ -862,7 +874,9 @@ pub trait OwnerRpcS {
"height": "5", "height": "5",
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "0", "lock_height": "0",
"ttl_cutoff_height": "0",
"num_participants": 2, "num_participants": 2,
"payment_proof": null,
"participant_data": [ "participant_data": [
{ {
"id": "0", "id": "0",
@ -918,8 +932,8 @@ pub trait OwnerRpcS {
"offset": "d202964900000000d302964900000000d402964900000000d502964900000000" "offset": "d202964900000000d302964900000000d402964900000000d502964900000000"
}, },
"version_info": { "version_info": {
"orig_version": 2, "orig_version": 3,
"version": 2, "version": 3,
"block_header_version": 2 "block_header_version": 2
} }
} }
@ -998,7 +1012,7 @@ pub trait OwnerRpcS {
``` ```
*/ */
fn post_tx(&self, token: Token, tx: TransactionV2, fluff: bool) -> Result<(), ErrorKind>; fn post_tx(&self, token: Token, tx: TransactionV3, fluff: bool) -> Result<(), ErrorKind>;
/** /**
Networked version of [Owner::cancel_tx](struct.Owner.html#method.cancel_tx). Networked version of [Owner::cancel_tx](struct.Owner.html#method.cancel_tx).
@ -1138,7 +1152,7 @@ pub trait OwnerRpcS {
&self, &self,
token: Token, token: Token,
tx: &TxLogEntry, tx: &TxLogEntry,
) -> Result<Option<TransactionV2>, ErrorKind>; ) -> Result<Option<TransactionV3>, ErrorKind>;
/** /**
Networked version of [Owner::verify_slate_messages](struct.Owner.html#method.verify_slate_messages). Networked version of [Owner::verify_slate_messages](struct.Owner.html#method.verify_slate_messages).
@ -1158,6 +1172,7 @@ pub trait OwnerRpcS {
"height": "4", "height": "4",
"id": "0436430c-2b02-624c-2032-570501212b00", "id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "4", "lock_height": "4",
"ttl_cutoff_height": "0",
"num_participants": 2, "num_participants": 2,
"participant_data": [ "participant_data": [
{ {
@ -1194,11 +1209,12 @@ pub trait OwnerRpcS {
} }
] ]
}, },
"offset": "d202964900000000d302964900000000d402964900000000d502964900000000" "offset": "d202964900000000d302964900000000d402964900000000d502964900000000",
"payment_proof": null
}, },
"version_info": { "version_info": {
"orig_version": 2, "orig_version": 3,
"version": 2, "version": 3,
"block_header_version": 2 "block_header_version": 2
} }
} }
@ -1834,7 +1850,7 @@ where
fn init_send_tx(&self, token: Token, args: InitTxArgs) -> Result<VersionedSlate, ErrorKind> { fn init_send_tx(&self, token: Token, args: InitTxArgs) -> Result<VersionedSlate, ErrorKind> {
let slate = Owner::init_send_tx(self, (&token.keychain_mask).as_ref(), args) let slate = Owner::init_send_tx(self, (&token.keychain_mask).as_ref(), args)
.map_err(|e| e.kind())?; .map_err(|e| e.kind())?;
let version = SlateVersion::V2; let version = SlateVersion::V3;
Ok(VersionedSlate::into_version(slate, version)) Ok(VersionedSlate::into_version(slate, version))
} }
@ -1845,7 +1861,7 @@ where
) -> Result<VersionedSlate, ErrorKind> { ) -> Result<VersionedSlate, ErrorKind> {
let slate = Owner::issue_invoice_tx(self, (&token.keychain_mask).as_ref(), args) let slate = Owner::issue_invoice_tx(self, (&token.keychain_mask).as_ref(), args)
.map_err(|e| e.kind())?; .map_err(|e| e.kind())?;
let version = SlateVersion::V2; let version = SlateVersion::V3;
Ok(VersionedSlate::into_version(slate, version)) Ok(VersionedSlate::into_version(slate, version))
} }
@ -1862,7 +1878,7 @@ where
args, args,
) )
.map_err(|e| e.kind())?; .map_err(|e| e.kind())?;
let version = SlateVersion::V2; let version = SlateVersion::V3;
Ok(VersionedSlate::into_version(out_slate, version)) Ok(VersionedSlate::into_version(out_slate, version))
} }
@ -1877,7 +1893,7 @@ where
&Slate::from(in_slate), &Slate::from(in_slate),
) )
.map_err(|e| e.kind())?; .map_err(|e| e.kind())?;
let version = SlateVersion::V2; let version = SlateVersion::V3;
Ok(VersionedSlate::into_version(out_slate, version)) Ok(VersionedSlate::into_version(out_slate, version))
} }
@ -1910,13 +1926,13 @@ where
&self, &self,
token: Token, token: Token,
tx: &TxLogEntry, tx: &TxLogEntry,
) -> Result<Option<TransactionV2>, ErrorKind> { ) -> Result<Option<TransactionV3>, ErrorKind> {
Owner::get_stored_tx(self, (&token.keychain_mask).as_ref(), tx) Owner::get_stored_tx(self, (&token.keychain_mask).as_ref(), tx)
.map(|x| x.map(|y| TransactionV2::from(y))) .map(|x| x.map(|y| TransactionV3::from(y)))
.map_err(|e| e.kind()) .map_err(|e| e.kind())
} }
fn post_tx(&self, token: Token, tx: TransactionV2, fluff: bool) -> Result<(), ErrorKind> { fn post_tx(&self, token: Token, tx: TransactionV3, fluff: bool) -> Result<(), ErrorKind> {
Owner::post_tx( Owner::post_tx(
self, self,
(&token.keychain_mask).as_ref(), (&token.keychain_mask).as_ref(),

View file

@ -736,15 +736,15 @@ pub struct PostArgs {
pub fluff: bool, pub fluff: bool,
} }
pub fn post<'a, L, C, K>( pub fn post<L, C, K>(
wallet: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>, wallet: Arc<Mutex<Box<dyn WalletInst<'static, L, C, K>>>>,
keychain_mask: Option<&SecretKey>, keychain_mask: Option<&SecretKey>,
args: PostArgs, args: PostArgs,
) -> Result<(), Error> ) -> Result<(), Error>
where where
L: WalletLCProvider<'a, C, K>, L: WalletLCProvider<'static, C, K> + 'static,
C: NodeClient + 'a, C: NodeClient + 'static,
K: keychain::Keychain + 'a, K: keychain::Keychain + 'static,
{ {
let slate = PathToSlate((&args.input).into()).get_tx()?; let slate = PathToSlate((&args.input).into()).get_tx()?;

View file

@ -111,7 +111,7 @@ impl HttpSlateSender {
return Err(ErrorKind::ClientCallback(report).into()); return Err(ErrorKind::ClientCallback(report).into());
} }
if !supported_slate_versions.contains(&"V2".to_owned()) { if !supported_slate_versions.contains(&"V3".to_owned()) {
let report = format!("Unable to negotiate slate format with other wallet."); let report = format!("Unable to negotiate slate format with other wallet.");
error!("{}", report); error!("{}", report);
return Err(ErrorKind::ClientCallback(report).into()); return Err(ErrorKind::ClientCallback(report).into());

View file

@ -26,7 +26,7 @@ use crate::core::{pow, ser};
use crate::keychain::Keychain; use crate::keychain::Keychain;
use crate::libwallet; use crate::libwallet;
use crate::libwallet::api_impl::foreign; use crate::libwallet::api_impl::foreign;
use crate::libwallet::slate_versions::v2::SlateV2; use crate::libwallet::slate_versions::v3::SlateV3;
use crate::libwallet::{ use crate::libwallet::{
NodeClient, NodeVersionInfo, Slate, TxWrapper, WalletInst, WalletLCProvider, NodeClient, NodeVersionInfo, Slate, TxWrapper, WalletInst, WalletLCProvider,
}; };
@ -216,7 +216,7 @@ where
Some(w) => w, Some(w) => w,
}; };
let slate: SlateV2 = serde_json::from_str(&m.body).context( let slate: SlateV3 = serde_json::from_str(&m.body).context(
libwallet::ErrorKind::ClientCallback("Error parsing TxWrapper".to_owned()), libwallet::ErrorKind::ClientCallback("Error parsing TxWrapper".to_owned()),
)?; )?;
@ -239,7 +239,7 @@ where
sender_id: m.dest, sender_id: m.dest,
dest: m.sender_id, dest: m.sender_id,
method: m.method, method: m.method,
body: serde_json::to_string(&SlateV2::from(slate)).unwrap(), body: serde_json::to_string(&SlateV3::from(slate)).unwrap(),
}) })
} }
@ -392,7 +392,7 @@ impl LocalWalletClient {
sender_id: self.id.clone(), sender_id: self.id.clone(),
dest: dest.to_owned(), dest: dest.to_owned(),
method: "send_tx_slate".to_owned(), method: "send_tx_slate".to_owned(),
body: serde_json::to_string(&SlateV2::from(slate)).unwrap(), body: serde_json::to_string(&SlateV3::from(slate)).unwrap(),
}; };
{ {
let p = self.proxy_tx.lock(); let p = self.proxy_tx.lock();
@ -403,7 +403,7 @@ impl LocalWalletClient {
let r = self.rx.lock(); let r = self.rx.lock();
let m = r.recv().unwrap(); let m = r.recv().unwrap();
trace!("Received send_tx_slate response: {:?}", m.clone()); trace!("Received send_tx_slate response: {:?}", m.clone());
let slate: SlateV2 = serde_json::from_str(&m.body).context( let slate: SlateV3 = serde_json::from_str(&m.body).context(
libwallet::ErrorKind::ClientCallback("Parsing send_tx_slate response".to_owned()), libwallet::ErrorKind::ClientCallback("Parsing send_tx_slate response".to_owned()),
)?; )?;
Ok(Slate::from(slate)) Ok(Slate::from(slate))

View file

@ -24,6 +24,7 @@ chrono = { version = "0.4.4", features = ["serde"] }
lazy_static = "1" lazy_static = "1"
strum = "0.15" strum = "0.15"
strum_macros = "0.15" strum_macros = "0.15"
ed25519-dalek = "1.0.0-pre.1"
grin_wallet_util = { path = "../util", version = "3.0.0-alpha.1" } grin_wallet_util = { path = "../util", version = "3.0.0-alpha.1" }
grin_wallet_config = { path = "../config", version = "3.0.0-alpha.1" } grin_wallet_config = { path = "../config", version = "3.0.0-alpha.1" }

View file

@ -30,6 +30,8 @@ use crate::grin_util::secp::key::{PublicKey, SecretKey};
use crate::grin_util::secp::pedersen::Commitment; use crate::grin_util::secp::pedersen::Commitment;
use crate::grin_util::secp::Signature; use crate::grin_util::secp::Signature;
use crate::grin_util::{self, secp, RwLock}; use crate::grin_util::{self, secp, RwLock};
use crate::slate_versions::ser as dalek_ser;
use ed25519_dalek::PublicKey as DalekPublicKey;
use failure::ResultExt; use failure::ResultExt;
use rand::rngs::mock::StepRng; use rand::rngs::mock::StepRng;
use rand::thread_rng; use rand::thread_rng;
@ -39,13 +41,23 @@ use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use uuid::Uuid; use uuid::Uuid;
use crate::slate_versions::v2::{ use crate::slate_versions::v3::{
CoinbaseV2, InputV2, OutputV2, ParticipantDataV2, SlateV2, TransactionBodyV2, TransactionV2, CoinbaseV3, InputV3, OutputV3, ParticipantDataV3, PaymentInfoV3, SlateV3, TransactionBodyV3,
TxKernelV2, VersionCompatInfoV2, TransactionV3, TxKernelV3, VersionCompatInfoV3,
}; };
use crate::slate_versions::{CURRENT_SLATE_VERSION, GRIN_BLOCK_HEADER_VERSION}; use crate::slate_versions::{CURRENT_SLATE_VERSION, GRIN_BLOCK_HEADER_VERSION};
use crate::types::CbData; use crate::types::CbData;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct PaymentInfo {
#[serde(with = "dalek_ser::dalek_pubkey_serde")]
pub sender_address: DalekPublicKey,
#[serde(with = "dalek_ser::option_dalek_pubkey_serde")]
pub receiver_address: Option<DalekPublicKey>,
#[serde(with = "secp_ser::option_sig_serde")]
pub receiver_signature: Option<Signature>,
}
/// Public data for each participant in the slate /// Public data for each participant in the slate
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ParticipantData { pub struct ParticipantData {
@ -174,9 +186,20 @@ pub struct Slate {
/// Participant data, each participant in the transaction will /// Participant data, each participant in the transaction will
/// insert their public data here. For now, 0 is sender and 1 /// insert their public data here. For now, 0 is sender and 1
/// is receiver, though this will change for multi-party /// is receiver, though this will change for multi-party
#[serde(with = "secp_ser::string_or_u64")]
pub ttl_cutoff_height: u64,
/// Participant data, each participant in the transaction will
/// insert their public data here. For now, 0 is sender and 1
/// is receiver, though this will change for multi-party
pub participant_data: Vec<ParticipantData>, pub participant_data: Vec<ParticipantData>,
/// Payment Proof
#[serde(default = "default_payment_none")]
pub payment_proof: Option<PaymentInfo>,
} }
fn default_payment_none() -> Option<PaymentInfo> {
None
}
/// Versioning and compatibility info about this slate /// Versioning and compatibility info about this slate
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct VersionCompatInfo { pub struct VersionCompatInfo {
@ -206,18 +229,18 @@ impl Slate {
/// Recieve a slate, upgrade it to the latest version internally /// Recieve a slate, upgrade it to the latest version internally
pub fn deserialize_upgrade(slate_json: &str) -> Result<Slate, Error> { pub fn deserialize_upgrade(slate_json: &str) -> Result<Slate, Error> {
let version = Slate::parse_slate_version(slate_json)?; let version = Slate::parse_slate_version(slate_json)?;
let v2: SlateV2 = match version { let v3: SlateV3 = match version {
2 => serde_json::from_str(slate_json).context(ErrorKind::SlateDeser)?, 3 => serde_json::from_str(slate_json).context(ErrorKind::SlateDeser)?,
// left as a reminder // left as a reminder
/*0 => { /*0 => {
let v0: SlateV0 = let v0: SlateV0 =
serde_json::from_str(slate_json).context(ErrorKind::SlateDeser)?; serde_json::from_str(slate_json).context(ErrorKind::SlateDeser)?;
let v1 = SlateV1::from(v0); let v1 = SlateV1::from(v0);
SlateV2::from(v1) SlateV3::from(v1)
}*/ }*/
_ => return Err(ErrorKind::SlateVersion(version).into()), _ => return Err(ErrorKind::SlateVersion(version).into()),
}; };
Ok(v2.into()) Ok(v3.into())
} }
/// Create a new slate /// Create a new slate
@ -230,12 +253,14 @@ impl Slate {
fee: 0, fee: 0,
height: 0, height: 0,
lock_height: 0, lock_height: 0,
ttl_cutoff_height: 0,
participant_data: vec![], participant_data: vec![],
version_info: VersionCompatInfo { version_info: VersionCompatInfo {
version: CURRENT_SLATE_VERSION, version: CURRENT_SLATE_VERSION,
orig_version: CURRENT_SLATE_VERSION, orig_version: CURRENT_SLATE_VERSION,
block_header_version: GRIN_BLOCK_HEADER_VERSION, block_header_version: GRIN_BLOCK_HEADER_VERSION,
}, },
payment_proof: None,
} }
} }
@ -698,9 +723,9 @@ impl Serialize for Slate {
{ {
use serde::ser::Error; use serde::ser::Error;
let v2 = SlateV2::from(self); let v3 = SlateV3::from(self);
match self.version_info.orig_version { match self.version_info.orig_version {
2 => v2.serialize(serializer), 3 => v3.serialize(serializer),
// left as a reminder // left as a reminder
/*0 => { /*0 => {
let v1 = SlateV1::from(v2); let v1 = SlateV1::from(v2);
@ -733,11 +758,11 @@ impl SlateVersionProbe {
} }
// Coinbase data to versioned. // Coinbase data to versioned.
impl From<CbData> for CoinbaseV2 { impl From<CbData> for CoinbaseV3 {
fn from(cb: CbData) -> CoinbaseV2 { fn from(cb: CbData) -> CoinbaseV3 {
CoinbaseV2 { CoinbaseV3 {
output: OutputV2::from(&cb.output), output: OutputV3::from(&cb.output),
kernel: TxKernelV2::from(&cb.kernel), kernel: TxKernelV3::from(&cb.kernel),
key_id: cb.key_id, key_id: cb.key_id,
} }
} }
@ -746,8 +771,8 @@ impl From<CbData> for CoinbaseV2 {
// Current slate version to versioned conversions // Current slate version to versioned conversions
// Slate to versioned // Slate to versioned
impl From<Slate> for SlateV2 { impl From<Slate> for SlateV3 {
fn from(slate: Slate) -> SlateV2 { fn from(slate: Slate) -> SlateV3 {
let Slate { let Slate {
num_participants, num_participants,
id, id,
@ -756,13 +781,19 @@ impl From<Slate> for SlateV2 {
fee, fee,
height, height,
lock_height, lock_height,
ttl_cutoff_height,
participant_data, participant_data,
version_info, version_info,
payment_proof,
} = slate; } = slate;
let participant_data = map_vec!(participant_data, |data| ParticipantDataV2::from(data)); let participant_data = map_vec!(participant_data, |data| ParticipantDataV3::from(data));
let version_info = VersionCompatInfoV2::from(&version_info); let version_info = VersionCompatInfoV3::from(&version_info);
let tx = TransactionV2::from(tx); let payment_proof = match payment_proof {
SlateV2 { Some(p) => Some(PaymentInfoV3::from(&p)),
None => None,
};
let tx = TransactionV3::from(tx);
SlateV3 {
num_participants, num_participants,
id, id,
tx, tx,
@ -770,14 +801,16 @@ impl From<Slate> for SlateV2 {
fee, fee,
height, height,
lock_height, lock_height,
ttl_cutoff_height,
participant_data, participant_data,
version_info, version_info,
payment_proof,
} }
} }
} }
impl From<&Slate> for SlateV2 { impl From<&Slate> for SlateV3 {
fn from(slate: &Slate) -> SlateV2 { fn from(slate: &Slate) -> SlateV3 {
let Slate { let Slate {
num_participants, num_participants,
id, id,
@ -786,19 +819,26 @@ impl From<&Slate> for SlateV2 {
fee, fee,
height, height,
lock_height, lock_height,
ttl_cutoff_height,
participant_data, participant_data,
version_info, version_info,
payment_proof,
} = slate; } = slate;
let num_participants = *num_participants; let num_participants = *num_participants;
let id = *id; let id = *id;
let tx = TransactionV2::from(tx); let tx = TransactionV3::from(tx);
let amount = *amount; let amount = *amount;
let fee = *fee; let fee = *fee;
let height = *height; let height = *height;
let lock_height = *lock_height; let lock_height = *lock_height;
let participant_data = map_vec!(participant_data, |data| ParticipantDataV2::from(data)); let ttl_cutoff_height = *ttl_cutoff_height;
let version_info = VersionCompatInfoV2::from(version_info); let participant_data = map_vec!(participant_data, |data| ParticipantDataV3::from(data));
SlateV2 { let version_info = VersionCompatInfoV3::from(version_info);
let payment_proof = match payment_proof {
Some(p) => Some(PaymentInfoV3::from(p)),
None => None,
};
SlateV3 {
num_participants, num_participants,
id, id,
tx, tx,
@ -806,14 +846,16 @@ impl From<&Slate> for SlateV2 {
fee, fee,
height, height,
lock_height, lock_height,
ttl_cutoff_height,
participant_data, participant_data,
version_info, version_info,
payment_proof,
} }
} }
} }
impl From<&ParticipantData> for ParticipantDataV2 { impl From<&ParticipantData> for ParticipantDataV3 {
fn from(data: &ParticipantData) -> ParticipantDataV2 { fn from(data: &ParticipantData) -> ParticipantDataV3 {
let ParticipantData { let ParticipantData {
id, id,
public_blind_excess, public_blind_excess,
@ -828,7 +870,7 @@ impl From<&ParticipantData> for ParticipantDataV2 {
let part_sig = *part_sig; let part_sig = *part_sig;
let message: Option<String> = message.as_ref().map(|t| String::from(&**t)); let message: Option<String> = message.as_ref().map(|t| String::from(&**t));
let message_sig = *message_sig; let message_sig = *message_sig;
ParticipantDataV2 { ParticipantDataV3 {
id, id,
public_blind_excess, public_blind_excess,
public_nonce, public_nonce,
@ -839,8 +881,8 @@ impl From<&ParticipantData> for ParticipantDataV2 {
} }
} }
impl From<&VersionCompatInfo> for VersionCompatInfoV2 { impl From<&VersionCompatInfo> for VersionCompatInfoV3 {
fn from(data: &VersionCompatInfo) -> VersionCompatInfoV2 { fn from(data: &VersionCompatInfo) -> VersionCompatInfoV3 {
let VersionCompatInfo { let VersionCompatInfo {
version, version,
orig_version, orig_version,
@ -849,7 +891,7 @@ impl From<&VersionCompatInfo> for VersionCompatInfoV2 {
let version = *version; let version = *version;
let orig_version = *orig_version; let orig_version = *orig_version;
let block_header_version = *block_header_version; let block_header_version = *block_header_version;
VersionCompatInfoV2 { VersionCompatInfoV3 {
version, version,
orig_version, orig_version,
block_header_version, block_header_version,
@ -857,35 +899,53 @@ impl From<&VersionCompatInfo> for VersionCompatInfoV2 {
} }
} }
impl From<Transaction> for TransactionV2 { impl From<&PaymentInfo> for PaymentInfoV3 {
fn from(tx: Transaction) -> TransactionV2 { fn from(data: &PaymentInfo) -> PaymentInfoV3 {
let Transaction { offset, body } = tx; let PaymentInfo {
let body = TransactionBodyV2::from(&body); sender_address,
TransactionV2 { offset, body } receiver_address,
receiver_signature,
} = data;
let sender_address = *sender_address;
let receiver_address = *receiver_address;
let receiver_signature = *receiver_signature;
PaymentInfoV3 {
sender_address,
receiver_address,
receiver_signature,
}
} }
} }
impl From<&Transaction> for TransactionV2 { impl From<Transaction> for TransactionV3 {
fn from(tx: &Transaction) -> TransactionV2 { fn from(tx: Transaction) -> TransactionV3 {
let Transaction { offset, body } = tx;
let body = TransactionBodyV3::from(&body);
TransactionV3 { offset, body }
}
}
impl From<&Transaction> for TransactionV3 {
fn from(tx: &Transaction) -> TransactionV3 {
let Transaction { offset, body } = tx; let Transaction { offset, body } = tx;
let offset = offset.clone(); let offset = offset.clone();
let body = TransactionBodyV2::from(body); let body = TransactionBodyV3::from(body);
TransactionV2 { offset, body } TransactionV3 { offset, body }
} }
} }
impl From<&TransactionBody> for TransactionBodyV2 { impl From<&TransactionBody> for TransactionBodyV3 {
fn from(body: &TransactionBody) -> TransactionBodyV2 { fn from(body: &TransactionBody) -> TransactionBodyV3 {
let TransactionBody { let TransactionBody {
inputs, inputs,
outputs, outputs,
kernels, kernels,
} = body; } = body;
let inputs = map_vec!(inputs, |inp| InputV2::from(inp)); let inputs = map_vec!(inputs, |inp| InputV3::from(inp));
let outputs = map_vec!(outputs, |out| OutputV2::from(out)); let outputs = map_vec!(outputs, |out| OutputV3::from(out));
let kernels = map_vec!(kernels, |kern| TxKernelV2::from(kern)); let kernels = map_vec!(kernels, |kern| TxKernelV3::from(kern));
TransactionBodyV2 { TransactionBodyV3 {
inputs, inputs,
outputs, outputs,
kernels, kernels,
@ -893,21 +953,21 @@ impl From<&TransactionBody> for TransactionBodyV2 {
} }
} }
impl From<&Input> for InputV2 { impl From<&Input> for InputV3 {
fn from(input: &Input) -> InputV2 { fn from(input: &Input) -> InputV3 {
let Input { features, commit } = *input; let Input { features, commit } = *input;
InputV2 { features, commit } InputV3 { features, commit }
} }
} }
impl From<&Output> for OutputV2 { impl From<&Output> for OutputV3 {
fn from(output: &Output) -> OutputV2 { fn from(output: &Output) -> OutputV3 {
let Output { let Output {
features, features,
commit, commit,
proof, proof,
} = *output; } = *output;
OutputV2 { OutputV3 {
features, features,
commit, commit,
proof, proof,
@ -915,8 +975,8 @@ impl From<&Output> for OutputV2 {
} }
} }
impl From<&TxKernel> for TxKernelV2 { impl From<&TxKernel> for TxKernelV3 {
fn from(kernel: &TxKernel) -> TxKernelV2 { fn from(kernel: &TxKernel) -> TxKernelV3 {
let (features, fee, lock_height) = match kernel.features { let (features, fee, lock_height) = match kernel.features {
KernelFeatures::Plain { fee } => (CompatKernelFeatures::Plain, fee, 0), KernelFeatures::Plain { fee } => (CompatKernelFeatures::Plain, fee, 0),
KernelFeatures::Coinbase => (CompatKernelFeatures::Coinbase, 0, 0), KernelFeatures::Coinbase => (CompatKernelFeatures::Coinbase, 0, 0),
@ -924,7 +984,7 @@ impl From<&TxKernel> for TxKernelV2 {
(CompatKernelFeatures::HeightLocked, fee, lock_height) (CompatKernelFeatures::HeightLocked, fee, lock_height)
} }
}; };
TxKernelV2 { TxKernelV3 {
features, features,
fee, fee,
lock_height, lock_height,
@ -935,9 +995,9 @@ impl From<&TxKernel> for TxKernelV2 {
} }
// Versioned to current slate // Versioned to current slate
impl From<SlateV2> for Slate { impl From<SlateV3> for Slate {
fn from(slate: SlateV2) -> Slate { fn from(slate: SlateV3) -> Slate {
let SlateV2 { let SlateV3 {
num_participants, num_participants,
id, id,
tx, tx,
@ -945,11 +1005,17 @@ impl From<SlateV2> for Slate {
fee, fee,
height, height,
lock_height, lock_height,
ttl_cutoff_height,
participant_data, participant_data,
version_info, version_info,
payment_proof,
} = slate; } = slate;
let participant_data = map_vec!(participant_data, |data| ParticipantData::from(data)); let participant_data = map_vec!(participant_data, |data| ParticipantData::from(data));
let version_info = VersionCompatInfo::from(&version_info); let version_info = VersionCompatInfo::from(&version_info);
let payment_proof = match payment_proof {
Some(p) => Some(PaymentInfo::from(&p)),
None => None,
};
let tx = Transaction::from(tx); let tx = Transaction::from(tx);
Slate { Slate {
num_participants, num_participants,
@ -959,15 +1025,17 @@ impl From<SlateV2> for Slate {
fee, fee,
height, height,
lock_height, lock_height,
ttl_cutoff_height,
participant_data, participant_data,
version_info, version_info,
payment_proof,
} }
} }
} }
impl From<&ParticipantDataV2> for ParticipantData { impl From<&ParticipantDataV3> for ParticipantData {
fn from(data: &ParticipantDataV2) -> ParticipantData { fn from(data: &ParticipantDataV3) -> ParticipantData {
let ParticipantDataV2 { let ParticipantDataV3 {
id, id,
public_blind_excess, public_blind_excess,
public_nonce, public_nonce,
@ -992,9 +1060,9 @@ impl From<&ParticipantDataV2> for ParticipantData {
} }
} }
impl From<&VersionCompatInfoV2> for VersionCompatInfo { impl From<&VersionCompatInfoV3> for VersionCompatInfo {
fn from(data: &VersionCompatInfoV2) -> VersionCompatInfo { fn from(data: &VersionCompatInfoV3) -> VersionCompatInfo {
let VersionCompatInfoV2 { let VersionCompatInfoV3 {
version, version,
orig_version, orig_version,
block_header_version, block_header_version,
@ -1010,17 +1078,35 @@ impl From<&VersionCompatInfoV2> for VersionCompatInfo {
} }
} }
impl From<TransactionV2> for Transaction { impl From<&PaymentInfoV3> for PaymentInfo {
fn from(tx: TransactionV2) -> Transaction { fn from(data: &PaymentInfoV3) -> PaymentInfo {
let TransactionV2 { offset, body } = tx; let PaymentInfoV3 {
sender_address,
receiver_address,
receiver_signature,
} = data;
let sender_address = *sender_address;
let receiver_address = *receiver_address;
let receiver_signature = *receiver_signature;
PaymentInfo {
sender_address,
receiver_address,
receiver_signature,
}
}
}
impl From<TransactionV3> for Transaction {
fn from(tx: TransactionV3) -> Transaction {
let TransactionV3 { offset, body } = tx;
let body = TransactionBody::from(&body); let body = TransactionBody::from(&body);
Transaction { offset, body } Transaction { offset, body }
} }
} }
impl From<&TransactionBodyV2> for TransactionBody { impl From<&TransactionBodyV3> for TransactionBody {
fn from(body: &TransactionBodyV2) -> TransactionBody { fn from(body: &TransactionBodyV3) -> TransactionBody {
let TransactionBodyV2 { let TransactionBodyV3 {
inputs, inputs,
outputs, outputs,
kernels, kernels,
@ -1037,16 +1123,16 @@ impl From<&TransactionBodyV2> for TransactionBody {
} }
} }
impl From<&InputV2> for Input { impl From<&InputV3> for Input {
fn from(input: &InputV2) -> Input { fn from(input: &InputV3) -> Input {
let InputV2 { features, commit } = *input; let InputV3 { features, commit } = *input;
Input { features, commit } Input { features, commit }
} }
} }
impl From<&OutputV2> for Output { impl From<&OutputV3> for Output {
fn from(output: &OutputV2) -> Output { fn from(output: &OutputV3) -> Output {
let OutputV2 { let OutputV3 {
features, features,
commit, commit,
proof, proof,
@ -1059,8 +1145,8 @@ impl From<&OutputV2> for Output {
} }
} }
impl From<&TxKernelV2> for TxKernel { impl From<&TxKernelV3> for TxKernel {
fn from(kernel: &TxKernelV2) -> TxKernel { fn from(kernel: &TxKernelV3) -> TxKernel {
let (fee, lock_height) = (kernel.fee, kernel.lock_height); let (fee, lock_height) = (kernel.fee, kernel.lock_height);
let features = match kernel.features { let features = match kernel.features {
CompatKernelFeatures::Plain => KernelFeatures::Plain { fee }, CompatKernelFeatures::Plain => KernelFeatures::Plain { fee },

View file

@ -18,14 +18,16 @@
//! remains for future needs //! remains for future needs
use crate::slate::Slate; use crate::slate::Slate;
use crate::slate_versions::v2::{CoinbaseV2, SlateV2}; use crate::slate_versions::v3::{CoinbaseV3, SlateV3};
use crate::types::CbData; use crate::types::CbData;
pub mod ser;
#[allow(missing_docs)] #[allow(missing_docs)]
pub mod v2; pub mod v3;
/// The most recent version of the slate /// The most recent version of the slate
pub const CURRENT_SLATE_VERSION: u16 = 2; pub const CURRENT_SLATE_VERSION: u16 = 3;
/// The grin block header this slate is intended to be compatible with /// The grin block header this slate is intended to be compatible with
pub const GRIN_BLOCK_HEADER_VERSION: u16 = 2; pub const GRIN_BLOCK_HEADER_VERSION: u16 = 2;
@ -33,8 +35,8 @@ pub const GRIN_BLOCK_HEADER_VERSION: u16 = 2;
/// Existing versions of the slate /// Existing versions of the slate
#[derive(EnumIter, Serialize, Deserialize, Clone, Debug, PartialEq, PartialOrd, Eq, Ord)] #[derive(EnumIter, Serialize, Deserialize, Clone, Debug, PartialEq, PartialOrd, Eq, Ord)]
pub enum SlateVersion { pub enum SlateVersion {
/// V2 (most current) /// V3 (most current)
V2, V3,
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
@ -42,26 +44,26 @@ pub enum SlateVersion {
/// Versions are ordered newest to oldest so serde attempts to /// Versions are ordered newest to oldest so serde attempts to
/// deserialize newer versions first, then falls back to older versions. /// deserialize newer versions first, then falls back to older versions.
pub enum VersionedSlate { pub enum VersionedSlate {
/// Current (Grin 1.1.0 - 2.x (current)) /// Current (3.0.0 Onwards )
V2(SlateV2), V3(SlateV3),
} }
impl VersionedSlate { impl VersionedSlate {
/// Return slate version /// Return slate version
pub fn version(&self) -> SlateVersion { pub fn version(&self) -> SlateVersion {
match *self { match *self {
VersionedSlate::V2(_) => SlateVersion::V2, VersionedSlate::V3(_) => SlateVersion::V3,
} }
} }
/// convert this slate type to a specified older version /// convert this slate type to a specified older version
pub fn into_version(slate: Slate, version: SlateVersion) -> VersionedSlate { pub fn into_version(slate: Slate, version: SlateVersion) -> VersionedSlate {
match version { match version {
SlateVersion::V2 => VersionedSlate::V2(slate.into()), SlateVersion::V3 => VersionedSlate::V3(slate.into()),
// Left here as a reminder of what needs to be inserted on // Left here as a reminder of what needs to be inserted on
// the release of a new slate // the release of a new slate
/*SlateVersion::V0 => { /*SlateVersion::V0 => {
let s = SlateV2::from(slate); let s = SlateV3::from(slate);
let s = SlateV1::from(s); let s = SlateV1::from(s);
let s = SlateV0::from(s); let s = SlateV0::from(s);
VersionedSlate::V0(s) VersionedSlate::V0(s)
@ -73,8 +75,8 @@ impl VersionedSlate {
impl From<VersionedSlate> for Slate { impl From<VersionedSlate> for Slate {
fn from(slate: VersionedSlate) -> Slate { fn from(slate: VersionedSlate) -> Slate {
match slate { match slate {
VersionedSlate::V2(s) => { VersionedSlate::V3(s) => {
let s = SlateV2::from(s); let s = SlateV3::from(s);
Slate::from(s) Slate::from(s)
} // Again, left in as a reminder } // Again, left in as a reminder
/*VersionedSlate::V0(s) => { /*VersionedSlate::V0(s) => {
@ -93,14 +95,14 @@ impl From<VersionedSlate> for Slate {
/// deserialize newer versions first, then falls back to older versions. /// deserialize newer versions first, then falls back to older versions.
pub enum VersionedCoinbase { pub enum VersionedCoinbase {
/// Current supported coinbase version. /// Current supported coinbase version.
V2(CoinbaseV2), V3(CoinbaseV3),
} }
impl VersionedCoinbase { impl VersionedCoinbase {
/// convert this coinbase data to a specific versioned representation for the json api. /// convert this coinbase data to a specific versioned representation for the json api.
pub fn into_version(cb: CbData, version: SlateVersion) -> VersionedCoinbase { pub fn into_version(cb: CbData, version: SlateVersion) -> VersionedCoinbase {
match version { match version {
SlateVersion::V2 => VersionedCoinbase::V2(cb.into()), SlateVersion::V3 => VersionedCoinbase::V3(cb.into()),
} }
} }
} }

View file

@ -0,0 +1,132 @@
// 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.
//! Sane serialization & deserialization of cryptographic structs into hex
/// Serializes an ed25519 PublicKey to and from hex
pub mod dalek_pubkey_serde {
use crate::grin_util::{from_hex, to_hex};
use ed25519_dalek::PublicKey as DalekPublicKey;
use serde::{Deserialize, Deserializer, Serializer};
///
pub fn serialize<S>(key: &DalekPublicKey, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&to_hex(key.to_bytes().to_vec()))
}
///
pub fn deserialize<'de, D>(deserializer: D) -> Result<DalekPublicKey, D::Error>
where
D: Deserializer<'de>,
{
use serde::de::Error;
String::deserialize(deserializer)
.and_then(|string| from_hex(string).map_err(|err| Error::custom(err.to_string())))
.and_then(|bytes: Vec<u8>| {
DalekPublicKey::from_bytes(&bytes).map_err(|err| Error::custom(err.to_string()))
})
}
}
/// Serializes an Option<ed25519_dalek::PublicKey> to and from hex
pub mod option_dalek_pubkey_serde {
use ed25519_dalek::PublicKey as DalekPublicKey;
use serde::de::Error;
use serde::{Deserialize, Deserializer, Serializer};
use crate::grin_util::{from_hex, to_hex};
///
pub fn serialize<S>(key: &Option<DalekPublicKey>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match key {
Some(key) => serializer.serialize_str(&to_hex(key.to_bytes().to_vec())),
None => serializer.serialize_none(),
}
}
///
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<DalekPublicKey>, D::Error>
where
D: Deserializer<'de>,
{
Option::<String>::deserialize(deserializer).and_then(|res| match res {
Some(string) => from_hex(string.to_string())
.map_err(|err| Error::custom(err.to_string()))
.and_then(|bytes: Vec<u8>| {
let mut b = [0u8; 32];
b.copy_from_slice(&bytes[0..32]);
DalekPublicKey::from_bytes(&b)
.map(|val| Some(val))
.map_err(|err| Error::custom(err.to_string()))
}),
None => Ok(None),
})
}
}
// Test serialization methods of components that are being used
#[cfg(test)]
mod test {
use super::*;
use rand::rngs::mock::StepRng;
use crate::grin_util::{secp, static_secp_instance};
use ed25519_dalek::PublicKey as DalekPublicKey;
use ed25519_dalek::SecretKey as DalekSecretKey;
use serde::Deserialize;
use serde_json;
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
struct SerTest {
#[serde(with = "dalek_pubkey_serde")]
pub pub_key: DalekPublicKey,
#[serde(with = "option_dalek_pubkey_serde")]
pub pub_key_opt: Option<DalekPublicKey>,
}
impl SerTest {
pub fn random() -> SerTest {
let secp_inst = static_secp_instance();
let secp = secp_inst.lock();
let mut test_rng = StepRng::new(1234567890u64, 1);
let sec_key = secp::key::SecretKey::new(&secp, &mut test_rng);
let d_skey = DalekSecretKey::from_bytes(&sec_key.0).unwrap();
let d_pub_key: DalekPublicKey = (&d_skey).into();
SerTest {
pub_key: d_pub_key.clone(),
pub_key_opt: Some(d_pub_key),
}
}
}
#[test]
fn ser_dalek_primitives() {
for _ in 0..10 {
let s = SerTest::random();
println!("Before Serialization: {:?}", s);
let serialized = serde_json::to_string_pretty(&s).unwrap();
println!("JSON: {}", serialized);
let deserialized: SerTest = serde_json::from_str(&serialized).unwrap();
println!("After Serialization: {:?}", deserialized);
println!();
assert_eq!(s, deserialized);
}
}
}

View file

@ -12,28 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//! Contains V2 of the slate (grin-wallet 1.1.0) //! Contains V3 of the slate (grin-wallet 3.0.0)
//! Changes from V1: //! Changes from V2:
//! * ParticipantData struct fields serialized as hex strings instead of arrays: //! * Addition of payment_proof (PaymentInfo struct)
//! * public_blind_excess //! * Addition of a u64 ttl_cutoff_height field
//! * public_nonce
//! * part_sig
//! * message_sig
//! * Transaction fields serialized as hex strings instead of arrays:
//! * offset
//! * Input field serialized as hex strings instead of arrays:
//! commit
//! * Output fields serialized as hex strings instead of arrays:
//! commit
//! proof
//! * TxKernel fields serialized as hex strings instead of arrays:
//! commit
//! signature
//! * version field removed
//! * VersionCompatInfo struct created with fields and added to beginning of struct
//! version: u16
//! orig_version: u16,
//! block_header_version: u16,
use crate::grin_core::core::transaction::OutputFeatures; use crate::grin_core::core::transaction::OutputFeatures;
use crate::grin_core::libtx::secp_ser; use crate::grin_core::libtx::secp_ser;
@ -43,19 +25,21 @@ use crate::grin_util::secp::key::PublicKey;
use crate::grin_util::secp::pedersen::{Commitment, RangeProof}; use crate::grin_util::secp::pedersen::{Commitment, RangeProof};
use crate::grin_util::secp::Signature; use crate::grin_util::secp::Signature;
use crate::slate::CompatKernelFeatures; use crate::slate::CompatKernelFeatures;
use crate::slate_versions::ser as dalek_ser;
use ed25519_dalek::PublicKey as DalekPublicKey;
use uuid::Uuid; use uuid::Uuid;
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct SlateV2 { pub struct SlateV3 {
/// Versioning info /// Versioning info
pub version_info: VersionCompatInfoV2, pub version_info: VersionCompatInfoV3,
/// The number of participants intended to take part in this transaction /// The number of participants intended to take part in this transaction
pub num_participants: usize, pub num_participants: usize,
/// Unique transaction ID, selected by sender /// Unique transaction ID, selected by sender
pub id: Uuid, pub id: Uuid,
/// The core transaction data: /// The core transaction data:
/// inputs, outputs, kernels, kernel offset /// inputs, outputs, kernels, kernel offset
pub tx: TransactionV2, pub tx: TransactionV3,
/// base amount (excluding fee) /// base amount (excluding fee)
#[serde(with = "secp_ser::string_or_u64")] #[serde(with = "secp_ser::string_or_u64")]
pub amount: u64, pub amount: u64,
@ -68,14 +52,26 @@ pub struct SlateV2 {
/// Lock height /// Lock height
#[serde(with = "secp_ser::string_or_u64")] #[serde(with = "secp_ser::string_or_u64")]
pub lock_height: u64, pub lock_height: u64,
/// TTL, the block height at which wallets
/// should refuse to process the transaction and unlock all
/// associated outputs
#[serde(with = "secp_ser::string_or_u64")]
pub ttl_cutoff_height: u64,
/// Participant data, each participant in the transaction will /// Participant data, each participant in the transaction will
/// insert their public data here. For now, 0 is sender and 1 /// insert their public data here. For now, 0 is sender and 1
/// is receiver, though this will change for multi-party /// is receiver, though this will change for multi-party
pub participant_data: Vec<ParticipantDataV2>, pub participant_data: Vec<ParticipantDataV3>,
/// Payment Proof
#[serde(default = "default_payment_none")]
pub payment_proof: Option<PaymentInfoV3>,
}
fn default_payment_none() -> Option<PaymentInfoV3> {
None
} }
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct VersionCompatInfoV2 { pub struct VersionCompatInfoV3 {
/// The current version of the slate format /// The current version of the slate format
pub version: u16, pub version: u16,
/// Original version this slate was converted from /// Original version this slate was converted from
@ -85,7 +81,7 @@ pub struct VersionCompatInfoV2 {
} }
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ParticipantDataV2 { pub struct ParticipantDataV3 {
/// Id of participant in the transaction. (For now, 0=sender, 1=rec) /// Id of participant in the transaction. (For now, 0=sender, 1=rec)
#[serde(with = "secp_ser::string_or_u64")] #[serde(with = "secp_ser::string_or_u64")]
pub id: u64, pub id: u64,
@ -105,9 +101,19 @@ pub struct ParticipantDataV2 {
pub message_sig: Option<Signature>, pub message_sig: Option<Signature>,
} }
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct PaymentInfoV3 {
#[serde(with = "dalek_ser::dalek_pubkey_serde")]
pub sender_address: DalekPublicKey,
#[serde(with = "dalek_ser::option_dalek_pubkey_serde")]
pub receiver_address: Option<DalekPublicKey>,
#[serde(with = "secp_ser::option_sig_serde")]
pub receiver_signature: Option<Signature>,
}
/// A transaction /// A transaction
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct TransactionV2 { pub struct TransactionV3 {
/// The kernel "offset" k2 /// The kernel "offset" k2
/// excess is k1G after splitting the key k = k1 + k2 /// excess is k1G after splitting the key k = k1 + k2
#[serde( #[serde(
@ -116,21 +122,21 @@ pub struct TransactionV2 {
)] )]
pub offset: BlindingFactor, pub offset: BlindingFactor,
/// The transaction body - inputs/outputs/kernels /// The transaction body - inputs/outputs/kernels
pub body: TransactionBodyV2, pub body: TransactionBodyV3,
} }
/// TransactionBody is a common abstraction for transaction and block /// TransactionBody is a common abstraction for transaction and block
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct TransactionBodyV2 { pub struct TransactionBodyV3 {
/// List of inputs spent by the transaction. /// List of inputs spent by the transaction.
pub inputs: Vec<InputV2>, pub inputs: Vec<InputV3>,
/// List of outputs the transaction produces. /// List of outputs the transaction produces.
pub outputs: Vec<OutputV2>, pub outputs: Vec<OutputV3>,
/// List of kernels that make up this transaction (usually a single kernel). /// List of kernels that make up this transaction (usually a single kernel).
pub kernels: Vec<TxKernelV2>, pub kernels: Vec<TxKernelV3>,
} }
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct InputV2 { pub struct InputV3 {
/// The features of the output being spent. /// The features of the output being spent.
/// We will check maturity for coinbase output. /// We will check maturity for coinbase output.
pub features: OutputFeatures, pub features: OutputFeatures,
@ -143,7 +149,7 @@ pub struct InputV2 {
} }
#[derive(Debug, Copy, Clone, Serialize, Deserialize)] #[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub struct OutputV2 { pub struct OutputV3 {
/// Options for an output's structure or use /// Options for an output's structure or use
pub features: OutputFeatures, pub features: OutputFeatures,
/// The homomorphic commitment representing the output amount /// The homomorphic commitment representing the output amount
@ -161,7 +167,7 @@ pub struct OutputV2 {
} }
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct TxKernelV2 { pub struct TxKernelV3 {
/// Options for a kernel's structure or use /// Options for a kernel's structure or use
pub features: CompatKernelFeatures, pub features: CompatKernelFeatures,
/// Fee originally included in the transaction this proof is for. /// Fee originally included in the transaction this proof is for.
@ -187,11 +193,11 @@ pub struct TxKernelV2 {
/// A mining node requests new coinbase via the foreign api every time a new candidate block is built. /// A mining node requests new coinbase via the foreign api every time a new candidate block is built.
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct CoinbaseV2 { pub struct CoinbaseV3 {
/// Output /// Output
pub output: OutputV2, pub output: OutputV3,
/// Kernel /// Kernel
pub kernel: TxKernelV2, pub kernel: TxKernelV3,
/// Key Id /// Key Id
pub key_id: Option<Identifier>, pub key_id: Option<Identifier>,
} }

View file

@ -364,7 +364,7 @@ fn owner_v3_lifecycle() -> Result<(), grin_wallet_controller::Error> {
"id": 1, "id": 1,
"method": "finalize_invoice_tx", "method": "finalize_invoice_tx",
"params": { "params": {
"slate": VersionedSlate::into_version(slate, SlateVersion::V2), "slate": VersionedSlate::into_version(slate, SlateVersion::V3),
} }
}); });
let res = let res =