From 4fe6bf1c23af10e239afa8cf1ed9be51df931e2c Mon Sep 17 00:00:00 2001 From: Antioch Peverell Date: Fri, 29 May 2020 15:52:46 +0100 Subject: [PATCH] NRD kernel variant (compile against grin master) (#408) * wip * hardcode NRD kernel during tx building * commit * compiles against grin with NRD kernel variant --- Cargo.lock | 16 +++++----- libwallet/src/error.rs | 4 +++ libwallet/src/slate.rs | 48 +++++++++++++++++++++++++----- libwallet/src/slate_versions/v4.rs | 23 +++++++++++++- util/Cargo.toml | 12 ++++---- 5 files changed, 80 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 997f2f72..617ada5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1176,7 +1176,7 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "grin_api" version = "4.0.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#6faa0e8d75be42280f3954eebedb1676cd40bb6b" +source = "git+https://github.com/mimblewimble/grin#5b825fbf0ddb7ccc6c2fcd49c1ec585fc0583331" dependencies = [ "bytes 0.5.4", "easy-jsonrpc-mw", @@ -1209,7 +1209,7 @@ dependencies = [ [[package]] name = "grin_chain" version = "4.0.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#6faa0e8d75be42280f3954eebedb1676cd40bb6b" +source = "git+https://github.com/mimblewimble/grin#5b825fbf0ddb7ccc6c2fcd49c1ec585fc0583331" dependencies = [ "bit-vec", "bitflags 1.2.1", @@ -1232,7 +1232,7 @@ dependencies = [ [[package]] name = "grin_core" version = "4.0.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#6faa0e8d75be42280f3954eebedb1676cd40bb6b" +source = "git+https://github.com/mimblewimble/grin#5b825fbf0ddb7ccc6c2fcd49c1ec585fc0583331" dependencies = [ "blake2-rfc", "byteorder", @@ -1258,7 +1258,7 @@ dependencies = [ [[package]] name = "grin_keychain" version = "4.0.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#6faa0e8d75be42280f3954eebedb1676cd40bb6b" +source = "git+https://github.com/mimblewimble/grin#5b825fbf0ddb7ccc6c2fcd49c1ec585fc0583331" dependencies = [ "blake2-rfc", "byteorder", @@ -1280,7 +1280,7 @@ dependencies = [ [[package]] name = "grin_p2p" version = "4.0.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#6faa0e8d75be42280f3954eebedb1676cd40bb6b" +source = "git+https://github.com/mimblewimble/grin#5b825fbf0ddb7ccc6c2fcd49c1ec585fc0583331" dependencies = [ "bitflags 1.2.1", "chrono", @@ -1301,7 +1301,7 @@ dependencies = [ [[package]] name = "grin_pool" version = "4.0.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#6faa0e8d75be42280f3954eebedb1676cd40bb6b" +source = "git+https://github.com/mimblewimble/grin#5b825fbf0ddb7ccc6c2fcd49c1ec585fc0583331" dependencies = [ "blake2-rfc", "chrono", @@ -1335,7 +1335,7 @@ dependencies = [ [[package]] name = "grin_store" version = "4.0.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#6faa0e8d75be42280f3954eebedb1676cd40bb6b" +source = "git+https://github.com/mimblewimble/grin#5b825fbf0ddb7ccc6c2fcd49c1ec585fc0583331" dependencies = [ "byteorder", "croaring-mw", @@ -1355,7 +1355,7 @@ dependencies = [ [[package]] name = "grin_util" version = "4.0.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#6faa0e8d75be42280f3954eebedb1676cd40bb6b" +source = "git+https://github.com/mimblewimble/grin#5b825fbf0ddb7ccc6c2fcd49c1ec585fc0583331" dependencies = [ "backtrace", "base64 0.9.3", diff --git a/libwallet/src/error.rs b/libwallet/src/error.rs index 0b07fdf9..81e3f67a 100644 --- a/libwallet/src/error.rs +++ b/libwallet/src/error.rs @@ -278,6 +278,10 @@ pub enum ErrorKind { #[fail(display = "Unknown Kernel Feature: {}", _0)] UnknownKernelFeatures(u8), + /// Invalid Kernel Feature + #[fail(display = "Invalid Kernel Feature: {}", _0)] + InvalidKernelFeatures(u8), + /// Invalid Slatepack Data #[fail(display = "Invalid Slatepack Data: {}", _0)] InvalidSlatepackData(String), diff --git a/libwallet/src/slate.rs b/libwallet/src/slate.rs index f4f15d9e..b75f78c6 100644 --- a/libwallet/src/slate.rs +++ b/libwallet/src/slate.rs @@ -18,8 +18,8 @@ use crate::error::{Error, ErrorKind}; use crate::grin_core::core::amount_to_hr_string; use crate::grin_core::core::transaction::{ - Input, KernelFeatures, Output, OutputFeatures, Transaction, TransactionBody, TxKernel, - Weighting, + Input, KernelFeatures, NRDRelativeHeight, Output, OutputFeatures, Transaction, TransactionBody, + TxKernel, Weighting, }; use crate::grin_core::core::verifier_cache::LruVerifierCache; use crate::grin_core::libtx::{aggsig, build, proof::ProofBuild, tx_fee}; @@ -114,7 +114,11 @@ pub struct Slate { /// should refuse to process the transaction and unlock all /// associated outputs pub ttl_cutoff_height: u64, - /// Kernel Features flag, if any + /// Kernel Features flag - + /// 0: plain + /// 1: coinbase (invalid) + /// 2: height_locked + /// 3: NRD pub kernel_features: u8, /// Offset, needed when posting of tranasction is deferred pub offset: BlindingFactor, @@ -160,7 +164,7 @@ pub enum SlateState { #[derive(Debug, Clone, PartialEq, Eq)] /// Kernel features arguments definition pub struct KernelFeaturesArgs { - /// Lock height, for HeightLocked + /// Lock height, for HeightLocked (also NRD relative lock height) pub lock_height: u64, } @@ -346,12 +350,17 @@ impl Slate { Ok(()) } - // Construct the appropriate kernel features based on our fee and lock_height. - // If lock_height is 0 then its a plain kernel, otherwise its a height locked kernel. + // Build kernel features based on variant and associated data. + // 0: plain + // 1: coinbase (invalid) + // 2: height_locked (with associated lock_height) + // 3: NRD (with associated relative_height) + // Any other value is invalid. fn kernel_features(&self) -> Result { match self.kernel_features { 0 => Ok(KernelFeatures::Plain { fee: self.fee }), - 1 => Ok(KernelFeatures::HeightLocked { + 1 => Err(ErrorKind::InvalidKernelFeatures(1).into()), + 2 => Ok(KernelFeatures::HeightLocked { fee: self.fee, lock_height: match &self.kernel_features_args { Some(a) => a.lock_height, @@ -360,7 +369,16 @@ impl Slate { } }, }), - n => return Err(ErrorKind::UnknownKernelFeatures(n).into()), + 3 => Ok(KernelFeatures::NoRecentDuplicate { + fee: self.fee, + relative_height: match &self.kernel_features_args { + Some(a) => NRDRelativeHeight::new(a.lock_height)?, + None => { + return Err(ErrorKind::KernelFeaturesMissing(format!("lock_height")).into()) + } + }, + }), + n => Err(ErrorKind::UnknownKernelFeatures(n).into()), } } @@ -996,6 +1014,14 @@ impl From<&TxKernel> for TxKernelV4 { KernelFeatures::HeightLocked { fee, lock_height } => { (CompatKernelFeatures::HeightLocked, fee, lock_height) } + KernelFeatures::NoRecentDuplicate { + fee, + relative_height, + } => ( + CompatKernelFeatures::NoRecentDuplicate, + fee, + relative_height.into(), + ), }; TxKernelV4 { features, @@ -1257,6 +1283,11 @@ impl From<&TxKernelV4> for TxKernel { CompatKernelFeatures::Plain => KernelFeatures::Plain { fee }, CompatKernelFeatures::Coinbase => KernelFeatures::Coinbase, CompatKernelFeatures::HeightLocked => KernelFeatures::HeightLocked { fee, lock_height }, + CompatKernelFeatures::NoRecentDuplicate => KernelFeatures::NoRecentDuplicate { + fee, + relative_height: NRDRelativeHeight::new(lock_height) + .expect("a valid NRD relative height"), + }, }; TxKernel { features, @@ -1271,4 +1302,5 @@ pub enum CompatKernelFeatures { Plain, Coinbase, HeightLocked, + NoRecentDuplicate, } diff --git a/libwallet/src/slate_versions/v4.rs b/libwallet/src/slate_versions/v4.rs index 07fde173..f8b15206 100644 --- a/libwallet/src/slate_versions/v4.rs +++ b/libwallet/src/slate_versions/v4.rs @@ -689,14 +689,27 @@ impl TryFrom<&SlateV4> for SlateV3 { 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 => match feat_args { + 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 { @@ -783,6 +796,14 @@ impl From<&SlateV4> for Option { 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, diff --git a/util/Cargo.toml b/util/Cargo.toml index 51da5374..5167cd0e 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -43,12 +43,12 @@ grin_api = { git = "https://github.com/mimblewimble/grin", branch = "master" } grin_store = { git = "https://github.com/mimblewimble/grin", branch = "master" } # For local testing -#grin_core = { path = "../../grin/core"} -#grin_keychain = { path = "../../grin/keychain"} -#grin_chain = { path = "../../grin/chain"} -#grin_util = { path = "../../grin/util"} -#grin_api = { path = "../../grin/api"} -#grin_store = { path = "../../grin/store"} +# grin_core = { path = "../../grin/core"} +# grin_keychain = { path = "../../grin/keychain"} +# grin_chain = { path = "../../grin/chain"} +# grin_util = { path = "../../grin/util"} +# grin_api = { path = "../../grin/api"} +# grin_store = { path = "../../grin/store"} [dev-dependencies] pretty_assertions = "0.5.1"