diff --git a/Cargo.lock b/Cargo.lock index ced7db96..3fd8b542 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1367,7 +1367,7 @@ dependencies = [ [[package]] name = "grin_wallet" -version = "4.0.1-alpha.1" +version = "4.1.0-alpha.1" dependencies = [ "built", "clap", @@ -1395,7 +1395,7 @@ dependencies = [ [[package]] name = "grin_wallet_api" -version = "4.0.1-alpha.1" +version = "4.1.0-alpha.1" dependencies = [ "base64 0.12.1", "chrono", @@ -1419,7 +1419,7 @@ dependencies = [ [[package]] name = "grin_wallet_config" -version = "4.0.1-alpha.1" +version = "4.1.0-alpha.1" dependencies = [ "dirs 2.0.2", "grin_wallet_util", @@ -1432,7 +1432,7 @@ dependencies = [ [[package]] name = "grin_wallet_controller" -version = "4.0.1-alpha.1" +version = "4.1.0-alpha.1" dependencies = [ "chrono", "easy-jsonrpc-mw", @@ -1462,7 +1462,7 @@ dependencies = [ [[package]] name = "grin_wallet_impls" -version = "4.0.1-alpha.1" +version = "4.1.0-alpha.1" dependencies = [ "blake2-rfc", "byteorder", @@ -1497,7 +1497,7 @@ dependencies = [ [[package]] name = "grin_wallet_libwallet" -version = "4.0.1-alpha.1" +version = "4.1.0-alpha.1" dependencies = [ "age", "base64 0.9.3", @@ -1529,7 +1529,7 @@ dependencies = [ [[package]] name = "grin_wallet_util" -version = "4.0.1-alpha.1" +version = "4.1.0-alpha.1" dependencies = [ "data-encoding", "ed25519-dalek", diff --git a/Cargo.toml b/Cargo.toml index 12ce07af..a964329b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin_wallet" -version = "4.0.1-alpha.1" +version = "4.1.0-alpha.1" authors = ["Grin Developers "] description = "Simple, private and scalable cryptocurrency implementation based on the MimbleWimble chain format." license = "Apache-2.0" @@ -31,13 +31,13 @@ semver = "0.10" rustyline = "6" lazy_static = "1" -grin_wallet_api = { path = "./api", version = "4.0.1-alpha.1" } -grin_wallet_impls = { path = "./impls", version = "4.0.1-alpha.1" } -grin_wallet_libwallet = { path = "./libwallet", version = "4.0.1-alpha.1" } -grin_wallet_controller = { path = "./controller", version = "4.0.1-alpha.1" } -grin_wallet_config = { path = "./config", version = "4.0.1-alpha.1" } +grin_wallet_api = { path = "./api", version = "4.1.0-alpha.1" } +grin_wallet_impls = { path = "./impls", version = "4.1.0-alpha.1" } +grin_wallet_libwallet = { path = "./libwallet", version = "4.1.0-alpha.1" } +grin_wallet_controller = { path = "./controller", version = "4.1.0-alpha.1" } +grin_wallet_config = { path = "./config", version = "4.1.0-alpha.1" } -grin_wallet_util = { path = "./util", version = "4.0.1-alpha.1" } +grin_wallet_util = { path = "./util", version = "4.1.0-alpha.1" } [build-dependencies] built = { version = "0.4", features = ["git2"]} diff --git a/api/Cargo.toml b/api/Cargo.toml index b023a24c..34579982 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin_wallet_api" -version = "4.0.1-alpha.1" +version = "4.1.0-alpha.1" authors = ["Grin Developers "] description = "Grin Wallet API" license = "Apache-2.0" @@ -24,10 +24,10 @@ ring = "0.16" base64 = "0.12" ed25519-dalek = "1.0.0-pre.3" -grin_wallet_libwallet = { path = "../libwallet", version = "4.0.1-alpha.1" } -grin_wallet_config = { path = "../config", version = "4.0.1-alpha.1" } -grin_wallet_impls = { path = "../impls", version = "4.0.1-alpha.1" } -grin_wallet_util = { path = "../util", version = "4.0.1-alpha.1" } +grin_wallet_libwallet = { path = "../libwallet", version = "4.1.0-alpha.1" } +grin_wallet_config = { path = "../config", version = "4.1.0-alpha.1" } +grin_wallet_impls = { path = "../impls", version = "4.1.0-alpha.1" } +grin_wallet_util = { path = "../util", version = "4.1.0-alpha.1" } [dev-dependencies] serde_json = "1" diff --git a/api/src/foreign.rs b/api/src/foreign.rs index 9a543062..e27772e7 100644 --- a/api/src/foreign.rs +++ b/api/src/foreign.rs @@ -40,8 +40,6 @@ pub enum ForeignCheckMiddlewareFn { VerifySlateMessages, /// receive_tx ReceiveTx, - /// finalize_invoice_tx (delete HF3) - FinalizeInvoiceTx, /// finalize_tx FinalizeTx, } @@ -441,13 +439,6 @@ where pub fn finalize_tx(&self, slate: &Slate, post_automatically: bool) -> Result { let mut w_lock = self.wallet_inst.lock(); let w = w_lock.lc_provider()?.wallet_inst()?; - if let Some(m) = self.middleware.as_ref() { - m( - ForeignCheckMiddlewareFn::FinalizeInvoiceTx, - w.w2n_client().get_version_info(), - Some(slate), - )?; - } let post_automatically = match self.doctest_mode { true => false, false => post_automatically, diff --git a/api/src/foreign_rpc.rs b/api/src/foreign_rpc.rs index b09677ea..069633ba 100644 --- a/api/src/foreign_rpc.rs +++ b/api/src/foreign_rpc.rs @@ -53,8 +53,7 @@ pub trait ForeignRpc { "Ok": { "foreign_api_version": 2, "supported_slate_versions": [ - "V4", - "V3" + "V4" ] } } @@ -96,15 +95,13 @@ pub trait ForeignRpc { "kernel": { "excess": "08dfe86d732f2dd24bac36aa7502685221369514197c26d33fac03041d47e4b490", "excess_sig": "8f07ddd5e9f5179cff19486034181ed76505baaad53e5d994064127b56c5841be02fa098c54c9bf638e0ee1ad5eb896caa11565f632be7b9cd65643ba371044f", - "features": "Coinbase", - "fee": "0", - "lock_height": "0" + "features": "Coinbase" }, "key_id": "0300000000000000000000000400000000", "output": { - "commit": "08fe198e525a5937d0c5d01fa354394d2679be6df5d42064a0f7550c332fce3d9d", - "features": "Coinbase", - "proof": "9d8488fcb43c9c0f683b9ce62f3c8e047b71f2b4cd94b99a3c9a36aef3bb8361ee17b4489eb5f6d6507250532911acb76f18664604c2ca4215347a5d5d8e417d00ca2d59ec29371286986428b0ec1177fc2e416339ea8542eff8186550ad0d65ffac35d761c38819601d331fd427576e2fff823bbc3faa04f49f5332bd4de46cd4f83d0fd46cdb1dfb87069e95974e4a45e0235db71f5efe5cec83bbb30e152ac50a010ef4e57e33aabbeb894b9114f90bb5c3bb03b009014e358aa3914b1a208eb9d8806fbb679c256d4c1a47b0fce3f1235d58192cb7f615bd7c5dab48486db8962c2a594e69ff70029784a810b4eb76b0516805f3417308cda8acb38b9a3ea061568f0c97f5b46a3beff556dc7ebb58c774f08be472b4b6f603e5f8309c2d1f8d6f52667cb86816b330eca5374148aa898f5bbaf3f23a3ebcdc359ee1e14d73a65596c0ddf51f123234969ac8b557ba9dc53255dd6f5c0d3dd2c035a6d1a1185102612fdca474d018b9f9e81acfa3965d42769f5a303bbaabb78d17e0c026b8be0039c55ad1378c8316101b5206359f89fd1ee239115dde458749a040997be43c039055594cab76f602a0a1ee4f5322f3ab1157342404239adbf8b6786544cd67d9891c2689530e65f2a4b8e52d8551b92ffefb812ffa4a472a10701884151d1fb77d8cdc0b1868cb31b564e98e4c035e0eaa26203b882552c7b69deb0d8ec67cf28d5ec044554f8a91a6cae87eb377d6d906bba6ec94dda24ebfd372727f68334af798b11256d88e17cef7c4fed092128215f992e712ed128db2a9da2f5e8fadea9395bddd294a524dce47f818794c56b03e1253bf0fb9cb8beebc5742e4acf19c24824aa1d41996e839906e24be120a0bdf6800da599ec9ec3d1c4c11571c9f143eadbb554fa3c8c9777994a3f3421d454e4ec54c11b97eea3e4e6ede2d97a2bc" + "com": "08fe198e525a5937d0c5d01fa354394d2679be6df5d42064a0f7550c332fce3d9d", + "features": 1, + "prf": "9d8488fcb43c9c0f683b9ce62f3c8e047b71f2b4cd94b99a3c9a36aef3bb8361ee17b4489eb5f6d6507250532911acb76f18664604c2ca4215347a5d5d8e417d00ca2d59ec29371286986428b0ec1177fc2e416339ea8542eff8186550ad0d65ffac35d761c38819601d331fd427576e2fff823bbc3faa04f49f5332bd4de46cd4f83d0fd46cdb1dfb87069e95974e4a45e0235db71f5efe5cec83bbb30e152ac50a010ef4e57e33aabbeb894b9114f90bb5c3bb03b009014e358aa3914b1a208eb9d8806fbb679c256d4c1a47b0fce3f1235d58192cb7f615bd7c5dab48486db8962c2a594e69ff70029784a810b4eb76b0516805f3417308cda8acb38b9a3ea061568f0c97f5b46a3beff556dc7ebb58c774f08be472b4b6f603e5f8309c2d1f8d6f52667cb86816b330eca5374148aa898f5bbaf3f23a3ebcdc359ee1e14d73a65596c0ddf51f123234969ac8b557ba9dc53255dd6f5c0d3dd2c035a6d1a1185102612fdca474d018b9f9e81acfa3965d42769f5a303bbaabb78d17e0c026b8be0039c55ad1378c8316101b5206359f89fd1ee239115dde458749a040997be43c039055594cab76f602a0a1ee4f5322f3ab1157342404239adbf8b6786544cd67d9891c2689530e65f2a4b8e52d8551b92ffefb812ffa4a472a10701884151d1fb77d8cdc0b1868cb31b564e98e4c035e0eaa26203b882552c7b69deb0d8ec67cf28d5ec044554f8a91a6cae87eb377d6d906bba6ec94dda24ebfd372727f68334af798b11256d88e17cef7c4fed092128215f992e712ed128db2a9da2f5e8fadea9395bddd294a524dce47f818794c56b03e1253bf0fb9cb8beebc5742e4acf19c24824aa1d41996e839906e24be120a0bdf6800da599ec9ec3d1c4c11571c9f143eadbb554fa3c8c9777994a3f3421d454e4ec54c11b97eea3e4e6ede2d97a2bc" } } } @@ -288,9 +285,6 @@ pub trait ForeignRpc { ``` */ fn finalize_tx(&self, slate: VersionedSlate) -> Result; - - /// For backwards-compatibility. Remove HF3 - fn finalize_invoice_tx(&self, slate: VersionedSlate) -> Result; } impl<'a, L, C, K> ForeignRpc for Foreign<'a, L, C, K> @@ -305,7 +299,7 @@ where fn build_coinbase(&self, block_fees: &BlockFees) -> Result { let cb: CbData = Foreign::build_coinbase(self, block_fees).map_err(|e| e.kind())?; - Ok(VersionedCoinbase::into_version(cb, SlateVersion::V3)) + Ok(VersionedCoinbase::into_version(cb, SlateVersion::V4)) } fn receive_tx( @@ -332,14 +326,6 @@ where Foreign::finalize_tx(self, &Slate::from(in_slate), true).map_err(|e| e.kind())?; Ok(VersionedSlate::into_version(out_slate, version).map_err(|e| e.kind())?) } - - //TODO: Delete HF3 - fn finalize_invoice_tx(&self, in_slate: VersionedSlate) -> Result { - let version = in_slate.version(); - let out_slate = - Foreign::finalize_tx(self, &Slate::from(in_slate), false).map_err(|e| e.kind())?; - Ok(VersionedSlate::into_version(out_slate, version).map_err(|e| e.kind())?) - } } fn test_check_middleware( diff --git a/api/src/owner.rs b/api/src/owner.rs index cc0c5c76..62528a94 100644 --- a/api/src/owner.rs +++ b/api/src/owner.rs @@ -2320,17 +2320,6 @@ where ) -> Result<(bool, bool), Error> { owner::verify_payment_proof(self.wallet_inst.clone(), keychain_mask, proof) } - - /// Return whether this transaction is marked as invoice in the context - // TODO: Remove post HF3 - // This will be removed once state is added to slate - pub fn context_is_invoice( - &self, - keychain_mask: Option<&SecretKey>, - slate: &Slate, - ) -> Result { - owner::context_is_invoice(self.wallet_inst.clone(), keychain_mask, slate) - } } /// attempt to send slate synchronously, starting with TOR and downgrading to HTTP diff --git a/config/Cargo.toml b/config/Cargo.toml index efb07029..9185d5f8 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin_wallet_config" -version = "4.0.1-alpha.1" +version = "4.1.0-alpha.1" authors = ["Grin Developers "] description = "Configuration for grin wallet , a simple, private and scalable cryptocurrency implementation based on the MimbleWimble chain format." license = "Apache-2.0" @@ -16,7 +16,7 @@ serde_derive = "1" toml = "0.5" dirs = "2.0" -grin_wallet_util = { path = "../util", version = "4.0.1-alpha.1" } +grin_wallet_util = { path = "../util", version = "4.1.0-alpha.1" } [dev-dependencies] pretty_assertions = "0.6" diff --git a/controller/Cargo.toml b/controller/Cargo.toml index 12db5782..046e0525 100644 --- a/controller/Cargo.toml +++ b/controller/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin_wallet_controller" -version = "4.0.1-alpha.1" +version = "4.1.0-alpha.1" authors = ["Grin Developers "] description = "Controllers for grin wallet instantiation" license = "Apache-2.0" @@ -30,12 +30,12 @@ chrono = { version = "0.4.11", features = ["serde"] } easy-jsonrpc-mw = "0.5.4" lazy_static = "1" -grin_wallet_util = { path = "../util", version = "4.0.1-alpha.1" } +grin_wallet_util = { path = "../util", version = "4.1.0-alpha.1" } -grin_wallet_api = { path = "../api", version = "4.0.1-alpha.1" } -grin_wallet_impls = { path = "../impls", version = "4.0.1-alpha.1" } -grin_wallet_libwallet = { path = "../libwallet", version = "4.0.1-alpha.1" } -grin_wallet_config = { path = "../config", version = "4.0.1-alpha.1" } +grin_wallet_api = { path = "../api", version = "4.1.0-alpha.1" } +grin_wallet_impls = { path = "../impls", version = "4.1.0-alpha.1" } +grin_wallet_libwallet = { path = "../libwallet", version = "4.1.0-alpha.1" } +grin_wallet_config = { path = "../config", version = "4.1.0-alpha.1" } [dev-dependencies] ed25519-dalek = "1.0.0-pre.3" diff --git a/controller/src/command.rs b/controller/src/command.rs index 5721787c..198414c3 100644 --- a/controller/src/command.rs +++ b/controller/src/command.rs @@ -19,17 +19,16 @@ use crate::apiwallet::{try_slatepack_sync_workflow, Owner}; use crate::config::{TorConfig, WalletConfig, WALLET_CONFIG_FILE_NAME}; use crate::core::{core, global}; use crate::error::{Error, ErrorKind}; +use crate::impls::PathToSlatepack; use crate::impls::SlateGetter as _; -use crate::impls::{HttpSlateSender, PathToSlate, PathToSlatepack, SlatePutter}; use crate::keychain; use crate::libwallet::{ - self, InitTxArgs, IssueInvoiceTxArgs, NodeClient, PaymentProof, Slate, SlateVersion, Slatepack, + self, InitTxArgs, IssueInvoiceTxArgs, NodeClient, PaymentProof, Slate, SlateState, Slatepack, SlatepackAddress, Slatepacker, SlatepackerArgs, WalletLCProvider, }; use crate::util::secp::key::SecretKey; use crate::util::{Mutex, ZeroingString}; use crate::{controller, display}; -use grin_wallet_util::OnionV3Address; use serde_json as json; use std::convert::TryFrom; use std::fs::File; @@ -259,8 +258,6 @@ pub struct SendArgs { pub ttl_blocks: Option, pub skip_tor: bool, pub outfile: Option, - //TODO: Remove HF3 - pub output_v4_slate: bool, } pub fn send( @@ -276,126 +273,6 @@ where C: NodeClient + 'static, K: keychain::Keychain + 'static, { - let wallet_inst = owner_api.wallet_inst.clone(); - // Check other version, and if it only supports 3 set the target slate - // version to 3 to avoid removing the transaction object - // TODO: This block is temporary, for the period between the release of v4.0.0 and HF3, - // after which this should be removable - let mut args = args; - - //TODO: Remove block post HF3 - // All this block does is determine whether the slate should be - // output as a V3 Slate for the receiver - let mut tor_sender = None; - let is_pre_fork; - { - is_pre_fork = { - let cur_height = { - libwallet::wallet_lock!(wallet_inst, w); - w.w2n_client().get_chain_tip()?.0 - }; - match global::get_chain_type() { - global::ChainTypes::Mainnet => { - if cur_height < 786240 && !args.output_v4_slate { - true - } else { - false - } - } - global::ChainTypes::Floonet => { - if cur_height < 552960 && !args.output_v4_slate { - true - } else { - false - } - } - _ => false, - } - }; - - if is_pre_fork { - let trailing = match args.dest.ends_with('/') { - true => "", - false => "/", - }; - - let mut address_found = false; - // For sync methods, derive intended endpoint from dest - match SlatepackAddress::try_from(args.dest.as_str()) { - Ok(address) => { - let tor_addr = OnionV3Address::try_from(&address).unwrap(); - // Try pinging the destination via TOR - debug!("Version ping: TOR address is: {}", tor_addr); - match HttpSlateSender::with_socks_proxy( - &tor_addr.to_http_str(), - &tor_config.as_ref().unwrap().socks_proxy_addr, - &tor_config.as_ref().unwrap().send_config_dir, - ) { - Ok(mut sender) => { - let url_str = - format!("{}{}v2/foreign", tor_addr.to_http_str(), trailing); - if let Ok(v) = sender.check_other_version(&url_str) { - if v == SlateVersion::V3 { - args.target_slate_version = Some(3); - } - address_found = true; - } - tor_sender = Some(sender); - } - Err(e) => { - debug!( - "Version ping: Couldn't create slate sender for TOR: {:?}", - e - ); - } - } - } - Err(e) => { - debug!("Version ping: Address is not SlatepackAddress: {:?}", e); - } - } - - // now try http - if !address_found { - // Try pinging the destination via TOR - match HttpSlateSender::new(&args.dest) { - Ok(mut sender) => { - let url_str = format!("{}{}v2/foreign", args.dest, trailing); - match sender.check_other_version(&url_str) { - Ok(v) => { - if v == SlateVersion::V3 { - args.target_slate_version = Some(3); - } - address_found = true; - } - Err(e) => { - debug!( - "Version ping: Couldn't get other version for HTTP: {:?}", - e - ); - } - } - } - Err(e) => { - debug!( - "Version ping: Couldn't create slate sender for HTTP: {:?}", - e - ); - } - } - } - - if !address_found { - // otherwise, determine slate format based on block height - // For files spit out a V3 Slate if we're before HF3, - // Or V4 slate otherwise - if is_pre_fork { - args.target_slate_version = Some(3); - } - } - } - } // end pre HF3 Block - let mut slate = Slate::blank(2, false); controller::owner_single_use(None, keychain_mask, Some(owner_api), |api, m| { if args.estimate_selection_strategies { @@ -460,8 +337,7 @@ where None => None, }; - let res = - try_slatepack_sync_workflow(&slate, &args.dest, tor_config, tor_sender, false, test_mode); + let res = try_slatepack_sync_workflow(&slate, &args.dest, tor_config, None, false, test_mode); match res { Ok(Some(s)) => { @@ -490,7 +366,6 @@ where args.outfile, true, false, - is_pre_fork, )?; } Err(e) => return Err(e.into()), @@ -506,7 +381,6 @@ pub fn output_slatepack( out_file_override: Option, lock: bool, finalizing: bool, - is_pre_fork: bool, ) -> Result<(), libwallet::Error> where L: WalletLCProvider<'static, C, K> + 'static, @@ -547,20 +421,6 @@ where })?; } - // TODO: Remove HF3 - if is_pre_fork { - PathToSlate((&out_file_name).into()).put_tx(&slate, false)?; - println!(); - println!("Transaction file was output to:"); - println!(); - println!("{}", out_file_name); - println!(); - if !finalizing { - println!("Please send this file to the other party manually"); - } - return Ok(()); - } - println!("{}", out_file_name); let mut output = File::create(out_file_name.clone())?; output.write_all(&message.as_bytes())?; @@ -606,26 +466,20 @@ where let mut ret_address = None; let slate = match filename { Some(f) => { - // first try regular slate - remove HF3 - let mut sl = match PathToSlate((&f).into()).get_tx() { - Ok(s) => Some(s.0), //pre HF3, regular slate - Err(_) => None, - }; // otherwise, get slate from slatepack - if sl.is_none() { - controller::owner_single_use(None, keychain_mask, Some(owner_api), |api, m| { - let dec_key = api.get_slatepack_secret_key(m, 0)?; - let packer = Slatepacker::new(SlatepackerArgs { - sender: None, - recipients: vec![], - dec_key: Some(&dec_key), - }); - let pts = PathToSlatepack::new(f.into(), &packer, true); - sl = Some(pts.get_tx()?.0); - ret_address = pts.get_slatepack(true)?.sender; - Ok(()) - })?; - } + let mut sl = None; + controller::owner_single_use(None, keychain_mask, Some(owner_api), |api, m| { + let dec_key = api.get_slatepack_secret_key(m, 0)?; + let packer = Slatepacker::new(SlatepackerArgs { + sender: None, + recipients: vec![], + dec_key: Some(&dec_key), + }); + let pts = PathToSlatepack::new(f.into(), &packer, true); + sl = Some(pts.get_tx()?.0); + ret_address = pts.get_slatepack(true)?.sender; + Ok(()) + })?; sl } None => None, @@ -736,7 +590,6 @@ where args.outfile, false, false, - slate.version_info.version < 4, )?; Ok(()) } @@ -851,14 +704,8 @@ where // Rather than duplicating the entire command, we'll just // try to determine what kind of finalization this is - // based on the slate contents - // for now, we can tell this is an invoice transaction - // if the receipient (participant 1) hasn't completed sigs - let mut is_invoice = false; - controller::owner_single_use(None, keychain_mask, Some(owner_api), |api, m| { - is_invoice = api.context_is_invoice(m, &slate)?; - Ok(()) - })?; + // based on the slate state + let is_invoice = slate.state == SlateState::Invoice2; if is_invoice { let km = match keychain_mask.as_ref() { @@ -905,7 +752,6 @@ where args.outfile, false, true, - slate.version_info.version < 4, )?; Ok(()) @@ -917,8 +763,6 @@ pub struct IssueInvoiceArgs { pub dest: String, /// issue invoice tx args pub issue_args: IssueInvoiceTxArgs, - /// whether to output a V4 slate - pub output_v4_slate: bool, /// output file override pub outfile: Option, } @@ -933,37 +777,7 @@ where C: NodeClient + 'static, K: keychain::Keychain + 'static, { - //TODO: Remove block HF3 - let is_pre_fork = { - let cur_height = { - let wallet_inst = owner_api.wallet_inst.clone(); - libwallet::wallet_lock!(wallet_inst, w); - w.w2n_client().get_chain_tip()?.0 - }; - match global::get_chain_type() { - global::ChainTypes::Mainnet => { - if cur_height < 786240 && !&args.output_v4_slate { - true - } else { - false - } - } - global::ChainTypes::Floonet => { - if cur_height < 552960 && !&args.output_v4_slate { - true - } else { - false - } - } - _ => false, - } - }; - - let mut issue_args = args.issue_args.clone(); - - if is_pre_fork { - issue_args.target_slate_version = Some(3); - } + let issue_args = args.issue_args.clone(); let mut slate = Slate::blank(2, false); controller::owner_single_use(None, keychain_mask, Some(owner_api), |api, m| { @@ -979,7 +793,6 @@ where args.outfile, false, false, - is_pre_fork, )?; Ok(()) } @@ -1098,7 +911,6 @@ where args.outfile, true, false, - slate.version_info.version < 4, )?; Ok(()) } diff --git a/controller/tests/slatepack.rs b/controller/tests/slatepack.rs index 4dc06a50..285c2c97 100644 --- a/controller/tests/slatepack.rs +++ b/controller/tests/slatepack.rs @@ -409,7 +409,7 @@ fn slatepack_exchange_test_impl( wallet::controller::foreign_single_use(wallet2.clone(), mask2_i.clone(), |api| { let res = slate_from_packed(&send_file, use_armored, (&dec_key_2).as_ref())?; - slatepack = res.0; + let slatepack = res.0; slate = res.1; slate = api.receive_tx(&slate, None, None)?; output_slatepack( diff --git a/impls/Cargo.toml b/impls/Cargo.toml index 3865ea6f..7c449765 100644 --- a/impls/Cargo.toml +++ b/impls/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin_wallet_impls" -version = "4.0.1-alpha.1" +version = "4.1.0-alpha.1" authors = ["Grin Developers "] description = "Concrete types derived from libwallet traits" license = "Apache-2.0" @@ -41,6 +41,6 @@ regex = "1.3" timer = "0.2" sysinfo = "0.14" -grin_wallet_util = { path = "../util", version = "4.0.1-alpha.1" } -grin_wallet_config = { path = "../config", version = "4.0.1-alpha.1" } -grin_wallet_libwallet = { path = "../libwallet", version = "4.0.1-alpha.1" } +grin_wallet_util = { path = "../util", version = "4.1.0-alpha.1" } +grin_wallet_config = { path = "../config", version = "4.1.0-alpha.1" } +grin_wallet_libwallet = { path = "../libwallet", version = "4.1.0-alpha.1" } diff --git a/impls/src/adapters/file.rs b/impls/src/adapters/file.rs index 055e61c0..5843ce89 100644 --- a/impls/src/adapters/file.rs +++ b/impls/src/adapters/file.rs @@ -16,11 +16,7 @@ use std::fs::File; use std::io::{Read, Write}; -use crate::libwallet::slate_versions::v3::SlateV3; -use crate::libwallet::slate_versions::v4::SlateV4; -use crate::libwallet::{ - Error, ErrorKind, Slate, SlateState, SlateVersion, VersionedBinSlate, VersionedSlate, -}; +use crate::libwallet::{Error, ErrorKind, Slate, SlateVersion, VersionedBinSlate, VersionedSlate}; use crate::{SlateGetter, SlatePutter}; use grin_wallet_util::byte_ser; use std::convert::TryFrom; @@ -41,56 +37,7 @@ impl SlatePutter for PathToSlate { }*/ let mut pub_tx = File::create(&self.0)?; // TODO: - let out_slate = { - // TODO: Remove post HF3 - if slate.version_info.version == 2 || slate.version_info.version == 3 { - // if the slate we read in in V3 or 2 (holdover from 3.0.0), output a slate V3, - // which can be read by v3.x wallets - let v4_slate = SlateV4::from(slate.clone()); - let mut v3_slate = SlateV3::try_from(&v4_slate)?; - // Fill in V3 participant IDs according to state - if slate.state == SlateState::Invoice1 { - for mut e in v3_slate.participant_data.iter_mut() { - if Some(e.public_blind_excess.clone()) == slate.participant_id { - e.id = 1; - } else { - e.id = 0; - } - } - } - if slate.state == SlateState::Invoice2 { - for mut e in v3_slate.participant_data.iter_mut() { - if Some(e.public_blind_excess.clone()) == slate.participant_id { - e.id = 0; - } else { - e.id = 1; - } - } - } - if slate.state == SlateState::Standard1 { - for mut e in v3_slate.participant_data.iter_mut() { - if Some(e.public_blind_excess.clone()) == slate.participant_id { - e.id = 0; - } else { - e.id = 1; - } - } - } - if slate.state == SlateState::Standard2 { - for mut e in v3_slate.participant_data.iter_mut() { - if Some(e.public_blind_excess.clone()) == slate.participant_id { - e.id = 1; - } else { - e.id = 0; - } - } - } - v3_slate.version_info.version = 3; - VersionedSlate::V3(v3_slate) - } else { - VersionedSlate::into_version(slate.clone(), SlateVersion::V4)? - } - }; + let out_slate = VersionedSlate::into_version(slate.clone(), SlateVersion::V4)?; if as_bin { let bin_slate = VersionedBinSlate::try_from(out_slate).map_err(|_| ErrorKind::SlateSer)?; diff --git a/impls/src/adapters/http.rs b/impls/src/adapters/http.rs index 6697e65d..0313e0d6 100644 --- a/impls/src/adapters/http.rs +++ b/impls/src/adapters/http.rs @@ -148,9 +148,6 @@ impl HttpSlateSender { if supported_slate_versions.contains(&"V4".to_owned()) { return Ok(SlateVersion::V4); } - if supported_slate_versions.contains(&"V3".to_owned()) { - return Ok(SlateVersion::V3); - } let report = "Unable to negotiate slate format with other wallet.".to_string(); error!("{}", report); @@ -189,18 +186,6 @@ impl SlateSender for HttpSlateSender { let slate_send = match self.check_other_version(&url_str)? { SlateVersion::V4 => VersionedSlate::into_version(slate.clone(), SlateVersion::V4)?, - SlateVersion::V3 => { - let mut slate = slate.clone(); - //TODO: Fill out with Slate V4 incompatibilities - // * Will need to set particpant id to 1 manually if this is invoice - // * Set slate height manually - // * Reconcile unknown slate states from V3 - if false { - return Err(ErrorKind::ClientCallback("feature x requested, but other wallet does not support feature x. Please urge other user to upgrade, or re-send tx without feature x".into()).into()); - } - slate.version_info.version = 3; - VersionedSlate::into_version(slate, SlateVersion::V3)? - } }; // Note: not using easy-jsonrpc as don't want the dependencies in this crate let req = match finalize { diff --git a/libwallet/Cargo.toml b/libwallet/Cargo.toml index dbdf588a..093f5551 100644 --- a/libwallet/Cargo.toml +++ b/libwallet/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin_wallet_libwallet" -version = "4.0.1-alpha.1" +version = "4.1.0-alpha.1" authors = ["Grin Developers "] description = "Simple, private and scalable cryptocurrency implementation based on the MimbleWimble chain format." license = "Apache-2.0" @@ -36,6 +36,6 @@ secrecy = "0.6" bech32 = "0.7" byteorder = "1.3" -grin_wallet_util = { path = "../util", version = "4.0.1-alpha.1" } -grin_wallet_config = { path = "../config", version = "4.0.1-alpha.1" } +grin_wallet_util = { path = "../util", version = "4.1.0-alpha.1" } +grin_wallet_config = { path = "../config", version = "4.1.0-alpha.1" } diff --git a/libwallet/src/api_impl/foreign.rs b/libwallet/src/api_impl/foreign.rs index 0e048282..0665b36f 100644 --- a/libwallet/src/api_impl/foreign.rs +++ b/libwallet/src/api_impl/foreign.rs @@ -91,10 +91,7 @@ where } } - // if this is compact mode, we need to create the transaction now - if ret_slate.is_compact() { - ret_slate.tx = Some(Transaction::empty()); - } + ret_slate.tx = Some(Transaction::empty()); let height = w.last_confirmed_height()?; let keychain = w.keychain(keychain_mask)?; @@ -121,15 +118,12 @@ where p.receiver_signature = Some(sig); } - // Can remove amount and fee now - // as well as sender's sig data - if ret_slate.is_compact() { - ret_slate.amount = 0; - ret_slate.fee = 0; - ret_slate.remove_other_sigdata(&keychain, &context.sec_nonce, &context.sec_key)?; - } + ret_slate.amount = 0; + ret_slate.fee = 0; + ret_slate.remove_other_sigdata(&keychain, &context.sec_nonce, &context.sec_key)?; ret_slate.state = SlateState::Standard2; + Ok(ret_slate) } @@ -150,12 +144,12 @@ where let is_invoice = context.is_invoice; if is_invoice { check_ttl(w, &sl)?; - if sl.is_compact() { - let mut temp_ctx = context.clone(); - temp_ctx.sec_key = context.initial_sec_key.clone(); - temp_ctx.sec_nonce = context.initial_sec_nonce.clone(); - selection::repopulate_tx(&mut *w, keychain_mask, &mut sl, &temp_ctx, false)?; - } + + let mut temp_ctx = context.clone(); + temp_ctx.sec_key = context.initial_sec_key.clone(); + temp_ctx.sec_nonce = context.initial_sec_nonce.clone(); + selection::repopulate_tx(&mut *w, keychain_mask, &mut sl, &temp_ctx, false)?; + tx::complete_tx(&mut *w, keychain_mask, &mut sl, &context)?; tx::update_stored_tx(&mut *w, keychain_mask, &context, &mut sl, true)?; { @@ -164,9 +158,7 @@ where batch.commit()?; } sl.state = SlateState::Invoice3; - if sl.is_compact() { - sl.amount = 0; - } + sl.amount = 0; } else { sl = owner_finalize(w, keychain_mask, slate)?; } diff --git a/libwallet/src/api_impl/owner.rs b/libwallet/src/api_impl/owner.rs index 4dfc93dc..652798ca 100644 --- a/libwallet/src/api_impl/owner.rs +++ b/libwallet/src/api_impl/owner.rs @@ -541,9 +541,7 @@ where batch.commit()?; } - if slate.is_compact() { - slate.compact()?; - } + slate.compact()?; Ok(slate) } @@ -595,9 +593,7 @@ where batch.commit()?; } - if slate.is_compact() { - slate.compact()?; - } + slate.compact()?; Ok(slate) } @@ -650,9 +646,7 @@ where } // if this is compact mode, we need to create the transaction now - if ret_slate.is_compact() { - ret_slate.tx = Some(Transaction::empty()); - } + ret_slate.tx = Some(Transaction::empty()); // if self sending, make sure to store 'initiator' keys let context_res = w.get_private_context(keychain_mask, slate.id.as_bytes()); @@ -691,12 +685,8 @@ where } } - // adjust offset with inputs, repopulate inputs (initiator needs them for now) - // TODO: Revisit post-HF3 - if ret_slate.is_compact() { - tx::sub_inputs_from_offset(&mut *w, keychain_mask, &context, &mut ret_slate)?; - selection::repopulate_tx(&mut *w, keychain_mask, &mut ret_slate, &context, false)?; - } + tx::sub_inputs_from_offset(&mut *w, keychain_mask, &context, &mut ret_slate)?; + selection::repopulate_tx(&mut *w, keychain_mask, &mut ret_slate, &context, false)?; // Save the aggsig context in our DB for when we // recieve the transaction back @@ -707,10 +697,8 @@ where } // Can remove amount as well as other sig data now - if ret_slate.is_compact() { - ret_slate.amount = 0; - ret_slate.remove_other_sigdata(&keychain, &context.sec_nonce, &context.sec_key)?; - } + ret_slate.amount = 0; + ret_slate.remove_other_sigdata(&keychain, &context.sec_nonce, &context.sec_key)?; ret_slate.state = SlateState::Invoice2; Ok(ret_slate) @@ -728,16 +716,20 @@ where K: Keychain + 'a, { let context = w.get_private_context(keychain_mask, slate.id.as_bytes())?; - let mut sl = slate.clone(); let mut excess_override = None; - if sl.is_compact() && sl.tx == None { - // attempt to repopulate if we're the initiator + + let mut sl = slate.clone(); + + if sl.tx == None { sl.tx = Some(Transaction::empty()); selection::repopulate_tx(&mut *w, keychain_mask, &mut sl, &context, true)?; - } else if sl.participant_data.len() == 1 { + } + + if slate.participant_data.len() == 1 { // purely for invoice workflow, payer needs the excess back temporarily for storage excess_override = context.calculated_excess; } + let height = w.w2n_client().get_chain_tip()?.0; selection::lock_tx_context( &mut *w, @@ -771,10 +763,8 @@ where // as opposed to locking them prior to this stage, as the excess to this point // will just be the change output - if sl.is_compact() { - tx::sub_inputs_from_offset(&mut *w, keychain_mask, &context, &mut sl)?; - selection::repopulate_tx(&mut *w, keychain_mask, &mut sl, &context, true)?; - } + tx::sub_inputs_from_offset(&mut *w, keychain_mask, &context, &mut sl)?; + selection::repopulate_tx(&mut *w, keychain_mask, &mut sl, &context, true)?; tx::complete_tx(&mut *w, keychain_mask, &mut sl, &context)?; tx::verify_slate_payment_proof(&mut *w, keychain_mask, &parent_key_id, &context, &sl)?; @@ -785,9 +775,8 @@ where batch.commit()?; } sl.state = SlateState::Standard3; - if sl.is_compact() { - sl.amount = 0; - } + sl.amount = 0; + Ok(sl) } diff --git a/libwallet/src/internal/selection.rs b/libwallet/src/internal/selection.rs index 16564ade..339afa09 100644 --- a/libwallet/src/internal/selection.rs +++ b/libwallet/src/internal/selection.rs @@ -55,10 +55,6 @@ where C: NodeClient + 'a, K: Keychain + 'a, { - //TODO: Revise HF3. If we're sending V4 slates, only include - // change outputs in excess sum - let include_inputs_in_sum = !slate.is_compact(); - let (elems, inputs, change_amounts_derivations, fee) = select_send_tx( wallet, keychain_mask, @@ -69,7 +65,7 @@ where change_outputs, selection_strategy_is_use_all, &parent_key_id, - include_inputs_in_sum, + false, )?; // Update the fee on the slate so we account for this when building the tx. diff --git a/libwallet/src/slate.rs b/libwallet/src/slate.rs index b2f98e07..55fbcecb 100644 --- a/libwallet/src/slate.rs +++ b/libwallet/src/slate.rs @@ -130,10 +130,6 @@ pub struct Slate { pub payment_proof: Option, /// Kernel features arguments pub kernel_features_args: Option, - //TODO: Remove post HF3 - /// participant ID, only stored for compatibility with V3 slates - /// not serialized anywhere - pub participant_id: Option, } impl fmt::Display for Slate { @@ -216,10 +212,6 @@ impl Slate { None => Err(ErrorKind::SlateTransactionRequired.into()), } } - /// Whether the slate started life as a compact slate - pub fn is_compact(&self) -> bool { - self.version_info.version >= 4 - } /// number of participants pub fn num_participants(&self) -> u8 { @@ -229,14 +221,6 @@ impl Slate { } } - /// Compact the slate for initial sending, storing the excess + offset explicit - /// and removing my input/output data - /// This info must be stored in the context for repopulation later - pub fn compact(&mut self) -> Result<(), Error> { - self.tx = None; - Ok(()) - } - /// Recieve a slate, upgrade it to the latest version internally /// Throw error if this can't be done pub fn deserialize_upgrade(slate_json: &str) -> Result { @@ -249,10 +233,16 @@ impl Slate { pub fn upgrade(v_slate: VersionedSlate) -> Result { let v4: SlateV4 = match v_slate { VersionedSlate::V4(s) => s, - VersionedSlate::V3(s) => SlateV4::from(s), }; Ok(v4.into()) } + /// Compact the slate for initial sending, storing the excess + offset explicit + /// and removing my input/output data + /// This info must be stored in the context for repopulation later + pub fn compact(&mut self) -> Result<(), Error> { + self.tx = None; + Ok(()) + } /// Create a new slate pub fn blank(num_participants: u8, is_invoice: bool) -> Slate { @@ -280,7 +270,6 @@ impl Slate { block_header_version: GRIN_BLOCK_HEADER_VERSION, }, payment_proof: None, - participant_id: None, kernel_features_args: None, } } @@ -352,15 +341,8 @@ impl Slate { where K: Keychain, { - // Whoever does this first generates the offset - // TODO: Remove HF3 - if self.participant_data.is_empty() && !self.is_compact() { - self.generate_offset(keychain, sec_key, use_test_rng)?; - } // Always choose my part of the offset, and subtract from my excess - if self.is_compact() { - self.generate_offset(keychain, sec_key, use_test_rng)?; - } + self.generate_offset(keychain, sec_key, use_test_rng)?; self.add_participant_info(keychain, &sec_key, &sec_nonce, None)?; Ok(()) } @@ -414,9 +396,8 @@ impl Slate { K: Keychain, { // TODO: Note we're unable to verify fees in this instance - if !self.is_compact() { - self.check_fees()?; - } + // Left here is a reminder that we no longer check fees + // self.check_fees()?; self.verify_part_sigs(keychain.secp())?; let sig_part = aggsig::calculate_partial_sig( @@ -534,7 +515,6 @@ impl Slate { public_nonce: pub_nonce, part_sig: part_sig, }); - self.participant_id = Some(pub_key); Ok(()) } @@ -565,18 +545,12 @@ impl Slate { } }; - if self.is_compact() { - let total_offset = keychain.blind_sum( - &BlindSum::new() - .add_blinding_factor(self.offset.clone()) - .add_blinding_factor(my_offset.clone()), - )?; - self.offset = total_offset; - } else { - //TODO: Remove HF3 - self.tx_or_err_mut()?.offset = my_offset.clone(); - self.offset = my_offset.clone(); - }; + let total_offset = keychain.blind_sum( + &BlindSum::new() + .add_blinding_factor(self.offset.clone()) + .add_blinding_factor(my_offset.clone()), + )?; + self.offset = total_offset; let adjusted_offset = keychain.blind_sum( &BlindSum::new() @@ -765,7 +739,6 @@ impl From for SlateV4 { participant_data, version_info, payment_proof, - participant_id: _participant_id, kernel_features_args, } = slate.clone(); let participant_data = map_vec!(participant_data, |data| ParticipantDataV4::from(data)); @@ -812,7 +785,6 @@ impl From<&Slate> for SlateV4 { participant_data, version_info, payment_proof, - participant_id: _participant_id, kernel_features_args, } = slate; let num_parts = *num_parts; @@ -1090,7 +1062,6 @@ impl From for Slate { participant_data, version_info, payment_proof, - participant_id: None, kernel_features_args, } } diff --git a/libwallet/src/slate_versions/mod.rs b/libwallet/src/slate_versions/mod.rs index 757c609e..94ade6cf 100644 --- a/libwallet/src/slate_versions/mod.rs +++ b/libwallet/src/slate_versions/mod.rs @@ -14,21 +14,18 @@ //! This module contains old slate versions and conversions to the newest slate version //! Used for serialization and deserialization of slates in a backwards compatible way. -//! Versions earlier than V2 are removed for the 2.0.0 release, but versioning code +//! Versions earlier than V3 are removed for the 4.0.0 release, but versioning code //! remains for future needs use crate::slate::Slate; -use crate::slate_versions::v3::{CoinbaseV3, SlateV3}; use crate::slate_versions::v4::{CoinbaseV4, SlateV4}; use crate::slate_versions::v4_bin::SlateV4Bin; use crate::types::CbData; -use crate::{Error, ErrorKind}; +use crate::Error; use std::convert::TryFrom; pub mod ser; -#[allow(missing_docs)] -pub mod v3; #[allow(missing_docs)] pub mod v4; #[allow(missing_docs)] @@ -45,8 +42,6 @@ pub const GRIN_BLOCK_HEADER_VERSION: u16 = 3; pub enum SlateVersion { /// V4 (most current) V4, - /// V3 (3.0.0 - 4.0.0) - V3, } #[derive(Debug, Serialize, Deserialize)] @@ -56,8 +51,6 @@ pub enum SlateVersion { pub enum VersionedSlate { /// Current (4.0.0 Onwards ) V4(SlateV4), - /// V2 (2.0.0 - 3.0.0) - V3(SlateV3), } impl VersionedSlate { @@ -65,7 +58,6 @@ impl VersionedSlate { pub fn version(&self) -> SlateVersion { match *self { VersionedSlate::V4(_) => SlateVersion::V4, - VersionedSlate::V3(_) => SlateVersion::V3, } } @@ -73,11 +65,6 @@ impl VersionedSlate { pub fn into_version(slate: Slate, version: SlateVersion) -> Result { match version { SlateVersion::V4 => Ok(VersionedSlate::V4(slate.into())), - SlateVersion::V3 => { - let s = SlateV4::from(slate); - let s = SlateV3::try_from(&s)?; - Ok(VersionedSlate::V3(s)) - } } } } @@ -86,10 +73,6 @@ impl From for Slate { fn from(slate: VersionedSlate) -> Slate { match slate { VersionedSlate::V4(s) => Slate::from(s), - VersionedSlate::V3(s) => { - let s = SlateV4::from(s); - Slate::from(s) - } } } } @@ -108,11 +91,6 @@ impl TryFrom for VersionedBinSlate { fn try_from(slate: VersionedSlate) -> Result { match slate { VersionedSlate::V4(s) => Ok(VersionedBinSlate::V4(SlateV4Bin(s))), - VersionedSlate::V3(_) => { - return Err( - ErrorKind::Compatibility("V3 Slate does not support binary".to_owned()).into(), - ) - } } } } @@ -132,8 +110,6 @@ impl From for VersionedSlate { pub enum VersionedCoinbase { /// Current supported coinbase version. V4(CoinbaseV4), - /// Previous supported coinbase version. - V3(CoinbaseV3), } impl VersionedCoinbase { @@ -141,7 +117,6 @@ impl VersionedCoinbase { pub fn into_version(cb: CbData, version: SlateVersion) -> VersionedCoinbase { match version { SlateVersion::V4 => VersionedCoinbase::V4(cb.into()), - SlateVersion::V3 => VersionedCoinbase::V3(cb.into()), } } } diff --git a/libwallet/src/slate_versions/v3.rs b/libwallet/src/slate_versions/v3.rs deleted file mode 100644 index 1b79b917..00000000 --- a/libwallet/src/slate_versions/v3.rs +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright 2020 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. - -//! 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; -use crate::grin_keychain::{BlindingFactor, Identifier}; -use crate::grin_util::secp; -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 crate::slate_versions::v4::{OutputV4, TxKernelV4}; -use crate::types::CbData; -use ed25519_dalek::PublicKey as DalekPublicKey; -use ed25519_dalek::Signature as DalekSignature; -use uuid::Uuid; - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct SlateV3 { - /// Versioning info - 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: TransactionV3, - /// base amount (excluding fee) - #[serde(with = "secp_ser::string_or_u64")] - pub amount: u64, - /// fee amount - #[serde(with = "secp_ser::string_or_u64")] - pub fee: u64, - /// Block height for the transaction - #[serde(with = "secp_ser::string_or_u64")] - pub height: u64, - /// 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(default = "default_ttl_none")] - #[serde(with = "secp_ser::opt_string_or_u64")] - pub ttl_cutoff_height: Option, - /// 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, - /// Payment Proof - #[serde(default = "default_payment_none")] - pub payment_proof: Option, -} - -fn default_payment_none() -> Option { - None -} - -fn default_ttl_none() -> Option { - None -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct VersionCompatInfoV3 { - /// The current version of the slate format - pub version: u16, - /// Original version this slate was converted from - pub orig_version: u16, - /// Version of grin block header this slate is compatible with - pub block_header_version: u16, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -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, - /// Public key corresponding to private blinding factor - #[serde(with = "secp_ser::pubkey_serde")] - pub public_blind_excess: PublicKey, - /// Public key corresponding to private nonce - #[serde(with = "secp_ser::pubkey_serde")] - pub public_nonce: PublicKey, - /// Public partial signature - #[serde(with = "secp_ser::option_sig_serde")] - pub part_sig: Option, - /// A message for other participants - pub message: Option, - /// Signature, created with private key corresponding to 'public_blind_excess' - #[serde(with = "secp_ser::option_sig_serde")] - pub message_sig: Option, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct PaymentInfoV3 { - #[serde(with = "dalek_ser::dalek_pubkey_serde")] - pub sender_address: DalekPublicKey, - #[serde(with = "dalek_ser::dalek_pubkey_serde")] - pub receiver_address: DalekPublicKey, - #[serde(with = "dalek_ser::option_dalek_sig_serde")] - pub receiver_signature: Option, -} - -/// A transaction -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransactionV3 { - /// The kernel "offset" k2 - /// excess is k1G after splitting the key k = k1 + k2 - #[serde( - serialize_with = "secp_ser::as_hex", - deserialize_with = "secp_ser::blind_from_hex" - )] - pub offset: BlindingFactor, - /// The transaction body - inputs/outputs/kernels - pub body: TransactionBodyV3, -} - -/// TransactionBody is a common abstraction for transaction and block -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransactionBodyV3 { - /// List of inputs spent by the transaction. - pub inputs: Vec, - /// List of outputs the transaction produces. - pub outputs: Vec, - /// List of kernels that make up this transaction (usually a single kernel). - pub kernels: Vec, -} -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct InputV3 { - /// The features of the output being spent. - /// We will check maturity for coinbase output. - pub features: OutputFeatures, - /// The commit referencing the output being spent. - #[serde( - serialize_with = "secp_ser::as_hex", - deserialize_with = "secp_ser::commitment_from_hex" - )] - pub commit: Commitment, -} - -#[derive(Debug, Copy, Clone, Serialize, Deserialize)] -pub struct OutputV3 { - /// Options for an output's structure or use - pub features: OutputFeatures, - /// The homomorphic commitment representing the output amount - #[serde( - serialize_with = "secp_ser::as_hex", - deserialize_with = "secp_ser::commitment_from_hex" - )] - pub commit: Commitment, - /// A proof that the commitment is in the right range - #[serde( - serialize_with = "secp_ser::as_hex", - deserialize_with = "secp_ser::rangeproof_from_hex" - )] - pub proof: RangeProof, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TxKernelV3 { - /// Options for a kernel's structure or use - pub features: CompatKernelFeatures, - /// Fee originally included in the transaction this proof is for. - #[serde(with = "secp_ser::string_or_u64")] - pub fee: u64, - /// This kernel is not valid earlier than lock_height blocks - /// The max lock_height of all *inputs* to this transaction - #[serde(with = "secp_ser::string_or_u64")] - pub lock_height: u64, - /// Remainder of the sum of all transaction commitments. If the transaction - /// is well formed, amounts components should sum to zero and the excess - /// is hence a valid public key. - #[serde( - serialize_with = "secp_ser::as_hex", - deserialize_with = "secp_ser::commitment_from_hex" - )] - pub excess: Commitment, - /// The signature proving the excess is a valid public key, which signs - /// the transaction fee. - #[serde(with = "secp_ser::sig_serde")] - pub excess_sig: secp::Signature, -} - -/// 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 CoinbaseV3 { - /// Output - pub output: OutputV3, - /// Kernel - pub kernel: TxKernelV3, - /// Key Id - pub key_id: Option, -} - -// Coinbase data to versioned. -impl From for CoinbaseV3 { - fn from(cb: CbData) -> CoinbaseV3 { - let output = OutputV4::from(&cb.output); - let output = OutputV3::from(&output); - let kernel = TxKernelV4::from(&cb.kernel); - let kernel = TxKernelV3::from(&kernel); - CoinbaseV3 { - output, - kernel, - key_id: cb.key_id, - } - } -} diff --git a/libwallet/src/slate_versions/v4.rs b/libwallet/src/slate_versions/v4.rs index ae4a3046..01d50243 100644 --- a/libwallet/src/slate_versions/v4.rs +++ b/libwallet/src/slate_versions/v4.rs @@ -53,9 +53,7 @@ //! * The `receiver_signature` field is renamed to `rsig` //! * `rsig` may be omitted if it has not yet been filled out -use crate::grin_core::core::transaction::KernelFeatures; use crate::grin_core::libtx::secp_ser; -use crate::grin_core::map_vec; use crate::grin_keychain::{BlindingFactor, Identifier}; use crate::grin_util::secp; use crate::grin_util::secp::key::PublicKey; @@ -63,17 +61,10 @@ use crate::grin_util::secp::pedersen::{Commitment, RangeProof}; use crate::grin_util::secp::Signature; use crate::slate::CompatKernelFeatures; use crate::slate_versions::ser; -use crate::{Error, ErrorKind}; use ed25519_dalek::PublicKey as DalekPublicKey; use ed25519_dalek::Signature as DalekSignature; -use std::convert::TryFrom; use uuid::Uuid; -use crate::slate_versions::v3::{ - InputV3, OutputV3, ParticipantDataV3, PaymentInfoV3, SlateV3, TransactionBodyV3, TransactionV3, - TxKernelV3, VersionCompatInfoV3, -}; - #[derive(Serialize, Deserialize, Debug, Clone)] pub struct SlateV4 { // Required Fields @@ -463,471 +454,3 @@ pub struct CoinbaseV4 { /// Key Id pub key_id: Option, } - -// V3 to V4 For Slate -impl From for SlateV4 { - fn from(slate: SlateV3) -> SlateV4 { - let SlateV3 { - version_info, - num_participants, - id, - tx, - amount, - fee, - height: _, - lock_height, - ttl_cutoff_height, - participant_data, - payment_proof, - } = slate.clone(); - let participant_data = map_vec!(participant_data, |data| ParticipantDataV4::from(data)); - let ver = VersionCompatInfoV4::from(&version_info); - - let payment_proof = match payment_proof { - Some(p) => Some(PaymentInfoV4::from(&p)), - None => None, - }; - let ttl_cutoff_height = match ttl_cutoff_height { - None => 0, - Some(n) => n, - }; - let (feat, feat_args) = match lock_height { - 0 => (0, None), - n => (2, Some(KernelFeaturesArgsV4 { lock_hgt: n })), - }; - SlateV4 { - ver, - num_parts: num_participants as u8, - id, - sta: SlateStateV4::Unknown, - coms: (&slate).into(), - amt: amount, - fee, - feat, - ttl: ttl_cutoff_height, - off: tx.offset, - sigs: participant_data, - proof: payment_proof, - feat_args, - } - } -} - -impl From<&SlateV3> for Option> { - fn from(slate: &SlateV3) -> Option> { - let mut ret_vec = vec![]; - for i in slate.tx.body.inputs.iter() { - ret_vec.push(CommitsV4 { - f: i.features.into(), - c: i.commit, - p: None, - }); - } - for o in slate.tx.body.outputs.iter() { - ret_vec.push(CommitsV4 { - f: o.features.into(), - c: o.commit, - p: Some(o.proof), - }); - } - Some(ret_vec) - } -} - -impl From<&ParticipantDataV3> for ParticipantDataV4 { - fn from(data: &ParticipantDataV3) -> ParticipantDataV4 { - let ParticipantDataV3 { - id, - public_blind_excess, - public_nonce, - part_sig, - message, - message_sig, - } = data; - let _id = *id; - let public_blind_excess = *public_blind_excess; - let public_nonce = *public_nonce; - let part_sig = *part_sig; - let _message: Option = message.as_ref().map(|t| String::from(&**t)); - let _message_sig = *message_sig; - ParticipantDataV4 { - xs: public_blind_excess, - nonce: public_nonce, - part: part_sig, - } - } -} - -impl From<&VersionCompatInfoV3> for VersionCompatInfoV4 { - fn from(data: &VersionCompatInfoV3) -> VersionCompatInfoV4 { - let VersionCompatInfoV3 { - version, - orig_version, - block_header_version, - } = data; - let version = *version; - let _orig_version = *orig_version; - let block_header_version = *block_header_version; - VersionCompatInfoV4 { - version, - block_header_version, - } - } -} - -impl From for TransactionV4 { - fn from(tx: TransactionV3) -> TransactionV4 { - let TransactionV3 { offset, body } = tx; - let body = TransactionBodyV4::from(&body); - TransactionV4 { offset, body } - } -} - -impl From<&TransactionBodyV3> for TransactionBodyV4 { - fn from(body: &TransactionBodyV3) -> TransactionBodyV4 { - let TransactionBodyV3 { - inputs, - outputs, - kernels, - } = body; - - let inputs = map_vec!(inputs, |inp| InputV4::from(inp)); - let outputs = map_vec!(outputs, |out| OutputV4::from(out)); - let kernels = map_vec!(kernels, |kern| TxKernelV4::from(kern)); - TransactionBodyV4 { - ins: inputs, - outs: outputs, - kers: kernels, - } - } -} - -impl From<&InputV3> for InputV4 { - fn from(input: &InputV3) -> InputV4 { - let InputV3 { features, commit } = *input; - InputV4 { - features: features.into(), - commit, - } - } -} - -impl From<&OutputV3> for OutputV4 { - fn from(output: &OutputV3) -> OutputV4 { - let OutputV3 { - features, - commit, - proof, - } = *output; - OutputV4 { - features: features.into(), - com: commit, - prf: proof, - } - } -} - -impl From<&TxKernelV3> for TxKernelV4 { - fn from(kernel: &TxKernelV3) -> TxKernelV4 { - let (fee, lock_height) = (kernel.fee, kernel.lock_height); - TxKernelV4 { - features: kernel.features, - fee, - lock_height, - excess: kernel.excess, - excess_sig: kernel.excess_sig, - } - } -} - -impl From<&PaymentInfoV3> for PaymentInfoV4 { - fn from(input: &PaymentInfoV3) -> PaymentInfoV4 { - let PaymentInfoV3 { - sender_address, - receiver_address, - receiver_signature, - } = *input; - PaymentInfoV4 { - saddr: sender_address, - raddr: receiver_address, - rsig: receiver_signature, - } - } -} - -// V4 to V3 -#[allow(unused_variables)] -impl TryFrom<&SlateV4> for SlateV3 { - type Error = Error; - fn try_from(slate: &SlateV4) -> Result { - let SlateV4 { - num_parts: num_participants, - id, - sta: _, - coms, - amt: amount, - fee, - feat, - ttl: ttl_cutoff_height, - off: offset, - sigs: participant_data, - ver, - proof: payment_proof, - feat_args, - } = slate; - let num_participants = match *num_participants { - 0 => 2, - n => n, - }; - let id = *id; - let amount = *amount; - let fee = *fee; - - // Match on kernel feature variant: - // 0: plain - // 1: coinbase (invalid) - // 2: height locked (with associated lock_height) - // 3: NRD (with associated relative_height) - // Anything else is unknown. - let lock_height = match feat { - 0 => 0, - 1 => return Err(ErrorKind::InvalidKernelFeatures(1).into()), - 2 => match feat_args { - None => return Err(ErrorKind::KernelFeaturesMissing("lock_hgt".to_owned()).into()), - Some(h) => h.lock_hgt, - }, - 3 => match feat_args { - None => return Err(ErrorKind::KernelFeaturesMissing("lock_hgt".to_owned()).into()), - Some(h) => h.lock_hgt, - }, - n => return Err(ErrorKind::UnknownKernelFeatures(*n).into()), - }; - - let participant_data = map_vec!(participant_data, |data| ParticipantDataV3::from(data)); - let version_info = VersionCompatInfoV3::from(ver); - let payment_proof = match payment_proof { - Some(p) => Some(PaymentInfoV3::from(p)), - None => None, - }; - let tx: Option = slate.into(); - let tx = match tx { - Some(t) => TransactionV3::from(t), - None => { - return Err(ErrorKind::SlateInvalidDowngrade( - "Full transaction info required".to_owned(), - ) - .into()) - } - }; - - let ttl_cutoff_height = match *ttl_cutoff_height { - 0 => None, - n => Some(n), - }; - - Ok(SlateV3 { - num_participants: num_participants as usize, - id, - tx, - amount, - fee, - height: 0, - lock_height, - ttl_cutoff_height, - participant_data, - version_info, - payment_proof, - }) - } -} - -// Node's Transaction object and lock height to SlateV4 `coms` -impl From<&SlateV4> for Option { - fn from(slate: &SlateV4) -> Option { - let res = crate::slate::tx_from_slate_v4(slate); - let tx = match res { - Some(tx) => tx, - None => return None, - }; - let mut out_fee = 0; - let mut out_lock_height = 0; - let txv3 = TransactionV3 { - offset: tx.offset, - body: TransactionBodyV3 { - inputs: tx - .body - .inputs - .iter() - .map(|i| InputV3 { - features: i.features, - commit: i.commit, - }) - .collect(), - outputs: tx - .body - .outputs - .iter() - .map(|o| OutputV3 { - features: o.features, - commit: o.commit, - proof: o.proof, - }) - .collect(), - kernels: tx - .body - .kernels - .iter() - .map(|k| TxKernelV3 { - features: match k.features { - KernelFeatures::Plain { fee } => { - out_fee = fee; - CompatKernelFeatures::Plain - } - KernelFeatures::Coinbase => CompatKernelFeatures::Coinbase, - KernelFeatures::HeightLocked { fee, lock_height } => { - out_fee = fee; - out_lock_height = lock_height; - CompatKernelFeatures::HeightLocked - } - KernelFeatures::NoRecentDuplicate { - fee, - relative_height, - } => { - out_fee = fee; - out_lock_height = relative_height.into(); - CompatKernelFeatures::NoRecentDuplicate - } - }, - fee: out_fee, - lock_height: out_lock_height, - excess: k.excess, - excess_sig: k.excess_sig, - }) - .collect(), - }, - }; - Some(txv3) - } -} - -impl From<&ParticipantDataV4> for ParticipantDataV3 { - fn from(data: &ParticipantDataV4) -> ParticipantDataV3 { - let ParticipantDataV4 { - xs: public_blind_excess, - nonce: public_nonce, - part: part_sig, - } = data; - let public_blind_excess = *public_blind_excess; - let public_nonce = *public_nonce; - let part_sig = *part_sig; - ParticipantDataV3 { - id: 0, - public_blind_excess, - public_nonce, - part_sig, - message: None, - message_sig: None, - } - } -} - -impl From<&VersionCompatInfoV4> for VersionCompatInfoV3 { - fn from(data: &VersionCompatInfoV4) -> VersionCompatInfoV3 { - let VersionCompatInfoV4 { - version, - block_header_version, - } = data; - let version = *version; - let orig_version = version; - let block_header_version = *block_header_version; - VersionCompatInfoV3 { - version, - orig_version, - block_header_version, - } - } -} - -impl From for TransactionV3 { - fn from(tx: TransactionV4) -> TransactionV3 { - let TransactionV4 { offset, body } = tx; - let body = TransactionBodyV3::from(&body); - TransactionV3 { offset, body } - } -} - -impl From<&TransactionV4> for TransactionV3 { - fn from(tx: &TransactionV4) -> TransactionV3 { - let TransactionV4 { offset, body } = tx; - let offset = offset.clone(); - let body = TransactionBodyV3::from(body); - TransactionV3 { offset, body } - } -} - -impl From<&TransactionBodyV4> for TransactionBodyV3 { - fn from(body: &TransactionBodyV4) -> TransactionBodyV3 { - let TransactionBodyV4 { ins, outs, kers } = body; - - let inputs = map_vec!(ins, |inp| InputV3::from(inp)); - let outputs = map_vec!(outs, |out| OutputV3::from(out)); - let kernels = map_vec!(kers, |kern| TxKernelV3::from(kern)); - TransactionBodyV3 { - inputs, - outputs, - kernels, - } - } -} - -impl From<&InputV4> for InputV3 { - fn from(input: &InputV4) -> InputV3 { - let InputV4 { features, commit } = *input; - InputV3 { - features: features.into(), - commit, - } - } -} - -impl From<&OutputV4> for OutputV3 { - fn from(output: &OutputV4) -> OutputV3 { - let OutputV4 { - features, - com: commit, - prf: proof, - } = *output; - OutputV3 { - features: features.into(), - commit, - proof, - } - } -} - -impl From<&TxKernelV4> for TxKernelV3 { - fn from(kernel: &TxKernelV4) -> TxKernelV3 { - TxKernelV3 { - features: kernel.features, - fee: kernel.fee, - lock_height: kernel.lock_height, - excess: kernel.excess, - excess_sig: kernel.excess_sig, - } - } -} - -impl From<&PaymentInfoV4> for PaymentInfoV3 { - fn from(input: &PaymentInfoV4) -> PaymentInfoV3 { - let PaymentInfoV4 { - saddr: sender_address, - raddr: receiver_address, - rsig: receiver_signature, - } = *input; - PaymentInfoV3 { - sender_address, - receiver_address, - receiver_signature, - } - } -} diff --git a/src/bin/grin-wallet.yml b/src/bin/grin-wallet.yml index 2009e92f..03d34a53 100644 --- a/src/bin/grin-wallet.yml +++ b/src/bin/grin-wallet.yml @@ -150,11 +150,6 @@ subcommands: short: u long: outfile takes_value: true - #TODO: Remove HF3 - - v4: - help: Output a V4 slate prior to HF3 block - long: v4 - takes_value: false - unpack: about: Unpack and display an armored Slatepack Message, decrypting if possible args: @@ -217,11 +212,6 @@ subcommands: short: u long: outfile takes_value: true - #TODO: Remove HF3 - - v4: - help: Output a V4 slate prior to HF3 block - long: v4 - takes_value: false - pay: about: Spend coins to pay the provided invoice transaction args: diff --git a/src/cmd/wallet_args.rs b/src/cmd/wallet_args.rs index 8ceaeb4a..293a95cb 100644 --- a/src/cmd/wallet_args.rs +++ b/src/cmd/wallet_args.rs @@ -502,9 +502,6 @@ pub fn parse_send_args(args: &ArgMatches) -> Result Result"] description = "Util, for generic utilities and to re-export grin crates" license = "Apache-2.0"