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 = [
"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)",
"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_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"grin_wallet_config 3.0.0-alpha.1",

View file

@ -53,7 +53,7 @@ pub trait ForeignRpc {
"Ok": {
"foreign_api_version": 2,
"supported_slate_versions": [
"V2"
"V3"
]
}
}
@ -133,6 +133,8 @@ pub trait ForeignRpc {
"height": "4",
"id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "4",
"ttl_cutoff_height": "0",
"payment_proof": null,
"num_participants": 2,
"participant_data": [
{
@ -251,6 +253,8 @@ pub trait ForeignRpc {
"fee": "7000000",
"height": "5",
"lock_height": "0",
"ttl_cutoff_height": "0",
"payment_proof": null,
"participant_data": [
{
"id": "0",
@ -279,6 +283,8 @@ pub trait ForeignRpc {
"height": "5",
"id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "0",
"ttl_cutoff_height": "0",
"payment_proof": null,
"num_participants": 2,
"participant_data": [
{
@ -414,6 +420,8 @@ pub trait ForeignRpc {
"fee": "7000000",
"height": "5",
"lock_height": "0",
"ttl_cutoff_height": "0",
"payment_proof": null,
"participant_data": [
{
"id": "1",
@ -447,6 +455,8 @@ pub trait ForeignRpc {
"height": "5",
"id": "0436430c-2b02-624c-2032-570501212b00",
"lock_height": "0",
"ttl_cutoff_height": "0",
"payment_proof": null,
"num_participants": 2,
"participant_data": [
{
@ -529,7 +539,7 @@ where
fn build_coinbase(&self, block_fees: &BlockFees) -> Result<VersionedCoinbase, ErrorKind> {
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> {

View file

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

View file

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

View file

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

View file

@ -111,7 +111,7 @@ impl HttpSlateSender {
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.");
error!("{}", report);
return Err(ErrorKind::ClientCallback(report).into());

View file

@ -26,7 +26,7 @@ use crate::core::{pow, ser};
use crate::keychain::Keychain;
use crate::libwallet;
use crate::libwallet::api_impl::foreign;
use crate::libwallet::slate_versions::v2::SlateV2;
use crate::libwallet::slate_versions::v3::SlateV3;
use crate::libwallet::{
NodeClient, NodeVersionInfo, Slate, TxWrapper, WalletInst, WalletLCProvider,
};
@ -216,7 +216,7 @@ where
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()),
)?;
@ -239,7 +239,7 @@ where
sender_id: m.dest,
dest: m.sender_id,
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(),
dest: dest.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();
@ -403,7 +403,7 @@ impl LocalWalletClient {
let r = self.rx.lock();
let m = r.recv().unwrap();
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()),
)?;
Ok(Slate::from(slate))

View file

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

View file

@ -18,14 +18,16 @@
//! remains for future needs
use crate::slate::Slate;
use crate::slate_versions::v2::{CoinbaseV2, SlateV2};
use crate::slate_versions::v3::{CoinbaseV3, SlateV3};
use crate::types::CbData;
pub mod ser;
#[allow(missing_docs)]
pub mod v2;
pub mod v3;
/// 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
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
#[derive(EnumIter, Serialize, Deserialize, Clone, Debug, PartialEq, PartialOrd, Eq, Ord)]
pub enum SlateVersion {
/// V2 (most current)
V2,
/// V3 (most current)
V3,
}
#[derive(Debug, Serialize, Deserialize)]
@ -42,26 +44,26 @@ pub enum SlateVersion {
/// Versions are ordered newest to oldest so serde attempts to
/// deserialize newer versions first, then falls back to older versions.
pub enum VersionedSlate {
/// Current (Grin 1.1.0 - 2.x (current))
V2(SlateV2),
/// Current (3.0.0 Onwards )
V3(SlateV3),
}
impl VersionedSlate {
/// Return slate version
pub fn version(&self) -> SlateVersion {
match *self {
VersionedSlate::V2(_) => SlateVersion::V2,
VersionedSlate::V3(_) => SlateVersion::V3,
}
}
/// 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::V3 => VersionedSlate::V3(slate.into()),
// Left here as a reminder of what needs to be inserted on
// the release of a new slate
/*SlateVersion::V0 => {
let s = SlateV2::from(slate);
let s = SlateV3::from(slate);
let s = SlateV1::from(s);
let s = SlateV0::from(s);
VersionedSlate::V0(s)
@ -73,8 +75,8 @@ impl VersionedSlate {
impl From<VersionedSlate> for Slate {
fn from(slate: VersionedSlate) -> Slate {
match slate {
VersionedSlate::V2(s) => {
let s = SlateV2::from(s);
VersionedSlate::V3(s) => {
let s = SlateV3::from(s);
Slate::from(s)
} // Again, left in as a reminder
/*VersionedSlate::V0(s) => {
@ -93,14 +95,14 @@ impl From<VersionedSlate> for Slate {
/// deserialize newer versions first, then falls back to older versions.
pub enum VersionedCoinbase {
/// Current supported coinbase version.
V2(CoinbaseV2),
V3(CoinbaseV3),
}
impl VersionedCoinbase {
/// convert this coinbase data to a specific versioned representation for the json api.
pub fn into_version(cb: CbData, version: SlateVersion) -> VersionedCoinbase {
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
// limitations under the License.
//! Contains V2 of the slate (grin-wallet 1.1.0)
//! Changes from V1:
//! * ParticipantData struct fields serialized as hex strings instead of arrays:
//! * public_blind_excess
//! * 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,
//! Contains V3 of the slate (grin-wallet 3.0.0)
//! Changes from V2:
//! * Addition of payment_proof (PaymentInfo struct)
//! * Addition of a u64 ttl_cutoff_height field
use crate::grin_core::core::transaction::OutputFeatures;
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::Signature;
use crate::slate::CompatKernelFeatures;
use crate::slate_versions::ser as dalek_ser;
use ed25519_dalek::PublicKey as DalekPublicKey;
use uuid::Uuid;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct SlateV2 {
pub struct SlateV3 {
/// Versioning info
pub version_info: VersionCompatInfoV2,
pub version_info: VersionCompatInfoV3,
/// The number of participants intended to take part in this transaction
pub num_participants: usize,
/// Unique transaction ID, selected by sender
pub id: Uuid,
/// The core transaction data:
/// inputs, outputs, kernels, kernel offset
pub tx: TransactionV2,
pub tx: TransactionV3,
/// base amount (excluding fee)
#[serde(with = "secp_ser::string_or_u64")]
pub amount: u64,
@ -68,14 +52,26 @@ pub struct SlateV2 {
/// Lock height
#[serde(with = "secp_ser::string_or_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
/// 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<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)]
pub struct VersionCompatInfoV2 {
pub struct VersionCompatInfoV3 {
/// The current version of the slate format
pub version: u16,
/// Original version this slate was converted from
@ -85,7 +81,7 @@ pub struct VersionCompatInfoV2 {
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ParticipantDataV2 {
pub struct ParticipantDataV3 {
/// Id of participant in the transaction. (For now, 0=sender, 1=rec)
#[serde(with = "secp_ser::string_or_u64")]
pub id: u64,
@ -105,9 +101,19 @@ pub struct ParticipantDataV2 {
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
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct TransactionV2 {
pub struct TransactionV3 {
/// The kernel "offset" k2
/// excess is k1G after splitting the key k = k1 + k2
#[serde(
@ -116,21 +122,21 @@ pub struct TransactionV2 {
)]
pub offset: BlindingFactor,
/// The transaction body - inputs/outputs/kernels
pub body: TransactionBodyV2,
pub body: TransactionBodyV3,
}
/// TransactionBody is a common abstraction for transaction and block
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct TransactionBodyV2 {
pub struct TransactionBodyV3 {
/// List of inputs spent by the transaction.
pub inputs: Vec<InputV2>,
pub inputs: Vec<InputV3>,
/// 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).
pub kernels: Vec<TxKernelV2>,
pub kernels: Vec<TxKernelV3>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct InputV2 {
pub struct InputV3 {
/// The features of the output being spent.
/// We will check maturity for coinbase output.
pub features: OutputFeatures,
@ -143,7 +149,7 @@ pub struct InputV2 {
}
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub struct OutputV2 {
pub struct OutputV3 {
/// Options for an output's structure or use
pub features: OutputFeatures,
/// The homomorphic commitment representing the output amount
@ -161,7 +167,7 @@ pub struct OutputV2 {
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct TxKernelV2 {
pub struct TxKernelV3 {
/// Options for a kernel's structure or use
pub features: CompatKernelFeatures,
/// 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.
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct CoinbaseV2 {
pub struct CoinbaseV3 {
/// Output
pub output: OutputV2,
pub output: OutputV3,
/// Kernel
pub kernel: TxKernelV2,
pub kernel: TxKernelV3,
/// Key Id
pub key_id: Option<Identifier>,
}

View file

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