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]]
|
[[package]]
|
||||||
name = "grin_wallet"
|
name = "grin_wallet"
|
||||||
version = "4.0.1-alpha.1"
|
version = "4.1.0-alpha.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"built",
|
"built",
|
||||||
"clap",
|
"clap",
|
||||||
|
@ -1395,7 +1395,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "grin_wallet_api"
|
name = "grin_wallet_api"
|
||||||
version = "4.0.1-alpha.1"
|
version = "4.1.0-alpha.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.12.1",
|
"base64 0.12.1",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
@ -1419,7 +1419,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "grin_wallet_config"
|
name = "grin_wallet_config"
|
||||||
version = "4.0.1-alpha.1"
|
version = "4.1.0-alpha.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs 2.0.2",
|
"dirs 2.0.2",
|
||||||
"grin_wallet_util",
|
"grin_wallet_util",
|
||||||
|
@ -1432,7 +1432,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "grin_wallet_controller"
|
name = "grin_wallet_controller"
|
||||||
version = "4.0.1-alpha.1"
|
version = "4.1.0-alpha.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"easy-jsonrpc-mw",
|
"easy-jsonrpc-mw",
|
||||||
|
@ -1462,7 +1462,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "grin_wallet_impls"
|
name = "grin_wallet_impls"
|
||||||
version = "4.0.1-alpha.1"
|
version = "4.1.0-alpha.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"blake2-rfc",
|
"blake2-rfc",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
@ -1497,7 +1497,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "grin_wallet_libwallet"
|
name = "grin_wallet_libwallet"
|
||||||
version = "4.0.1-alpha.1"
|
version = "4.1.0-alpha.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"age",
|
"age",
|
||||||
"base64 0.9.3",
|
"base64 0.9.3",
|
||||||
|
@ -1529,7 +1529,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "grin_wallet_util"
|
name = "grin_wallet_util"
|
||||||
version = "4.0.1-alpha.1"
|
version = "4.1.0-alpha.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"data-encoding",
|
"data-encoding",
|
||||||
"ed25519-dalek",
|
"ed25519-dalek",
|
||||||
|
|
14
Cargo.toml
14
Cargo.toml
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "grin_wallet"
|
name = "grin_wallet"
|
||||||
version = "4.0.1-alpha.1"
|
version = "4.1.0-alpha.1"
|
||||||
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
||||||
description = "Simple, private and scalable cryptocurrency implementation based on the MimbleWimble chain format."
|
description = "Simple, private and scalable cryptocurrency implementation based on the MimbleWimble chain format."
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
@ -31,13 +31,13 @@ semver = "0.10"
|
||||||
rustyline = "6"
|
rustyline = "6"
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
|
|
||||||
grin_wallet_api = { path = "./api", version = "4.0.1-alpha.1" }
|
grin_wallet_api = { path = "./api", version = "4.1.0-alpha.1" }
|
||||||
grin_wallet_impls = { path = "./impls", version = "4.0.1-alpha.1" }
|
grin_wallet_impls = { path = "./impls", version = "4.1.0-alpha.1" }
|
||||||
grin_wallet_libwallet = { path = "./libwallet", version = "4.0.1-alpha.1" }
|
grin_wallet_libwallet = { path = "./libwallet", version = "4.1.0-alpha.1" }
|
||||||
grin_wallet_controller = { path = "./controller", version = "4.0.1-alpha.1" }
|
grin_wallet_controller = { path = "./controller", version = "4.1.0-alpha.1" }
|
||||||
grin_wallet_config = { path = "./config", version = "4.0.1-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]
|
[build-dependencies]
|
||||||
built = { version = "0.4", features = ["git2"]}
|
built = { version = "0.4", features = ["git2"]}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "grin_wallet_api"
|
name = "grin_wallet_api"
|
||||||
version = "4.0.1-alpha.1"
|
version = "4.1.0-alpha.1"
|
||||||
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
||||||
description = "Grin Wallet API"
|
description = "Grin Wallet API"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
@ -24,10 +24,10 @@ ring = "0.16"
|
||||||
base64 = "0.12"
|
base64 = "0.12"
|
||||||
ed25519-dalek = "1.0.0-pre.3"
|
ed25519-dalek = "1.0.0-pre.3"
|
||||||
|
|
||||||
grin_wallet_libwallet = { path = "../libwallet", version = "4.0.1-alpha.1" }
|
grin_wallet_libwallet = { path = "../libwallet", version = "4.1.0-alpha.1" }
|
||||||
grin_wallet_config = { path = "../config", version = "4.0.1-alpha.1" }
|
grin_wallet_config = { path = "../config", version = "4.1.0-alpha.1" }
|
||||||
grin_wallet_impls = { path = "../impls", version = "4.0.1-alpha.1" }
|
grin_wallet_impls = { path = "../impls", 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" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
|
|
|
@ -40,8 +40,6 @@ pub enum ForeignCheckMiddlewareFn {
|
||||||
VerifySlateMessages,
|
VerifySlateMessages,
|
||||||
/// receive_tx
|
/// receive_tx
|
||||||
ReceiveTx,
|
ReceiveTx,
|
||||||
/// finalize_invoice_tx (delete HF3)
|
|
||||||
FinalizeInvoiceTx,
|
|
||||||
/// finalize_tx
|
/// finalize_tx
|
||||||
FinalizeTx,
|
FinalizeTx,
|
||||||
}
|
}
|
||||||
|
@ -441,13 +439,6 @@ where
|
||||||
pub fn finalize_tx(&self, slate: &Slate, post_automatically: bool) -> Result<Slate, Error> {
|
pub fn finalize_tx(&self, slate: &Slate, post_automatically: bool) -> Result<Slate, Error> {
|
||||||
let mut w_lock = self.wallet_inst.lock();
|
let mut w_lock = self.wallet_inst.lock();
|
||||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
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 {
|
let post_automatically = match self.doctest_mode {
|
||||||
true => false,
|
true => false,
|
||||||
false => post_automatically,
|
false => post_automatically,
|
||||||
|
|
|
@ -53,8 +53,7 @@ pub trait ForeignRpc {
|
||||||
"Ok": {
|
"Ok": {
|
||||||
"foreign_api_version": 2,
|
"foreign_api_version": 2,
|
||||||
"supported_slate_versions": [
|
"supported_slate_versions": [
|
||||||
"V4",
|
"V4"
|
||||||
"V3"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,15 +95,13 @@ pub trait ForeignRpc {
|
||||||
"kernel": {
|
"kernel": {
|
||||||
"excess": "08dfe86d732f2dd24bac36aa7502685221369514197c26d33fac03041d47e4b490",
|
"excess": "08dfe86d732f2dd24bac36aa7502685221369514197c26d33fac03041d47e4b490",
|
||||||
"excess_sig": "8f07ddd5e9f5179cff19486034181ed76505baaad53e5d994064127b56c5841be02fa098c54c9bf638e0ee1ad5eb896caa11565f632be7b9cd65643ba371044f",
|
"excess_sig": "8f07ddd5e9f5179cff19486034181ed76505baaad53e5d994064127b56c5841be02fa098c54c9bf638e0ee1ad5eb896caa11565f632be7b9cd65643ba371044f",
|
||||||
"features": "Coinbase",
|
"features": "Coinbase"
|
||||||
"fee": "0",
|
|
||||||
"lock_height": "0"
|
|
||||||
},
|
},
|
||||||
"key_id": "0300000000000000000000000400000000",
|
"key_id": "0300000000000000000000000400000000",
|
||||||
"output": {
|
"output": {
|
||||||
"commit": "08fe198e525a5937d0c5d01fa354394d2679be6df5d42064a0f7550c332fce3d9d",
|
"com": "08fe198e525a5937d0c5d01fa354394d2679be6df5d42064a0f7550c332fce3d9d",
|
||||||
"features": "Coinbase",
|
"features": 1,
|
||||||
"proof": "9d8488fcb43c9c0f683b9ce62f3c8e047b71f2b4cd94b99a3c9a36aef3bb8361ee17b4489eb5f6d6507250532911acb76f18664604c2ca4215347a5d5d8e417d00ca2d59ec29371286986428b0ec1177fc2e416339ea8542eff8186550ad0d65ffac35d761c38819601d331fd427576e2fff823bbc3faa04f49f5332bd4de46cd4f83d0fd46cdb1dfb87069e95974e4a45e0235db71f5efe5cec83bbb30e152ac50a010ef4e57e33aabbeb894b9114f90bb5c3bb03b009014e358aa3914b1a208eb9d8806fbb679c256d4c1a47b0fce3f1235d58192cb7f615bd7c5dab48486db8962c2a594e69ff70029784a810b4eb76b0516805f3417308cda8acb38b9a3ea061568f0c97f5b46a3beff556dc7ebb58c774f08be472b4b6f603e5f8309c2d1f8d6f52667cb86816b330eca5374148aa898f5bbaf3f23a3ebcdc359ee1e14d73a65596c0ddf51f123234969ac8b557ba9dc53255dd6f5c0d3dd2c035a6d1a1185102612fdca474d018b9f9e81acfa3965d42769f5a303bbaabb78d17e0c026b8be0039c55ad1378c8316101b5206359f89fd1ee239115dde458749a040997be43c039055594cab76f602a0a1ee4f5322f3ab1157342404239adbf8b6786544cd67d9891c2689530e65f2a4b8e52d8551b92ffefb812ffa4a472a10701884151d1fb77d8cdc0b1868cb31b564e98e4c035e0eaa26203b882552c7b69deb0d8ec67cf28d5ec044554f8a91a6cae87eb377d6d906bba6ec94dda24ebfd372727f68334af798b11256d88e17cef7c4fed092128215f992e712ed128db2a9da2f5e8fadea9395bddd294a524dce47f818794c56b03e1253bf0fb9cb8beebc5742e4acf19c24824aa1d41996e839906e24be120a0bdf6800da599ec9ec3d1c4c11571c9f143eadbb554fa3c8c9777994a3f3421d454e4ec54c11b97eea3e4e6ede2d97a2bc"
|
"prf": "9d8488fcb43c9c0f683b9ce62f3c8e047b71f2b4cd94b99a3c9a36aef3bb8361ee17b4489eb5f6d6507250532911acb76f18664604c2ca4215347a5d5d8e417d00ca2d59ec29371286986428b0ec1177fc2e416339ea8542eff8186550ad0d65ffac35d761c38819601d331fd427576e2fff823bbc3faa04f49f5332bd4de46cd4f83d0fd46cdb1dfb87069e95974e4a45e0235db71f5efe5cec83bbb30e152ac50a010ef4e57e33aabbeb894b9114f90bb5c3bb03b009014e358aa3914b1a208eb9d8806fbb679c256d4c1a47b0fce3f1235d58192cb7f615bd7c5dab48486db8962c2a594e69ff70029784a810b4eb76b0516805f3417308cda8acb38b9a3ea061568f0c97f5b46a3beff556dc7ebb58c774f08be472b4b6f603e5f8309c2d1f8d6f52667cb86816b330eca5374148aa898f5bbaf3f23a3ebcdc359ee1e14d73a65596c0ddf51f123234969ac8b557ba9dc53255dd6f5c0d3dd2c035a6d1a1185102612fdca474d018b9f9e81acfa3965d42769f5a303bbaabb78d17e0c026b8be0039c55ad1378c8316101b5206359f89fd1ee239115dde458749a040997be43c039055594cab76f602a0a1ee4f5322f3ab1157342404239adbf8b6786544cd67d9891c2689530e65f2a4b8e52d8551b92ffefb812ffa4a472a10701884151d1fb77d8cdc0b1868cb31b564e98e4c035e0eaa26203b882552c7b69deb0d8ec67cf28d5ec044554f8a91a6cae87eb377d6d906bba6ec94dda24ebfd372727f68334af798b11256d88e17cef7c4fed092128215f992e712ed128db2a9da2f5e8fadea9395bddd294a524dce47f818794c56b03e1253bf0fb9cb8beebc5742e4acf19c24824aa1d41996e839906e24be120a0bdf6800da599ec9ec3d1c4c11571c9f143eadbb554fa3c8c9777994a3f3421d454e4ec54c11b97eea3e4e6ede2d97a2bc"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -288,9 +285,6 @@ pub trait ForeignRpc {
|
||||||
```
|
```
|
||||||
*/
|
*/
|
||||||
fn finalize_tx(&self, slate: VersionedSlate) -> Result<VersionedSlate, ErrorKind>;
|
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>
|
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> {
|
fn build_coinbase(&self, block_fees: &BlockFees) -> Result<VersionedCoinbase, ErrorKind> {
|
||||||
let cb: CbData = Foreign::build_coinbase(self, block_fees).map_err(|e| e.kind())?;
|
let cb: CbData = Foreign::build_coinbase(self, block_fees).map_err(|e| e.kind())?;
|
||||||
Ok(VersionedCoinbase::into_version(cb, SlateVersion::V3))
|
Ok(VersionedCoinbase::into_version(cb, SlateVersion::V4))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn receive_tx(
|
fn receive_tx(
|
||||||
|
@ -332,14 +326,6 @@ where
|
||||||
Foreign::finalize_tx(self, &Slate::from(in_slate), true).map_err(|e| e.kind())?;
|
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())?)
|
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(
|
fn test_check_middleware(
|
||||||
|
|
|
@ -2320,17 +2320,6 @@ where
|
||||||
) -> Result<(bool, bool), Error> {
|
) -> Result<(bool, bool), Error> {
|
||||||
owner::verify_payment_proof(self.wallet_inst.clone(), keychain_mask, proof)
|
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
|
/// attempt to send slate synchronously, starting with TOR and downgrading to HTTP
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "grin_wallet_config"
|
name = "grin_wallet_config"
|
||||||
version = "4.0.1-alpha.1"
|
version = "4.1.0-alpha.1"
|
||||||
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
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."
|
description = "Configuration for grin wallet , a simple, private and scalable cryptocurrency implementation based on the MimbleWimble chain format."
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
@ -16,7 +16,7 @@ serde_derive = "1"
|
||||||
toml = "0.5"
|
toml = "0.5"
|
||||||
dirs = "2.0"
|
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]
|
[dev-dependencies]
|
||||||
pretty_assertions = "0.6"
|
pretty_assertions = "0.6"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "grin_wallet_controller"
|
name = "grin_wallet_controller"
|
||||||
version = "4.0.1-alpha.1"
|
version = "4.1.0-alpha.1"
|
||||||
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
||||||
description = "Controllers for grin wallet instantiation"
|
description = "Controllers for grin wallet instantiation"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
@ -30,12 +30,12 @@ chrono = { version = "0.4.11", features = ["serde"] }
|
||||||
easy-jsonrpc-mw = "0.5.4"
|
easy-jsonrpc-mw = "0.5.4"
|
||||||
lazy_static = "1"
|
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_api = { path = "../api", version = "4.1.0-alpha.1" }
|
||||||
grin_wallet_impls = { path = "../impls", version = "4.0.1-alpha.1" }
|
grin_wallet_impls = { path = "../impls", version = "4.1.0-alpha.1" }
|
||||||
grin_wallet_libwallet = { path = "../libwallet", version = "4.0.1-alpha.1" }
|
grin_wallet_libwallet = { path = "../libwallet", version = "4.1.0-alpha.1" }
|
||||||
grin_wallet_config = { path = "../config", version = "4.0.1-alpha.1" }
|
grin_wallet_config = { path = "../config", version = "4.1.0-alpha.1" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ed25519-dalek = "1.0.0-pre.3"
|
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::config::{TorConfig, WalletConfig, WALLET_CONFIG_FILE_NAME};
|
||||||
use crate::core::{core, global};
|
use crate::core::{core, global};
|
||||||
use crate::error::{Error, ErrorKind};
|
use crate::error::{Error, ErrorKind};
|
||||||
|
use crate::impls::PathToSlatepack;
|
||||||
use crate::impls::SlateGetter as _;
|
use crate::impls::SlateGetter as _;
|
||||||
use crate::impls::{HttpSlateSender, PathToSlate, PathToSlatepack, SlatePutter};
|
|
||||||
use crate::keychain;
|
use crate::keychain;
|
||||||
use crate::libwallet::{
|
use crate::libwallet::{
|
||||||
self, InitTxArgs, IssueInvoiceTxArgs, NodeClient, PaymentProof, Slate, SlateVersion, Slatepack,
|
self, InitTxArgs, IssueInvoiceTxArgs, NodeClient, PaymentProof, Slate, SlateState, Slatepack,
|
||||||
SlatepackAddress, Slatepacker, SlatepackerArgs, WalletLCProvider,
|
SlatepackAddress, Slatepacker, SlatepackerArgs, WalletLCProvider,
|
||||||
};
|
};
|
||||||
use crate::util::secp::key::SecretKey;
|
use crate::util::secp::key::SecretKey;
|
||||||
use crate::util::{Mutex, ZeroingString};
|
use crate::util::{Mutex, ZeroingString};
|
||||||
use crate::{controller, display};
|
use crate::{controller, display};
|
||||||
use grin_wallet_util::OnionV3Address;
|
|
||||||
use serde_json as json;
|
use serde_json as json;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
@ -259,8 +258,6 @@ pub struct SendArgs {
|
||||||
pub ttl_blocks: Option<u64>,
|
pub ttl_blocks: Option<u64>,
|
||||||
pub skip_tor: bool,
|
pub skip_tor: bool,
|
||||||
pub outfile: Option<String>,
|
pub outfile: Option<String>,
|
||||||
//TODO: Remove HF3
|
|
||||||
pub output_v4_slate: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send<L, C, K>(
|
pub fn send<L, C, K>(
|
||||||
|
@ -276,126 +273,6 @@ where
|
||||||
C: NodeClient + 'static,
|
C: NodeClient + 'static,
|
||||||
K: keychain::Keychain + '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);
|
let mut slate = Slate::blank(2, false);
|
||||||
controller::owner_single_use(None, keychain_mask, Some(owner_api), |api, m| {
|
controller::owner_single_use(None, keychain_mask, Some(owner_api), |api, m| {
|
||||||
if args.estimate_selection_strategies {
|
if args.estimate_selection_strategies {
|
||||||
|
@ -460,8 +337,7 @@ where
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let res =
|
let res = try_slatepack_sync_workflow(&slate, &args.dest, tor_config, None, false, test_mode);
|
||||||
try_slatepack_sync_workflow(&slate, &args.dest, tor_config, tor_sender, false, test_mode);
|
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Ok(Some(s)) => {
|
Ok(Some(s)) => {
|
||||||
|
@ -490,7 +366,6 @@ where
|
||||||
args.outfile,
|
args.outfile,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
is_pre_fork,
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
Err(e) => return Err(e.into()),
|
Err(e) => return Err(e.into()),
|
||||||
|
@ -506,7 +381,6 @@ pub fn output_slatepack<L, C, K>(
|
||||||
out_file_override: Option<String>,
|
out_file_override: Option<String>,
|
||||||
lock: bool,
|
lock: bool,
|
||||||
finalizing: bool,
|
finalizing: bool,
|
||||||
is_pre_fork: bool,
|
|
||||||
) -> Result<(), libwallet::Error>
|
) -> Result<(), libwallet::Error>
|
||||||
where
|
where
|
||||||
L: WalletLCProvider<'static, C, K> + 'static,
|
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);
|
println!("{}", out_file_name);
|
||||||
let mut output = File::create(out_file_name.clone())?;
|
let mut output = File::create(out_file_name.clone())?;
|
||||||
output.write_all(&message.as_bytes())?;
|
output.write_all(&message.as_bytes())?;
|
||||||
|
@ -606,26 +466,20 @@ where
|
||||||
let mut ret_address = None;
|
let mut ret_address = None;
|
||||||
let slate = match filename {
|
let slate = match filename {
|
||||||
Some(f) => {
|
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
|
// 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| {
|
controller::owner_single_use(None, keychain_mask, Some(owner_api), |api, m| {
|
||||||
let dec_key = api.get_slatepack_secret_key(m, 0)?;
|
let dec_key = api.get_slatepack_secret_key(m, 0)?;
|
||||||
let packer = Slatepacker::new(SlatepackerArgs {
|
let packer = Slatepacker::new(SlatepackerArgs {
|
||||||
sender: None,
|
sender: None,
|
||||||
recipients: vec![],
|
recipients: vec![],
|
||||||
dec_key: Some(&dec_key),
|
dec_key: Some(&dec_key),
|
||||||
});
|
});
|
||||||
let pts = PathToSlatepack::new(f.into(), &packer, true);
|
let pts = PathToSlatepack::new(f.into(), &packer, true);
|
||||||
sl = Some(pts.get_tx()?.0);
|
sl = Some(pts.get_tx()?.0);
|
||||||
ret_address = pts.get_slatepack(true)?.sender;
|
ret_address = pts.get_slatepack(true)?.sender;
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
}
|
|
||||||
sl
|
sl
|
||||||
}
|
}
|
||||||
None => None,
|
None => None,
|
||||||
|
@ -736,7 +590,6 @@ where
|
||||||
args.outfile,
|
args.outfile,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
slate.version_info.version < 4,
|
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -851,14 +704,8 @@ where
|
||||||
|
|
||||||
// Rather than duplicating the entire command, we'll just
|
// Rather than duplicating the entire command, we'll just
|
||||||
// try to determine what kind of finalization this is
|
// try to determine what kind of finalization this is
|
||||||
// based on the slate contents
|
// based on the slate state
|
||||||
// for now, we can tell this is an invoice transaction
|
let is_invoice = slate.state == SlateState::Invoice2;
|
||||||
// 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(())
|
|
||||||
})?;
|
|
||||||
|
|
||||||
if is_invoice {
|
if is_invoice {
|
||||||
let km = match keychain_mask.as_ref() {
|
let km = match keychain_mask.as_ref() {
|
||||||
|
@ -905,7 +752,6 @@ where
|
||||||
args.outfile,
|
args.outfile,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
slate.version_info.version < 4,
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -917,8 +763,6 @@ pub struct IssueInvoiceArgs {
|
||||||
pub dest: String,
|
pub dest: String,
|
||||||
/// issue invoice tx args
|
/// issue invoice tx args
|
||||||
pub issue_args: IssueInvoiceTxArgs,
|
pub issue_args: IssueInvoiceTxArgs,
|
||||||
/// whether to output a V4 slate
|
|
||||||
pub output_v4_slate: bool,
|
|
||||||
/// output file override
|
/// output file override
|
||||||
pub outfile: Option<String>,
|
pub outfile: Option<String>,
|
||||||
}
|
}
|
||||||
|
@ -933,37 +777,7 @@ where
|
||||||
C: NodeClient + 'static,
|
C: NodeClient + 'static,
|
||||||
K: keychain::Keychain + 'static,
|
K: keychain::Keychain + 'static,
|
||||||
{
|
{
|
||||||
//TODO: Remove block HF3
|
let issue_args = args.issue_args.clone();
|
||||||
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 mut slate = Slate::blank(2, false);
|
let mut slate = Slate::blank(2, false);
|
||||||
controller::owner_single_use(None, keychain_mask, Some(owner_api), |api, m| {
|
controller::owner_single_use(None, keychain_mask, Some(owner_api), |api, m| {
|
||||||
|
@ -979,7 +793,6 @@ where
|
||||||
args.outfile,
|
args.outfile,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
is_pre_fork,
|
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1098,7 +911,6 @@ where
|
||||||
args.outfile,
|
args.outfile,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
slate.version_info.version < 4,
|
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -409,7 +409,7 @@ fn slatepack_exchange_test_impl(
|
||||||
|
|
||||||
wallet::controller::foreign_single_use(wallet2.clone(), mask2_i.clone(), |api| {
|
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())?;
|
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 = res.1;
|
||||||
slate = api.receive_tx(&slate, None, None)?;
|
slate = api.receive_tx(&slate, None, None)?;
|
||||||
output_slatepack(
|
output_slatepack(
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "grin_wallet_impls"
|
name = "grin_wallet_impls"
|
||||||
version = "4.0.1-alpha.1"
|
version = "4.1.0-alpha.1"
|
||||||
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
||||||
description = "Concrete types derived from libwallet traits"
|
description = "Concrete types derived from libwallet traits"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
@ -41,6 +41,6 @@ regex = "1.3"
|
||||||
timer = "0.2"
|
timer = "0.2"
|
||||||
sysinfo = "0.14"
|
sysinfo = "0.14"
|
||||||
|
|
||||||
grin_wallet_util = { path = "../util", version = "4.0.1-alpha.1" }
|
grin_wallet_util = { path = "../util", version = "4.1.0-alpha.1" }
|
||||||
grin_wallet_config = { path = "../config", version = "4.0.1-alpha.1" }
|
grin_wallet_config = { path = "../config", version = "4.1.0-alpha.1" }
|
||||||
grin_wallet_libwallet = { path = "../libwallet", version = "4.0.1-alpha.1" }
|
grin_wallet_libwallet = { path = "../libwallet", version = "4.1.0-alpha.1" }
|
||||||
|
|
|
@ -16,11 +16,7 @@
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
use crate::libwallet::slate_versions::v3::SlateV3;
|
use crate::libwallet::{Error, ErrorKind, Slate, SlateVersion, VersionedBinSlate, VersionedSlate};
|
||||||
use crate::libwallet::slate_versions::v4::SlateV4;
|
|
||||||
use crate::libwallet::{
|
|
||||||
Error, ErrorKind, Slate, SlateState, SlateVersion, VersionedBinSlate, VersionedSlate,
|
|
||||||
};
|
|
||||||
use crate::{SlateGetter, SlatePutter};
|
use crate::{SlateGetter, SlatePutter};
|
||||||
use grin_wallet_util::byte_ser;
|
use grin_wallet_util::byte_ser;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
@ -41,56 +37,7 @@ impl SlatePutter for PathToSlate {
|
||||||
}*/
|
}*/
|
||||||
let mut pub_tx = File::create(&self.0)?;
|
let mut pub_tx = File::create(&self.0)?;
|
||||||
// TODO:
|
// TODO:
|
||||||
let out_slate = {
|
let out_slate = VersionedSlate::into_version(slate.clone(), SlateVersion::V4)?;
|
||||||
// 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)?
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if as_bin {
|
if as_bin {
|
||||||
let bin_slate =
|
let bin_slate =
|
||||||
VersionedBinSlate::try_from(out_slate).map_err(|_| ErrorKind::SlateSer)?;
|
VersionedBinSlate::try_from(out_slate).map_err(|_| ErrorKind::SlateSer)?;
|
||||||
|
|
|
@ -148,9 +148,6 @@ impl HttpSlateSender {
|
||||||
if supported_slate_versions.contains(&"V4".to_owned()) {
|
if supported_slate_versions.contains(&"V4".to_owned()) {
|
||||||
return Ok(SlateVersion::V4);
|
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();
|
let report = "Unable to negotiate slate format with other wallet.".to_string();
|
||||||
error!("{}", report);
|
error!("{}", report);
|
||||||
|
@ -189,18 +186,6 @@ impl SlateSender for HttpSlateSender {
|
||||||
|
|
||||||
let slate_send = match self.check_other_version(&url_str)? {
|
let slate_send = match self.check_other_version(&url_str)? {
|
||||||
SlateVersion::V4 => VersionedSlate::into_version(slate.clone(), SlateVersion::V4)?,
|
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
|
// Note: not using easy-jsonrpc as don't want the dependencies in this crate
|
||||||
let req = match finalize {
|
let req = match finalize {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "grin_wallet_libwallet"
|
name = "grin_wallet_libwallet"
|
||||||
version = "4.0.1-alpha.1"
|
version = "4.1.0-alpha.1"
|
||||||
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
||||||
description = "Simple, private and scalable cryptocurrency implementation based on the MimbleWimble chain format."
|
description = "Simple, private and scalable cryptocurrency implementation based on the MimbleWimble chain format."
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
@ -36,6 +36,6 @@ secrecy = "0.6"
|
||||||
bech32 = "0.7"
|
bech32 = "0.7"
|
||||||
byteorder = "1.3"
|
byteorder = "1.3"
|
||||||
|
|
||||||
grin_wallet_util = { path = "../util", version = "4.0.1-alpha.1" }
|
grin_wallet_util = { path = "../util", version = "4.1.0-alpha.1" }
|
||||||
grin_wallet_config = { path = "../config", version = "4.0.1-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
|
ret_slate.tx = Some(Transaction::empty());
|
||||||
if ret_slate.is_compact() {
|
|
||||||
ret_slate.tx = Some(Transaction::empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
let height = w.last_confirmed_height()?;
|
let height = w.last_confirmed_height()?;
|
||||||
let keychain = w.keychain(keychain_mask)?;
|
let keychain = w.keychain(keychain_mask)?;
|
||||||
|
@ -121,15 +118,12 @@ where
|
||||||
|
|
||||||
p.receiver_signature = Some(sig);
|
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;
|
ret_slate.state = SlateState::Standard2;
|
||||||
|
|
||||||
Ok(ret_slate)
|
Ok(ret_slate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,12 +144,12 @@ where
|
||||||
let is_invoice = context.is_invoice;
|
let is_invoice = context.is_invoice;
|
||||||
if is_invoice {
|
if is_invoice {
|
||||||
check_ttl(w, &sl)?;
|
check_ttl(w, &sl)?;
|
||||||
if sl.is_compact() {
|
|
||||||
let mut temp_ctx = context.clone();
|
let mut temp_ctx = context.clone();
|
||||||
temp_ctx.sec_key = context.initial_sec_key.clone();
|
temp_ctx.sec_key = context.initial_sec_key.clone();
|
||||||
temp_ctx.sec_nonce = context.initial_sec_nonce.clone();
|
temp_ctx.sec_nonce = context.initial_sec_nonce.clone();
|
||||||
selection::repopulate_tx(&mut *w, keychain_mask, &mut sl, &temp_ctx, false)?;
|
selection::repopulate_tx(&mut *w, keychain_mask, &mut sl, &temp_ctx, false)?;
|
||||||
}
|
|
||||||
tx::complete_tx(&mut *w, keychain_mask, &mut sl, &context)?;
|
tx::complete_tx(&mut *w, keychain_mask, &mut sl, &context)?;
|
||||||
tx::update_stored_tx(&mut *w, keychain_mask, &context, &mut sl, true)?;
|
tx::update_stored_tx(&mut *w, keychain_mask, &context, &mut sl, true)?;
|
||||||
{
|
{
|
||||||
|
@ -164,9 +158,7 @@ where
|
||||||
batch.commit()?;
|
batch.commit()?;
|
||||||
}
|
}
|
||||||
sl.state = SlateState::Invoice3;
|
sl.state = SlateState::Invoice3;
|
||||||
if sl.is_compact() {
|
sl.amount = 0;
|
||||||
sl.amount = 0;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
sl = owner_finalize(w, keychain_mask, slate)?;
|
sl = owner_finalize(w, keychain_mask, slate)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -541,9 +541,7 @@ where
|
||||||
batch.commit()?;
|
batch.commit()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if slate.is_compact() {
|
slate.compact()?;
|
||||||
slate.compact()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(slate)
|
Ok(slate)
|
||||||
}
|
}
|
||||||
|
@ -595,9 +593,7 @@ where
|
||||||
batch.commit()?;
|
batch.commit()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if slate.is_compact() {
|
slate.compact()?;
|
||||||
slate.compact()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(slate)
|
Ok(slate)
|
||||||
}
|
}
|
||||||
|
@ -650,9 +646,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
// if this is compact mode, we need to create the transaction now
|
// 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
|
// if self sending, make sure to store 'initiator' keys
|
||||||
let context_res = w.get_private_context(keychain_mask, slate.id.as_bytes());
|
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)
|
tx::sub_inputs_from_offset(&mut *w, keychain_mask, &context, &mut ret_slate)?;
|
||||||
// TODO: Revisit post-HF3
|
selection::repopulate_tx(&mut *w, keychain_mask, &mut ret_slate, &context, false)?;
|
||||||
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
|
// Save the aggsig context in our DB for when we
|
||||||
// recieve the transaction back
|
// recieve the transaction back
|
||||||
|
@ -707,10 +697,8 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can remove amount as well as other sig data now
|
// Can remove amount as well as other sig data now
|
||||||
if ret_slate.is_compact() {
|
ret_slate.amount = 0;
|
||||||
ret_slate.amount = 0;
|
ret_slate.remove_other_sigdata(&keychain, &context.sec_nonce, &context.sec_key)?;
|
||||||
ret_slate.remove_other_sigdata(&keychain, &context.sec_nonce, &context.sec_key)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret_slate.state = SlateState::Invoice2;
|
ret_slate.state = SlateState::Invoice2;
|
||||||
Ok(ret_slate)
|
Ok(ret_slate)
|
||||||
|
@ -728,16 +716,20 @@ where
|
||||||
K: Keychain + 'a,
|
K: Keychain + 'a,
|
||||||
{
|
{
|
||||||
let context = w.get_private_context(keychain_mask, slate.id.as_bytes())?;
|
let context = w.get_private_context(keychain_mask, slate.id.as_bytes())?;
|
||||||
let mut sl = slate.clone();
|
|
||||||
let mut excess_override = None;
|
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());
|
sl.tx = Some(Transaction::empty());
|
||||||
selection::repopulate_tx(&mut *w, keychain_mask, &mut sl, &context, true)?;
|
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
|
// purely for invoice workflow, payer needs the excess back temporarily for storage
|
||||||
excess_override = context.calculated_excess;
|
excess_override = context.calculated_excess;
|
||||||
}
|
}
|
||||||
|
|
||||||
let height = w.w2n_client().get_chain_tip()?.0;
|
let height = w.w2n_client().get_chain_tip()?.0;
|
||||||
selection::lock_tx_context(
|
selection::lock_tx_context(
|
||||||
&mut *w,
|
&mut *w,
|
||||||
|
@ -771,10 +763,8 @@ where
|
||||||
// as opposed to locking them prior to this stage, as the excess to this point
|
// as opposed to locking them prior to this stage, as the excess to this point
|
||||||
// will just be the change output
|
// will just be the change output
|
||||||
|
|
||||||
if sl.is_compact() {
|
tx::sub_inputs_from_offset(&mut *w, keychain_mask, &context, &mut sl)?;
|
||||||
tx::sub_inputs_from_offset(&mut *w, keychain_mask, &context, &mut sl)?;
|
selection::repopulate_tx(&mut *w, keychain_mask, &mut sl, &context, true)?;
|
||||||
selection::repopulate_tx(&mut *w, keychain_mask, &mut sl, &context, true)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
tx::complete_tx(&mut *w, keychain_mask, &mut sl, &context)?;
|
tx::complete_tx(&mut *w, keychain_mask, &mut sl, &context)?;
|
||||||
tx::verify_slate_payment_proof(&mut *w, keychain_mask, &parent_key_id, &context, &sl)?;
|
tx::verify_slate_payment_proof(&mut *w, keychain_mask, &parent_key_id, &context, &sl)?;
|
||||||
|
@ -785,9 +775,8 @@ where
|
||||||
batch.commit()?;
|
batch.commit()?;
|
||||||
}
|
}
|
||||||
sl.state = SlateState::Standard3;
|
sl.state = SlateState::Standard3;
|
||||||
if sl.is_compact() {
|
sl.amount = 0;
|
||||||
sl.amount = 0;
|
|
||||||
}
|
|
||||||
Ok(sl)
|
Ok(sl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,10 +55,6 @@ where
|
||||||
C: NodeClient + 'a,
|
C: NodeClient + 'a,
|
||||||
K: Keychain + '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(
|
let (elems, inputs, change_amounts_derivations, fee) = select_send_tx(
|
||||||
wallet,
|
wallet,
|
||||||
keychain_mask,
|
keychain_mask,
|
||||||
|
@ -69,7 +65,7 @@ where
|
||||||
change_outputs,
|
change_outputs,
|
||||||
selection_strategy_is_use_all,
|
selection_strategy_is_use_all,
|
||||||
&parent_key_id,
|
&parent_key_id,
|
||||||
include_inputs_in_sum,
|
false,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Update the fee on the slate so we account for this when building the tx.
|
// 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>,
|
pub payment_proof: Option<PaymentInfo>,
|
||||||
/// Kernel features arguments
|
/// Kernel features arguments
|
||||||
pub kernel_features_args: Option<KernelFeaturesArgs>,
|
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 {
|
impl fmt::Display for Slate {
|
||||||
|
@ -216,10 +212,6 @@ impl Slate {
|
||||||
None => Err(ErrorKind::SlateTransactionRequired.into()),
|
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
|
/// number of participants
|
||||||
pub fn num_participants(&self) -> u8 {
|
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
|
/// Recieve a slate, upgrade it to the latest version internally
|
||||||
/// Throw error if this can't be done
|
/// Throw error if this can't be done
|
||||||
pub fn deserialize_upgrade(slate_json: &str) -> Result<Slate, Error> {
|
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> {
|
pub fn upgrade(v_slate: VersionedSlate) -> Result<Slate, Error> {
|
||||||
let v4: SlateV4 = match v_slate {
|
let v4: SlateV4 = match v_slate {
|
||||||
VersionedSlate::V4(s) => s,
|
VersionedSlate::V4(s) => s,
|
||||||
VersionedSlate::V3(s) => SlateV4::from(s),
|
|
||||||
};
|
};
|
||||||
Ok(v4.into())
|
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
|
/// Create a new slate
|
||||||
pub fn blank(num_participants: u8, is_invoice: bool) -> Slate {
|
pub fn blank(num_participants: u8, is_invoice: bool) -> Slate {
|
||||||
|
@ -280,7 +270,6 @@ impl Slate {
|
||||||
block_header_version: GRIN_BLOCK_HEADER_VERSION,
|
block_header_version: GRIN_BLOCK_HEADER_VERSION,
|
||||||
},
|
},
|
||||||
payment_proof: None,
|
payment_proof: None,
|
||||||
participant_id: None,
|
|
||||||
kernel_features_args: None,
|
kernel_features_args: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,15 +341,8 @@ impl Slate {
|
||||||
where
|
where
|
||||||
K: Keychain,
|
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
|
// 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)?;
|
self.add_participant_info(keychain, &sec_key, &sec_nonce, None)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -414,9 +396,8 @@ impl Slate {
|
||||||
K: Keychain,
|
K: Keychain,
|
||||||
{
|
{
|
||||||
// TODO: Note we're unable to verify fees in this instance
|
// TODO: Note we're unable to verify fees in this instance
|
||||||
if !self.is_compact() {
|
// Left here is a reminder that we no longer check fees
|
||||||
self.check_fees()?;
|
// self.check_fees()?;
|
||||||
}
|
|
||||||
|
|
||||||
self.verify_part_sigs(keychain.secp())?;
|
self.verify_part_sigs(keychain.secp())?;
|
||||||
let sig_part = aggsig::calculate_partial_sig(
|
let sig_part = aggsig::calculate_partial_sig(
|
||||||
|
@ -534,7 +515,6 @@ impl Slate {
|
||||||
public_nonce: pub_nonce,
|
public_nonce: pub_nonce,
|
||||||
part_sig: part_sig,
|
part_sig: part_sig,
|
||||||
});
|
});
|
||||||
self.participant_id = Some(pub_key);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,18 +545,12 @@ impl Slate {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.is_compact() {
|
let total_offset = keychain.blind_sum(
|
||||||
let total_offset = keychain.blind_sum(
|
&BlindSum::new()
|
||||||
&BlindSum::new()
|
.add_blinding_factor(self.offset.clone())
|
||||||
.add_blinding_factor(self.offset.clone())
|
.add_blinding_factor(my_offset.clone()),
|
||||||
.add_blinding_factor(my_offset.clone()),
|
)?;
|
||||||
)?;
|
self.offset = total_offset;
|
||||||
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(
|
let adjusted_offset = keychain.blind_sum(
|
||||||
&BlindSum::new()
|
&BlindSum::new()
|
||||||
|
@ -765,7 +739,6 @@ impl From<Slate> for SlateV4 {
|
||||||
participant_data,
|
participant_data,
|
||||||
version_info,
|
version_info,
|
||||||
payment_proof,
|
payment_proof,
|
||||||
participant_id: _participant_id,
|
|
||||||
kernel_features_args,
|
kernel_features_args,
|
||||||
} = slate.clone();
|
} = slate.clone();
|
||||||
let participant_data = map_vec!(participant_data, |data| ParticipantDataV4::from(data));
|
let participant_data = map_vec!(participant_data, |data| ParticipantDataV4::from(data));
|
||||||
|
@ -812,7 +785,6 @@ impl From<&Slate> for SlateV4 {
|
||||||
participant_data,
|
participant_data,
|
||||||
version_info,
|
version_info,
|
||||||
payment_proof,
|
payment_proof,
|
||||||
participant_id: _participant_id,
|
|
||||||
kernel_features_args,
|
kernel_features_args,
|
||||||
} = slate;
|
} = slate;
|
||||||
let num_parts = *num_parts;
|
let num_parts = *num_parts;
|
||||||
|
@ -1090,7 +1062,6 @@ impl From<SlateV4> for Slate {
|
||||||
participant_data,
|
participant_data,
|
||||||
version_info,
|
version_info,
|
||||||
payment_proof,
|
payment_proof,
|
||||||
participant_id: None,
|
|
||||||
kernel_features_args,
|
kernel_features_args,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,21 +14,18 @@
|
||||||
|
|
||||||
//! This module contains old slate versions and conversions to the newest slate version
|
//! 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.
|
//! 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
|
//! remains for future needs
|
||||||
|
|
||||||
use crate::slate::Slate;
|
use crate::slate::Slate;
|
||||||
use crate::slate_versions::v3::{CoinbaseV3, SlateV3};
|
|
||||||
use crate::slate_versions::v4::{CoinbaseV4, SlateV4};
|
use crate::slate_versions::v4::{CoinbaseV4, SlateV4};
|
||||||
use crate::slate_versions::v4_bin::SlateV4Bin;
|
use crate::slate_versions::v4_bin::SlateV4Bin;
|
||||||
use crate::types::CbData;
|
use crate::types::CbData;
|
||||||
use crate::{Error, ErrorKind};
|
use crate::Error;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
pub mod ser;
|
pub mod ser;
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
|
||||||
pub mod v3;
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub mod v4;
|
pub mod v4;
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
|
@ -45,8 +42,6 @@ pub const GRIN_BLOCK_HEADER_VERSION: u16 = 3;
|
||||||
pub enum SlateVersion {
|
pub enum SlateVersion {
|
||||||
/// V4 (most current)
|
/// V4 (most current)
|
||||||
V4,
|
V4,
|
||||||
/// V3 (3.0.0 - 4.0.0)
|
|
||||||
V3,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
@ -56,8 +51,6 @@ pub enum SlateVersion {
|
||||||
pub enum VersionedSlate {
|
pub enum VersionedSlate {
|
||||||
/// Current (4.0.0 Onwards )
|
/// Current (4.0.0 Onwards )
|
||||||
V4(SlateV4),
|
V4(SlateV4),
|
||||||
/// V2 (2.0.0 - 3.0.0)
|
|
||||||
V3(SlateV3),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VersionedSlate {
|
impl VersionedSlate {
|
||||||
|
@ -65,7 +58,6 @@ impl VersionedSlate {
|
||||||
pub fn version(&self) -> SlateVersion {
|
pub fn version(&self) -> SlateVersion {
|
||||||
match *self {
|
match *self {
|
||||||
VersionedSlate::V4(_) => SlateVersion::V4,
|
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> {
|
pub fn into_version(slate: Slate, version: SlateVersion) -> Result<VersionedSlate, Error> {
|
||||||
match version {
|
match version {
|
||||||
SlateVersion::V4 => Ok(VersionedSlate::V4(slate.into())),
|
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 {
|
fn from(slate: VersionedSlate) -> Slate {
|
||||||
match slate {
|
match slate {
|
||||||
VersionedSlate::V4(s) => Slate::from(s),
|
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> {
|
fn try_from(slate: VersionedSlate) -> Result<VersionedBinSlate, Error> {
|
||||||
match slate {
|
match slate {
|
||||||
VersionedSlate::V4(s) => Ok(VersionedBinSlate::V4(SlateV4Bin(s))),
|
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 {
|
pub enum VersionedCoinbase {
|
||||||
/// Current supported coinbase version.
|
/// Current supported coinbase version.
|
||||||
V4(CoinbaseV4),
|
V4(CoinbaseV4),
|
||||||
/// Previous supported coinbase version.
|
|
||||||
V3(CoinbaseV3),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VersionedCoinbase {
|
impl VersionedCoinbase {
|
||||||
|
@ -141,7 +117,6 @@ impl VersionedCoinbase {
|
||||||
pub fn into_version(cb: CbData, version: SlateVersion) -> VersionedCoinbase {
|
pub fn into_version(cb: CbData, version: SlateVersion) -> VersionedCoinbase {
|
||||||
match version {
|
match version {
|
||||||
SlateVersion::V4 => VersionedCoinbase::V4(cb.into()),
|
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`
|
//! * The `receiver_signature` field is renamed to `rsig`
|
||||||
//! * `rsig` may be omitted if it has not yet been filled out
|
//! * `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::libtx::secp_ser;
|
||||||
use crate::grin_core::map_vec;
|
|
||||||
use crate::grin_keychain::{BlindingFactor, Identifier};
|
use crate::grin_keychain::{BlindingFactor, Identifier};
|
||||||
use crate::grin_util::secp;
|
use crate::grin_util::secp;
|
||||||
use crate::grin_util::secp::key::PublicKey;
|
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::grin_util::secp::Signature;
|
||||||
use crate::slate::CompatKernelFeatures;
|
use crate::slate::CompatKernelFeatures;
|
||||||
use crate::slate_versions::ser;
|
use crate::slate_versions::ser;
|
||||||
use crate::{Error, ErrorKind};
|
|
||||||
use ed25519_dalek::PublicKey as DalekPublicKey;
|
use ed25519_dalek::PublicKey as DalekPublicKey;
|
||||||
use ed25519_dalek::Signature as DalekSignature;
|
use ed25519_dalek::Signature as DalekSignature;
|
||||||
use std::convert::TryFrom;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::slate_versions::v3::{
|
|
||||||
InputV3, OutputV3, ParticipantDataV3, PaymentInfoV3, SlateV3, TransactionBodyV3, TransactionV3,
|
|
||||||
TxKernelV3, VersionCompatInfoV3,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct SlateV4 {
|
pub struct SlateV4 {
|
||||||
// Required Fields
|
// Required Fields
|
||||||
|
@ -463,471 +454,3 @@ pub struct CoinbaseV4 {
|
||||||
/// Key Id
|
/// Key Id
|
||||||
pub key_id: Option<Identifier>,
|
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
|
short: u
|
||||||
long: outfile
|
long: outfile
|
||||||
takes_value: true
|
takes_value: true
|
||||||
#TODO: Remove HF3
|
|
||||||
- v4:
|
|
||||||
help: Output a V4 slate prior to HF3 block
|
|
||||||
long: v4
|
|
||||||
takes_value: false
|
|
||||||
- unpack:
|
- unpack:
|
||||||
about: Unpack and display an armored Slatepack Message, decrypting if possible
|
about: Unpack and display an armored Slatepack Message, decrypting if possible
|
||||||
args:
|
args:
|
||||||
|
@ -217,11 +212,6 @@ subcommands:
|
||||||
short: u
|
short: u
|
||||||
long: outfile
|
long: outfile
|
||||||
takes_value: true
|
takes_value: true
|
||||||
#TODO: Remove HF3
|
|
||||||
- v4:
|
|
||||||
help: Output a V4 slate prior to HF3 block
|
|
||||||
long: v4
|
|
||||||
takes_value: false
|
|
||||||
- pay:
|
- pay:
|
||||||
about: Spend coins to pay the provided invoice transaction
|
about: Spend coins to pay the provided invoice transaction
|
||||||
args:
|
args:
|
||||||
|
|
|
@ -502,9 +502,6 @@ pub fn parse_send_args(args: &ArgMatches) -> Result<command::SendArgs, ParseErro
|
||||||
// max_outputs
|
// max_outputs
|
||||||
let max_outputs = 500;
|
let max_outputs = 500;
|
||||||
|
|
||||||
// TODO: Remove HF3
|
|
||||||
let output_v4_slate = args.is_present("v4");
|
|
||||||
|
|
||||||
// target slate version to create/send
|
// target slate version to create/send
|
||||||
let target_slate_version = {
|
let target_slate_version = {
|
||||||
match args.is_present("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,
|
payment_proof_address,
|
||||||
ttl_blocks,
|
ttl_blocks,
|
||||||
target_slate_version: target_slate_version,
|
target_slate_version: target_slate_version,
|
||||||
output_v4_slate,
|
|
||||||
outfile,
|
outfile,
|
||||||
skip_tor: args.is_present("manual"),
|
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
|
// target slate version to create
|
||||||
let target_slate_version = {
|
let target_slate_version = {
|
||||||
match args.is_present("slate_version") {
|
match args.is_present("slate_version") {
|
||||||
|
@ -682,7 +675,6 @@ pub fn parse_issue_invoice_args(
|
||||||
|
|
||||||
Ok(command::IssueInvoiceArgs {
|
Ok(command::IssueInvoiceArgs {
|
||||||
dest: dest.into(),
|
dest: dest.into(),
|
||||||
output_v4_slate,
|
|
||||||
issue_args: IssueInvoiceTxArgs {
|
issue_args: IssueInvoiceTxArgs {
|
||||||
dest_acct_name: None,
|
dest_acct_name: None,
|
||||||
amount,
|
amount,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "grin_wallet_util"
|
name = "grin_wallet_util"
|
||||||
version = "4.0.1-alpha.1"
|
version = "4.1.0-alpha.1"
|
||||||
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
|
||||||
description = "Util, for generic utilities and to re-export grin crates"
|
description = "Util, for generic utilities and to re-export grin crates"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
|
Loading…
Reference in a new issue