diff --git a/Cargo.lock b/Cargo.lock index 814d2b3e..3735ea65 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -683,7 +683,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "grin_api" version = "3.0.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#da2e75299191acd70d4a48bd63c3dcb2cfcc74d2" +source = "git+https://github.com/mimblewimble/grin#50ce7ba0433e916ddf6154ff64bdd987bd0e68c2" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -716,7 +716,7 @@ dependencies = [ [[package]] name = "grin_chain" version = "3.0.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#da2e75299191acd70d4a48bd63c3dcb2cfcc74d2" +source = "git+https://github.com/mimblewimble/grin#50ce7ba0433e916ddf6154ff64bdd987bd0e68c2" dependencies = [ "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -739,7 +739,7 @@ dependencies = [ [[package]] name = "grin_core" version = "3.0.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#da2e75299191acd70d4a48bd63c3dcb2cfcc74d2" +source = "git+https://github.com/mimblewimble/grin#50ce7ba0433e916ddf6154ff64bdd987bd0e68c2" dependencies = [ "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -766,7 +766,7 @@ dependencies = [ [[package]] name = "grin_keychain" version = "3.0.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#da2e75299191acd70d4a48bd63c3dcb2cfcc74d2" +source = "git+https://github.com/mimblewimble/grin#50ce7ba0433e916ddf6154ff64bdd987bd0e68c2" dependencies = [ "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -789,7 +789,7 @@ dependencies = [ [[package]] name = "grin_p2p" version = "3.0.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#da2e75299191acd70d4a48bd63c3dcb2cfcc74d2" +source = "git+https://github.com/mimblewimble/grin#50ce7ba0433e916ddf6154ff64bdd987bd0e68c2" dependencies = [ "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -812,7 +812,7 @@ dependencies = [ [[package]] name = "grin_pool" version = "3.0.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#da2e75299191acd70d4a48bd63c3dcb2cfcc74d2" +source = "git+https://github.com/mimblewimble/grin#50ce7ba0433e916ddf6154ff64bdd987bd0e68c2" dependencies = [ "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -846,7 +846,7 @@ dependencies = [ [[package]] name = "grin_store" version = "3.0.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#da2e75299191acd70d4a48bd63c3dcb2cfcc74d2" +source = "git+https://github.com/mimblewimble/grin#50ce7ba0433e916ddf6154ff64bdd987bd0e68c2" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "croaring 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -867,7 +867,7 @@ dependencies = [ [[package]] name = "grin_util" version = "3.0.0-alpha.1" -source = "git+https://github.com/mimblewimble/grin#da2e75299191acd70d4a48bd63c3dcb2cfcc74d2" +source = "git+https://github.com/mimblewimble/grin#50ce7ba0433e916ddf6154ff64bdd987bd0e68c2" dependencies = [ "backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1570,7 +1570,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/libwallet/src/internal/selection.rs b/libwallet/src/internal/selection.rs index 41ed7d74..012672b7 100644 --- a/libwallet/src/internal/selection.rs +++ b/libwallet/src/internal/selection.rs @@ -56,16 +56,17 @@ where slate.amount, slate.height, minimum_confirmations, - slate.lock_height, max_outputs, change_outputs, selection_strategy_is_use_all, &parent_key_id, )?; - let blinding = slate.add_transaction_elements(keychain, &ProofBuilder::new(keychain), elems)?; + // Update the fee on the slate so we account for this when building the tx. slate.fee = fee; + let blinding = slate.add_transaction_elements(keychain, &ProofBuilder::new(keychain), elems)?; + // Create our own private context let mut context = Context::new( keychain.secp(), @@ -270,7 +271,6 @@ pub fn select_send_tx<'a, T: ?Sized, C, K, B>( amount: u64, current_height: u64, minimum_confirmations: u64, - lock_height: u64, max_outputs: usize, change_outputs: usize, selection_strategy_is_use_all: bool, @@ -302,14 +302,9 @@ where )?; // build transaction skeleton with inputs and change - let (mut parts, change_amounts_derivations) = + let (parts, change_amounts_derivations) = inputs_and_change(&coins, wallet, keychain_mask, amount, fee, change_outputs)?; - // Build a "Plain" kernel unless lock_height>0 explicitly specified. - if lock_height > 0 { - parts.push(build::with_lock_height(lock_height)); - } - Ok((parts, coins, change_amounts_derivations, fee)) } @@ -444,8 +439,6 @@ where // calculate the total across all inputs, and how much is left let total: u64 = coins.iter().map(|c| c.value).sum(); - parts.push(build::with_fee(fee)); - // if we are spending 10,000 coins to send 1,000 then our change will be 9,000 // if the fee is 80 then the recipient will receive 1000 and our change will be // 8,920 diff --git a/libwallet/src/internal/tx.rs b/libwallet/src/internal/tx.rs index f75b6ac4..f6712566 100644 --- a/libwallet/src/internal/tx.rs +++ b/libwallet/src/internal/tx.rs @@ -365,6 +365,7 @@ where #[cfg(test)] mod test { + use crate::grin_core::core::KernelFeatures; use crate::grin_core::libtx::{build, ProofBuilder}; use crate::grin_keychain::{ExtKeychain, ExtKeychainPath, Keychain}; @@ -377,12 +378,14 @@ mod test { let key_id1 = ExtKeychainPath::new(1, 1, 0, 0, 0).to_identifier(); let tx1 = build::transaction( + KernelFeatures::Plain { fee: 0 }, vec![build::output(105, key_id1.clone())], &keychain, &builder, ) .unwrap(); let tx2 = build::transaction( + KernelFeatures::Plain { fee: 0 }, vec![build::input(105, key_id1.clone())], &keychain, &builder, diff --git a/libwallet/src/slate.rs b/libwallet/src/slate.rs index 172844a1..8c684bef 100644 --- a/libwallet/src/slate.rs +++ b/libwallet/src/slate.rs @@ -245,21 +245,28 @@ impl Slate { &mut self, keychain: &K, builder: &B, - mut elems: Vec>>, + elems: Vec>>, ) -> Result where K: Keychain, B: ProofBuild, { - // Append to the exiting transaction - if self.tx.kernels().len() != 0 { - elems.insert(0, build::initial_tx(self.tx.clone())); - } - let (tx, blind) = build::partial_transaction(elems, keychain, builder)?; + self.update_kernel(); + let (tx, blind) = build::partial_transaction(self.tx.clone(), elems, keychain, builder)?; self.tx = tx; Ok(blind) } + /// Update the tx kernel based on kernel features derived from the current slate. + /// The fee may change as we build a transaction and we need to + /// update the tx kernel to reflect this during the tx building process. + pub fn update_kernel(&mut self) { + self.tx = self + .tx + .clone() + .replace_kernel(TxKernel::with_features(self.kernel_features())); + } + /// Completes callers part of round 1, adding public key info /// to the slate pub fn fill_round_1( @@ -290,17 +297,22 @@ impl Slate { Ok(()) } - // This is the msg that we will sign as part of the tx kernel. - // If lock_height is 0 then build a plain kernel, otherwise build a height locked kernel. - fn msg_to_sign(&self) -> Result { - let features = match self.lock_height { + // 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. + fn kernel_features(&self) -> KernelFeatures { + match self.lock_height { 0 => KernelFeatures::Plain { fee: self.fee }, _ => KernelFeatures::HeightLocked { fee: self.fee, lock_height: self.lock_height, }, - }; - let msg = features.kernel_sig_msg()?; + } + } + + // This is the msg that we will sign as part of the tx kernel. + // If lock_height is 0 then build a plain kernel, otherwise build a height locked kernel. + fn msg_to_sign(&self) -> Result { + let msg = self.kernel_features().kernel_sig_msg()?; Ok(msg) } @@ -501,6 +513,7 @@ impl Slate { self.tx.kernels().len(), None, ); + if fee > self.tx.fee() { return Err(ErrorKind::Fee( format!("Fee Dispute Error: {}, {}", self.tx.fee(), fee,).to_string(),