mirror of
https://github.com/mimblewimble/grin-wallet.git
synced 2025-01-20 19:11:09 +03:00
Post Hardfork 3 Cleanup (#490)
* Change versioning on master to 4.1.x development * Remove SlateV3, V3 References from command-line code * continue to remove pre HF3 functionality, remove participant_id from slate, remove is_compact, derive slate state based on slate state field * slate no longer needs explicit compact step * version/build coinbase doctest cleanup * don't attempt to store transaction during tx lock if it doesn't exist * repair incorrectly removed logic * last test fixes (hopefully)
This commit is contained in:
parent
2888882e30
commit
6c9cef1370
24 changed files with 113 additions and 1201 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
@ -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",
|
||||
|
|
14
Cargo.toml
14
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 <mimblewimble@lists.launchpad.net>"]
|
||||
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"]}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "grin_wallet_api"
|
||||
version = "4.0.1-alpha.1"
|
||||
version = "4.1.0-alpha.1"
|
||||
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
||||
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"
|
||||
|
|
|
@ -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<Slate, Error> {
|
||||
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,
|
||||
|
|
|
@ -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<VersionedSlate, ErrorKind>;
|
||||
|
||||
/// For backwards-compatibility. Remove HF3
|
||||
fn finalize_invoice_tx(&self, slate: VersionedSlate) -> Result<VersionedSlate, ErrorKind>;
|
||||
}
|
||||
|
||||
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<VersionedCoinbase, ErrorKind> {
|
||||
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<VersionedSlate, ErrorKind> {
|
||||
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(
|
||||
|
|
|
@ -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<bool, Error> {
|
||||
owner::context_is_invoice(self.wallet_inst.clone(), keychain_mask, slate)
|
||||
}
|
||||
}
|
||||
|
||||
/// attempt to send slate synchronously, starting with TOR and downgrading to HTTP
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "grin_wallet_config"
|
||||
version = "4.0.1-alpha.1"
|
||||
version = "4.1.0-alpha.1"
|
||||
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
||||
description = "Configuration for grin wallet , a simple, private and scalable cryptocurrency implementation based on the MimbleWimble chain format."
|
||||
license = "Apache-2.0"
|
||||
|
@ -16,7 +16,7 @@ serde_derive = "1"
|
|||
toml = "0.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"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "grin_wallet_controller"
|
||||
version = "4.0.1-alpha.1"
|
||||
version = "4.1.0-alpha.1"
|
||||
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
||||
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"
|
||||
|
|
|
@ -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<u64>,
|
||||
pub skip_tor: bool,
|
||||
pub outfile: Option<String>,
|
||||
//TODO: Remove HF3
|
||||
pub output_v4_slate: bool,
|
||||
}
|
||||
|
||||
pub fn send<L, C, K>(
|
||||
|
@ -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<L, C, K>(
|
|||
out_file_override: Option<String>,
|
||||
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,13 +466,8 @@ 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() {
|
||||
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 {
|
||||
|
@ -625,7 +480,6 @@ where
|
|||
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<String>,
|
||||
}
|
||||
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "grin_wallet_impls"
|
||||
version = "4.0.1-alpha.1"
|
||||
version = "4.1.0-alpha.1"
|
||||
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
||||
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" }
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "grin_wallet_libwallet"
|
||||
version = "4.0.1-alpha.1"
|
||||
version = "4.1.0-alpha.1"
|
||||
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
||||
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" }
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
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.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)?;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
sl = owner_finalize(w, keychain_mask, slate)?;
|
||||
}
|
||||
|
|
|
@ -541,9 +541,7 @@ where
|
|||
batch.commit()?;
|
||||
}
|
||||
|
||||
if slate.is_compact() {
|
||||
slate.compact()?;
|
||||
}
|
||||
|
||||
Ok(slate)
|
||||
}
|
||||
|
@ -595,9 +593,7 @@ where
|
|||
batch.commit()?;
|
||||
}
|
||||
|
||||
if slate.is_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());
|
||||
}
|
||||
|
||||
// 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)?;
|
||||
}
|
||||
|
||||
// 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.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::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;
|
||||
}
|
||||
|
||||
Ok(sl)
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -130,10 +130,6 @@ pub struct Slate {
|
|||
pub payment_proof: Option<PaymentInfo>,
|
||||
/// Kernel features arguments
|
||||
pub kernel_features_args: Option<KernelFeaturesArgs>,
|
||||
//TODO: Remove post HF3
|
||||
/// participant ID, only stored for compatibility with V3 slates
|
||||
/// not serialized anywhere
|
||||
pub participant_id: Option<PublicKey>,
|
||||
}
|
||||
|
||||
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<Slate, Error> {
|
||||
|
@ -249,10 +233,16 @@ impl Slate {
|
|||
pub fn upgrade(v_slate: VersionedSlate) -> Result<Slate, Error> {
|
||||
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.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 adjusted_offset = keychain.blind_sum(
|
||||
&BlindSum::new()
|
||||
|
@ -765,7 +739,6 @@ impl From<Slate> 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<SlateV4> for Slate {
|
|||
participant_data,
|
||||
version_info,
|
||||
payment_proof,
|
||||
participant_id: None,
|
||||
kernel_features_args,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<VersionedSlate, Error> {
|
||||
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<VersionedSlate> 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<VersionedSlate> for VersionedBinSlate {
|
|||
fn try_from(slate: VersionedSlate) -> Result<VersionedBinSlate, Error> {
|
||||
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<VersionedBinSlate> 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()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<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<ParticipantDataV3>,
|
||||
/// Payment Proof
|
||||
#[serde(default = "default_payment_none")]
|
||||
pub payment_proof: Option<PaymentInfoV3>,
|
||||
}
|
||||
|
||||
fn default_payment_none() -> Option<PaymentInfoV3> {
|
||||
None
|
||||
}
|
||||
|
||||
fn default_ttl_none() -> Option<u64> {
|
||||
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<Signature>,
|
||||
/// A message for other participants
|
||||
pub message: Option<String>,
|
||||
/// Signature, created with private key corresponding to 'public_blind_excess'
|
||||
#[serde(with = "secp_ser::option_sig_serde")]
|
||||
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::dalek_pubkey_serde")]
|
||||
pub receiver_address: DalekPublicKey,
|
||||
#[serde(with = "dalek_ser::option_dalek_sig_serde")]
|
||||
pub receiver_signature: Option<DalekSignature>,
|
||||
}
|
||||
|
||||
/// 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<InputV3>,
|
||||
/// List of outputs the transaction produces.
|
||||
pub outputs: Vec<OutputV3>,
|
||||
/// List of kernels that make up this transaction (usually a single kernel).
|
||||
pub kernels: Vec<TxKernelV3>,
|
||||
}
|
||||
#[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<Identifier>,
|
||||
}
|
||||
|
||||
// Coinbase data to versioned.
|
||||
impl From<CbData> 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,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<Identifier>,
|
||||
}
|
||||
|
||||
// V3 to V4 For Slate
|
||||
impl From<SlateV3> 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<Vec<CommitsV4>> {
|
||||
fn from(slate: &SlateV3) -> Option<Vec<CommitsV4>> {
|
||||
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<String> = 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<TransactionV3> 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<SlateV3, Error> {
|
||||
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<TransactionV3> = 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<TransactionV3> {
|
||||
fn from(slate: &SlateV4) -> Option<TransactionV3> {
|
||||
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<TransactionV4> 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -502,9 +502,6 @@ pub fn parse_send_args(args: &ArgMatches) -> Result<command::SendArgs, ParseErro
|
|||
// max_outputs
|
||||
let max_outputs = 500;
|
||||
|
||||
// TODO: Remove HF3
|
||||
let output_v4_slate = args.is_present("v4");
|
||||
|
||||
// target slate version to create/send
|
||||
let target_slate_version = {
|
||||
match args.is_present("slate_version") {
|
||||
|
@ -543,7 +540,6 @@ pub fn parse_send_args(args: &ArgMatches) -> Result<command::SendArgs, ParseErro
|
|||
payment_proof_address,
|
||||
ttl_blocks,
|
||||
target_slate_version: target_slate_version,
|
||||
output_v4_slate,
|
||||
outfile,
|
||||
skip_tor: args.is_present("manual"),
|
||||
})
|
||||
|
@ -658,9 +654,6 @@ pub fn parse_issue_invoice_args(
|
|||
}
|
||||
};
|
||||
|
||||
// TODO: Remove HF3
|
||||
let output_v4_slate = args.is_present("v4");
|
||||
|
||||
// target slate version to create
|
||||
let target_slate_version = {
|
||||
match args.is_present("slate_version") {
|
||||
|
@ -682,7 +675,6 @@ pub fn parse_issue_invoice_args(
|
|||
|
||||
Ok(command::IssueInvoiceArgs {
|
||||
dest: dest.into(),
|
||||
output_v4_slate,
|
||||
issue_args: IssueInvoiceTxArgs {
|
||||
dest_acct_name: None,
|
||||
amount,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "grin_wallet_util"
|
||||
version = "4.0.1-alpha.1"
|
||||
version = "4.1.0-alpha.1"
|
||||
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
||||
description = "Util, for generic utilities and to re-export grin crates"
|
||||
license = "Apache-2.0"
|
||||
|
|
Loading…
Reference in a new issue