mirror of
https://github.com/mimblewimble/grin-wallet.git
synced 2025-02-01 17:01:10 +03:00
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:
parent
3190496402
commit
ba6c5ed0f8
4 changed files with 41 additions and 32 deletions
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -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)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
Loading…
Reference in a new issue