Tx combinator refactor (#249)

* update tx building to use simpler kernel feature handling

* pass in tx to build::partial_transaction
and update the kernel on the tx based on features from the slate

* bump SHA for grin dependencies
This commit is contained in:
Antioch Peverell 2019-11-01 12:20:36 +00:00 committed by Yeastplume
parent 3190496402
commit ba6c5ed0f8
4 changed files with 41 additions and 32 deletions

18
Cargo.lock generated
View file

@ -683,7 +683,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "grin_api" name = "grin_api"
version = "3.0.0-alpha.1" version = "3.0.0-alpha.1"
source = "git+https://github.com/mimblewimble/grin#da2e75299191acd70d4a48bd63c3dcb2cfcc74d2" source = "git+https://github.com/mimblewimble/grin#50ce7ba0433e916ddf6154ff64bdd987bd0e68c2"
dependencies = [ dependencies = [
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -716,7 +716,7 @@ dependencies = [
[[package]] [[package]]
name = "grin_chain" name = "grin_chain"
version = "3.0.0-alpha.1" version = "3.0.0-alpha.1"
source = "git+https://github.com/mimblewimble/grin#da2e75299191acd70d4a48bd63c3dcb2cfcc74d2" source = "git+https://github.com/mimblewimble/grin#50ce7ba0433e916ddf6154ff64bdd987bd0e68c2"
dependencies = [ dependencies = [
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -739,7 +739,7 @@ dependencies = [
[[package]] [[package]]
name = "grin_core" name = "grin_core"
version = "3.0.0-alpha.1" version = "3.0.0-alpha.1"
source = "git+https://github.com/mimblewimble/grin#da2e75299191acd70d4a48bd63c3dcb2cfcc74d2" source = "git+https://github.com/mimblewimble/grin#50ce7ba0433e916ddf6154ff64bdd987bd0e68c2"
dependencies = [ dependencies = [
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -766,7 +766,7 @@ dependencies = [
[[package]] [[package]]
name = "grin_keychain" name = "grin_keychain"
version = "3.0.0-alpha.1" version = "3.0.0-alpha.1"
source = "git+https://github.com/mimblewimble/grin#da2e75299191acd70d4a48bd63c3dcb2cfcc74d2" source = "git+https://github.com/mimblewimble/grin#50ce7ba0433e916ddf6154ff64bdd987bd0e68c2"
dependencies = [ dependencies = [
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -789,7 +789,7 @@ dependencies = [
[[package]] [[package]]
name = "grin_p2p" name = "grin_p2p"
version = "3.0.0-alpha.1" version = "3.0.0-alpha.1"
source = "git+https://github.com/mimblewimble/grin#da2e75299191acd70d4a48bd63c3dcb2cfcc74d2" source = "git+https://github.com/mimblewimble/grin#50ce7ba0433e916ddf6154ff64bdd987bd0e68c2"
dependencies = [ dependencies = [
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
@ -812,7 +812,7 @@ dependencies = [
[[package]] [[package]]
name = "grin_pool" name = "grin_pool"
version = "3.0.0-alpha.1" version = "3.0.0-alpha.1"
source = "git+https://github.com/mimblewimble/grin#da2e75299191acd70d4a48bd63c3dcb2cfcc74d2" source = "git+https://github.com/mimblewimble/grin#50ce7ba0433e916ddf6154ff64bdd987bd0e68c2"
dependencies = [ dependencies = [
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -846,7 +846,7 @@ dependencies = [
[[package]] [[package]]
name = "grin_store" name = "grin_store"
version = "3.0.0-alpha.1" version = "3.0.0-alpha.1"
source = "git+https://github.com/mimblewimble/grin#da2e75299191acd70d4a48bd63c3dcb2cfcc74d2" source = "git+https://github.com/mimblewimble/grin#50ce7ba0433e916ddf6154ff64bdd987bd0e68c2"
dependencies = [ dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "croaring 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -867,7 +867,7 @@ dependencies = [
[[package]] [[package]]
name = "grin_util" name = "grin_util"
version = "3.0.0-alpha.1" version = "3.0.0-alpha.1"
source = "git+https://github.com/mimblewimble/grin#da2e75299191acd70d4a48bd63c3dcb2cfcc74d2" source = "git+https://github.com/mimblewimble/grin#50ce7ba0433e916ddf6154ff64bdd987bd0e68c2"
dependencies = [ dependencies = [
"backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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 = [ dependencies = [
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
] ]

View file

@ -56,16 +56,17 @@ where
slate.amount, slate.amount,
slate.height, slate.height,
minimum_confirmations, minimum_confirmations,
slate.lock_height,
max_outputs, max_outputs,
change_outputs, change_outputs,
selection_strategy_is_use_all, selection_strategy_is_use_all,
&parent_key_id, &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; slate.fee = fee;
let blinding = slate.add_transaction_elements(keychain, &ProofBuilder::new(keychain), elems)?;
// Create our own private context // Create our own private context
let mut context = Context::new( let mut context = Context::new(
keychain.secp(), keychain.secp(),
@ -270,7 +271,6 @@ pub fn select_send_tx<'a, T: ?Sized, C, K, B>(
amount: u64, amount: u64,
current_height: u64, current_height: u64,
minimum_confirmations: u64, minimum_confirmations: u64,
lock_height: u64,
max_outputs: usize, max_outputs: usize,
change_outputs: usize, change_outputs: usize,
selection_strategy_is_use_all: bool, selection_strategy_is_use_all: bool,
@ -302,14 +302,9 @@ where
)?; )?;
// build transaction skeleton with inputs and change // 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)?; 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)) Ok((parts, coins, change_amounts_derivations, fee))
} }
@ -444,8 +439,6 @@ where
// calculate the total across all inputs, and how much is left // calculate the total across all inputs, and how much is left
let total: u64 = coins.iter().map(|c| c.value).sum(); 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 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 // if the fee is 80 then the recipient will receive 1000 and our change will be
// 8,920 // 8,920

View file

@ -365,6 +365,7 @@ where
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::grin_core::core::KernelFeatures;
use crate::grin_core::libtx::{build, ProofBuilder}; use crate::grin_core::libtx::{build, ProofBuilder};
use crate::grin_keychain::{ExtKeychain, ExtKeychainPath, Keychain}; 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 key_id1 = ExtKeychainPath::new(1, 1, 0, 0, 0).to_identifier();
let tx1 = build::transaction( let tx1 = build::transaction(
KernelFeatures::Plain { fee: 0 },
vec![build::output(105, key_id1.clone())], vec![build::output(105, key_id1.clone())],
&keychain, &keychain,
&builder, &builder,
) )
.unwrap(); .unwrap();
let tx2 = build::transaction( let tx2 = build::transaction(
KernelFeatures::Plain { fee: 0 },
vec![build::input(105, key_id1.clone())], vec![build::input(105, key_id1.clone())],
&keychain, &keychain,
&builder, &builder,

View file

@ -245,21 +245,28 @@ impl Slate {
&mut self, &mut self,
keychain: &K, keychain: &K,
builder: &B, builder: &B,
mut elems: Vec<Box<build::Append<K, B>>>, elems: Vec<Box<build::Append<K, B>>>,
) -> Result<BlindingFactor, Error> ) -> Result<BlindingFactor, Error>
where where
K: Keychain, K: Keychain,
B: ProofBuild, B: ProofBuild,
{ {
// Append to the exiting transaction self.update_kernel();
if self.tx.kernels().len() != 0 { let (tx, blind) = build::partial_transaction(self.tx.clone(), elems, keychain, builder)?;
elems.insert(0, build::initial_tx(self.tx.clone()));
}
let (tx, blind) = build::partial_transaction(elems, keychain, builder)?;
self.tx = tx; self.tx = tx;
Ok(blind) 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 /// Completes callers part of round 1, adding public key info
/// to the slate /// to the slate
pub fn fill_round_1<K>( pub fn fill_round_1<K>(
@ -290,17 +297,22 @@ impl Slate {
Ok(()) Ok(())
} }
// This is the msg that we will sign as part of the tx kernel. // Construct the appropriate kernel features based on our fee and lock_height.
// If lock_height is 0 then build a plain kernel, otherwise build a height locked kernel. // If lock_height is 0 then its a plain kernel, otherwise its a height locked kernel.
fn msg_to_sign(&self) -> Result<secp::Message, Error> { fn kernel_features(&self) -> KernelFeatures {
let features = match self.lock_height { match self.lock_height {
0 => KernelFeatures::Plain { fee: self.fee }, 0 => KernelFeatures::Plain { fee: self.fee },
_ => KernelFeatures::HeightLocked { _ => KernelFeatures::HeightLocked {
fee: self.fee, fee: self.fee,
lock_height: self.lock_height, 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<secp::Message, Error> {
let msg = self.kernel_features().kernel_sig_msg()?;
Ok(msg) Ok(msg)
} }
@ -501,6 +513,7 @@ impl Slate {
self.tx.kernels().len(), self.tx.kernels().len(),
None, None,
); );
if fee > self.tx.fee() { if fee > self.tx.fee() {
return Err(ErrorKind::Fee( return Err(ErrorKind::Fee(
format!("Fee Dispute Error: {}, {}", self.tx.fee(), fee,).to_string(), format!("Fee Dispute Error: {}, {}", self.tx.fee(), fee,).to_string(),