From 4048a3011a307146109cbdbdad1c02d80e4054e2 Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Mon, 27 Aug 2018 20:57:33 -0400 Subject: [PATCH] Improve file-based tx send to not use private file (#1421) Instead of generating a private file on send that needs to be provided again in finalize, the private context information is saved in the wallet db. Also move internal Context to bona fide libwallet type --- src/bin/cmd/client.rs | 1 - src/bin/cmd/wallet.rs | 7 +- src/bin/grin.rs | 7 +- src/bin/tui/peers.rs | 17 ++-- src/bin/tui/table.rs | 11 +-- wallet/src/file_wallet.rs | 18 +++- wallet/src/libwallet/api.rs | 24 +++--- wallet/src/libwallet/internal/mod.rs | 1 - wallet/src/libwallet/internal/selection.rs | 17 ++-- wallet/src/libwallet/internal/sigcontext.rs | 84 ------------------- wallet/src/libwallet/internal/tx.rs | 15 +--- wallet/src/libwallet/types.rs | 92 ++++++++++++++++++++- wallet/src/lmdb_wallet.rs | 25 ++++++ wallet/tests/libwallet.rs | 30 ++++--- 14 files changed, 190 insertions(+), 159 deletions(-) delete mode 100644 wallet/src/libwallet/internal/sigcontext.rs diff --git a/src/bin/cmd/client.rs b/src/bin/cmd/client.rs index 78a20ef2c..714c9521d 100644 --- a/src/bin/cmd/client.rs +++ b/src/bin/cmd/client.rs @@ -13,7 +13,6 @@ // limitations under the License. /// Grin client commands processing - use std::net::SocketAddr; use clap::ArgMatches; diff --git a/src/bin/cmd/wallet.rs b/src/bin/cmd/wallet.rs index 6e6a4bba6..27f093714 100644 --- a/src/bin/cmd/wallet.rs +++ b/src/bin/cmd/wallet.rs @@ -247,12 +247,7 @@ pub fn wallet_command(wallet_args: &ArgMatches, global_config: GlobalConfig) { let tx_file = send_args .value_of("input") .expect("Receiver's transaction file required"); - let priv_file = send_args - .value_of("private") - .expect("Private transaction file required"); - let slate = api - .file_finalize_tx(priv_file, tx_file) - .expect("Finalize failed"); + let slate = api.file_finalize_tx(tx_file).expect("Finalize failed"); let result = api.post_tx(&slate, fluff); match result { diff --git a/src/bin/grin.rs b/src/bin/grin.rs index 7539451a7..e653e4855 100644 --- a/src/bin/grin.rs +++ b/src/bin/grin.rs @@ -208,7 +208,7 @@ fn main() { .default_value("1") .takes_value(true)) .arg(Arg::with_name("dest") - .help("Send the transaction to the provided server") + .help("Send the transaction to the provided server (start with http://) or save as file.") .short("d") .long("dest") .takes_value(true)) @@ -232,11 +232,6 @@ fn main() { .short("i") .long("input") .takes_value(true)) - .arg(Arg::with_name("private") - .help("Private transaction file previously generated by send.") - .short("p") - .long("private") - .takes_value(true)) .arg(Arg::with_name("fluff") .help("Fluff the transaction (ignore Dandelion relay protocol)") .short("f") diff --git a/src/bin/tui/peers.rs b/src/bin/tui/peers.rs index 40a2f11d1..a53036a04 100644 --- a/src/bin/tui/peers.rs +++ b/src/bin/tui/peers.rs @@ -80,15 +80,14 @@ pub struct TUIPeerView; impl TUIStatusListener for TUIPeerView { fn create() -> Box { - let table_view = - TableView::::new() - .column(PeerColumn::Address, "Address", |c| c.width_percent(20)) - .column(PeerColumn::State, "State", |c| c.width_percent(20)) - .column(PeerColumn::Direction, "Direction", |c| c.width_percent(20)) - .column(PeerColumn::TotalDifficulty, "Total Difficulty", |c| { - c.width_percent(20) - }) - .column(PeerColumn::Version, "Version", |c| c.width_percent(20)); + let table_view = TableView::::new() + .column(PeerColumn::Address, "Address", |c| c.width_percent(20)) + .column(PeerColumn::State, "State", |c| c.width_percent(20)) + .column(PeerColumn::Direction, "Direction", |c| c.width_percent(20)) + .column(PeerColumn::TotalDifficulty, "Total Difficulty", |c| { + c.width_percent(20) + }) + .column(PeerColumn::Version, "Version", |c| c.width_percent(20)); let peer_status_view = BoxView::with_full_screen( LinearLayout::new(Orientation::Vertical) .child( diff --git a/src/bin/tui/table.rs b/src/bin/tui/table.rs index 76e9d6f1e..43977207b 100644 --- a/src/bin/tui/table.rs +++ b/src/bin/tui/table.rs @@ -664,7 +664,8 @@ impl, H: Eq + Hash + Copy + Clone + 'static> TableView fn column_select(&mut self) { let next = self.active_column(); let column = self.columns[next].column; - let current = self.columns + let current = self + .columns .iter() .position(|c| c.order != Ordering::Equal) .unwrap_or(0); @@ -736,10 +737,10 @@ impl + 'static, H: Eq + Hash + Copy + Clone + 'static> View let column_count = self.columns.len(); // Split up all columns into sized / unsized groups - let (mut sized, mut usized): (Vec<&mut TableColumn>, Vec<&mut TableColumn>) = - self.columns - .iter_mut() - .partition(|c| c.requested_width.is_some()); + let (mut sized, mut usized): (Vec<&mut TableColumn>, Vec<&mut TableColumn>) = self + .columns + .iter_mut() + .partition(|c| c.requested_width.is_some()); // Subtract one for the separators between our columns (that's column_count - 1) let mut available_width = size.x.saturating_sub(column_count.saturating_sub(1) * 3); diff --git a/wallet/src/file_wallet.rs b/wallet/src/file_wallet.rs index 6d9153f8d..ddecb153a 100644 --- a/wallet/src/file_wallet.rs +++ b/wallet/src/file_wallet.rs @@ -35,7 +35,7 @@ use error::{Error, ErrorKind}; use libwallet; use libwallet::types::{ - OutputData, TxLogEntry, WalletBackend, WalletClient, WalletDetails, WalletOutputBatch, + Context, OutputData, TxLogEntry, WalletBackend, WalletClient, WalletDetails, WalletOutputBatch, }; use types::{WalletConfig, WalletSeed}; @@ -121,6 +121,18 @@ where unimplemented!() } + fn save_private_context( + &mut self, + _slate_id: &[u8], + _ctx: &Context, + ) -> Result<(), libwallet::Error> { + unimplemented!() + } + + fn delete_private_context(&mut self, _slate_id: &[u8]) -> Result<(), libwallet::Error> { + unimplemented!() + } + fn commit(&self) -> Result<(), libwallet::Error> { let mut data_file = File::create(self.data_file_path.clone()) .context(libwallet::ErrorKind::CallbackImpl("Could not create"))?; @@ -239,6 +251,10 @@ where Box::new(self.tx_log.iter().cloned()) } + fn get_private_context(&mut self, _slate_id: &[u8]) -> Result { + unimplemented!() + } + fn get(&self, id: &Identifier) -> Result { self.outputs .get(&id.to_hex()) diff --git a/wallet/src/libwallet/api.rs b/wallet/src/libwallet/api.rs index 889f9e99d..361ae3392 100644 --- a/wallet/src/libwallet/api.rs +++ b/wallet/src/libwallet/api.rs @@ -28,7 +28,7 @@ use core::core::hash::Hashed; use core::ser; use keychain::Keychain; use libtx::slate::Slate; -use libwallet::internal::{selection, sigcontext, tx, updater}; +use libwallet::internal::{selection, tx, updater}; use libwallet::types::{ BlockFees, CbData, OutputData, TxLogEntry, TxWrapper, WalletBackend, WalletClient, WalletInfo, }; @@ -207,9 +207,12 @@ where let mut pub_tx = File::create(dest)?; pub_tx.write_all(json::to_string(&slate).unwrap().as_bytes())?; pub_tx.sync_all()?; - let mut priv_tx = File::create(dest.to_owned() + ".private")?; - priv_tx.write_all(json::to_string(&context).unwrap().as_bytes())?; - priv_tx.sync_all()?; + + { + let mut batch = w.batch()?; + batch.save_private_context(slate.id.as_bytes(), &context)?; + batch.commit()?; + } // lock our inputs lock_fn(&mut **w)?; @@ -259,23 +262,24 @@ where /// propagation. pub fn file_finalize_tx( &mut self, - private_tx_file: &str, receiver_file: &str, ) -> Result { + let mut pub_tx_f = File::open(receiver_file)?; let mut content = String::new(); pub_tx_f.read_to_string(&mut content)?; let mut slate: Slate = json::from_str(&content).map_err(|_| ErrorKind::Format)?; - let mut priv_tx_f = File::open(private_tx_file)?; - let mut content = String::new(); - priv_tx_f.read_to_string(&mut content)?; - let context: sigcontext::Context = json::from_str(&content).map_err(|_| ErrorKind::Format)?; - let mut w = self.wallet.lock().unwrap(); w.open_with_credentials()?; + let context = w.get_private_context(slate.id.as_bytes())?; tx::complete_tx(&mut **w, &mut slate, &context)?; + { + let mut batch = w.batch()?; + batch.delete_private_context(slate.id.as_bytes())?; + batch.commit()?; + } w.close()?; Ok(slate) diff --git a/wallet/src/libwallet/internal/mod.rs b/wallet/src/libwallet/internal/mod.rs index 46c20f834..46c9bd432 100644 --- a/wallet/src/libwallet/internal/mod.rs +++ b/wallet/src/libwallet/internal/mod.rs @@ -24,6 +24,5 @@ pub mod keys; pub mod restore; pub mod selection; -pub mod sigcontext; pub mod tx; pub mod updater; diff --git a/wallet/src/libwallet/internal/selection.rs b/wallet/src/libwallet/internal/selection.rs index 4198fdd57..f073d6b37 100644 --- a/wallet/src/libwallet/internal/selection.rs +++ b/wallet/src/libwallet/internal/selection.rs @@ -17,7 +17,7 @@ use keychain::{Identifier, Keychain}; use libtx::{build, slate::Slate, tx_fee}; use libwallet::error::{Error, ErrorKind}; -use libwallet::internal::{keys, sigcontext}; +use libwallet::internal::keys; use libwallet::types::*; use util::LOGGER; @@ -37,14 +37,7 @@ pub fn build_send_tx_slate( max_outputs: usize, change_outputs: usize, selection_strategy_is_use_all: bool, -) -> Result< - ( - Slate, - sigcontext::Context, - impl FnOnce(&mut T) -> Result<(), Error>, - ), - Error, -> +) -> Result<(Slate, Context, impl FnOnce(&mut T) -> Result<(), Error>), Error> where T: WalletBackend, C: WalletClient, @@ -74,7 +67,7 @@ where let blinding = slate.add_transaction_elements(&keychain, elems)?; // Create our own private context - let mut context = sigcontext::Context::new( + let mut context = Context::new( wallet.keychain().secp(), blinding.secret_key(&keychain.secp()).unwrap(), ); @@ -149,7 +142,7 @@ pub fn build_recipient_output_with_slate( ) -> Result< ( Identifier, - sigcontext::Context, + Context, impl FnOnce(&mut T) -> Result<(), Error>, ), Error, @@ -173,7 +166,7 @@ where slate.add_transaction_elements(&keychain, vec![build::output(amount, key_id.clone())])?; // Add blinding sum to our context - let mut context = sigcontext::Context::new( + let mut context = Context::new( keychain.secp(), blinding .secret_key(wallet.keychain().clone().secp()) diff --git a/wallet/src/libwallet/internal/sigcontext.rs b/wallet/src/libwallet/internal/sigcontext.rs deleted file mode 100644 index 2ee07f04d..000000000 --- a/wallet/src/libwallet/internal/sigcontext.rs +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2018 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. -//! Signature context holder helper (may be removed or replaced eventually) -use keychain::Identifier; -use libtx::aggsig; -use util::secp::key::{PublicKey, SecretKey}; -use util::secp::{self, Secp256k1}; - -#[derive(Serialize, Deserialize, Clone, Debug)] -/// Holds the context for a single aggsig transaction -pub struct Context { - /// Secret key (of which public is shared) - pub sec_key: SecretKey, - /// Secret nonce (of which public is shared) - /// (basically a SecretKey) - pub sec_nonce: SecretKey, - /// store my outputs between invocations - pub output_ids: Vec, - /// store my inputs - pub input_ids: Vec, - /// store the calculated fee - pub fee: u64, -} - -impl Context { - /// Create a new context with defaults - pub fn new(secp: &secp::Secp256k1, sec_key: SecretKey) -> Context { - Context { - sec_key: sec_key, - sec_nonce: aggsig::create_secnonce(secp).unwrap(), - input_ids: vec![], - output_ids: vec![], - fee: 0, - } - } -} - -impl Context { - /// Tracks an output contributing to my excess value (if it needs to - /// be kept between invocations - pub fn add_output(&mut self, output_id: &Identifier) { - self.output_ids.push(output_id.clone()); - } - - /// Returns all stored outputs - pub fn get_outputs(&self) -> Vec { - self.output_ids.clone() - } - - /// Tracks IDs of my inputs into the transaction - /// be kept between invocations - pub fn add_input(&mut self, input_id: &Identifier) { - self.input_ids.push(input_id.clone()); - } - - /// Returns all stored input identifiers - pub fn get_inputs(&self) -> Vec { - self.input_ids.clone() - } - - /// Returns private key, private nonce - pub fn get_private_keys(&self) -> (SecretKey, SecretKey) { - (self.sec_key.clone(), self.sec_nonce.clone()) - } - - /// Returns public key, public nonce - pub fn get_public_keys(&self, secp: &Secp256k1) -> (PublicKey, PublicKey) { - ( - PublicKey::from_secret_key(secp, &self.sec_key).unwrap(), - PublicKey::from_secret_key(secp, &self.sec_nonce).unwrap(), - ) - } -} diff --git a/wallet/src/libwallet/internal/tx.rs b/wallet/src/libwallet/internal/tx.rs index 4b070c378..9f612bd6e 100644 --- a/wallet/src/libwallet/internal/tx.rs +++ b/wallet/src/libwallet/internal/tx.rs @@ -18,8 +18,8 @@ use core::core::Transaction; use keychain::{Identifier, Keychain}; use libtx::slate::Slate; use libtx::{build, tx_fee}; -use libwallet::internal::{selection, sigcontext, updater}; -use libwallet::types::{TxLogEntryType, WalletBackend, WalletClient}; +use libwallet::internal::{selection, updater}; +use libwallet::types::{Context, TxLogEntryType, WalletBackend, WalletClient}; use libwallet::{Error, ErrorKind}; use util::LOGGER; @@ -61,14 +61,7 @@ pub fn create_send_tx( max_outputs: usize, num_change_outputs: usize, selection_strategy_is_use_all: bool, -) -> Result< - ( - Slate, - sigcontext::Context, - impl FnOnce(&mut T) -> Result<(), Error>, - ), - Error, -> +) -> Result<(Slate, Context, impl FnOnce(&mut T) -> Result<(), Error>), Error> where T: WalletBackend, C: WalletClient, @@ -117,7 +110,7 @@ where pub fn complete_tx( wallet: &mut T, slate: &mut Slate, - context: &sigcontext::Context, + context: &Context, ) -> Result<(), Error> where T: WalletBackend, diff --git a/wallet/src/libwallet/types.rs b/wallet/src/libwallet/types.rs index 1f3a7f7d7..6d1023869 100644 --- a/wallet/src/libwallet/types.rs +++ b/wallet/src/libwallet/types.rs @@ -30,10 +30,12 @@ use core::ser; use keychain::{Identifier, Keychain}; +use libtx::aggsig; use libtx::slate::Slate; use libwallet::error::{Error, ErrorKind}; -use util::secp::pedersen; +use util::secp::key::{PublicKey, SecretKey}; +use util::secp::{self, pedersen, Secp256k1}; /// Combined trait to allow dynamic wallet dispatch pub trait WalletInst: WalletBackend + Send + Sync + 'static @@ -82,6 +84,9 @@ where /// Get an (Optional) tx log entry by uuid fn get_tx_log_entry(&self, uuid: &Uuid) -> Result, Error>; + /// Retrieves the private context associated with a given slate id + fn get_private_context(&mut self, slate_id: &[u8]) -> Result; + /// Iterate over all output data stored by the backend fn tx_log_iter<'a>(&'a self) -> Box + 'a>; @@ -137,6 +142,12 @@ where /// Save an output as locked in the backend fn lock_output(&mut self, out: &mut OutputData) -> Result<(), Error>; + /// Saves the private context associated with a slate id + fn save_private_context(&mut self, slate_id: &[u8], ctx: &Context) -> Result<(), Error>; + + /// Delete the private context associated with the slate id + fn delete_private_context(&mut self, slate_id: &[u8]) -> Result<(), Error>; + /// Write the wallet data to backend file fn commit(&self) -> Result<(), Error>; } @@ -315,6 +326,85 @@ impl fmt::Display for OutputStatus { } } +#[derive(Serialize, Deserialize, Clone, Debug)] +/// Holds the context for a single aggsig transaction +pub struct Context { + /// Secret key (of which public is shared) + pub sec_key: SecretKey, + /// Secret nonce (of which public is shared) + /// (basically a SecretKey) + pub sec_nonce: SecretKey, + /// store my outputs between invocations + pub output_ids: Vec, + /// store my inputs + pub input_ids: Vec, + /// store the calculated fee + pub fee: u64, +} + +impl Context { + /// Create a new context with defaults + pub fn new(secp: &secp::Secp256k1, sec_key: SecretKey) -> Context { + Context { + sec_key: sec_key, + sec_nonce: aggsig::create_secnonce(secp).unwrap(), + input_ids: vec![], + output_ids: vec![], + fee: 0, + } + } +} + +impl Context { + /// Tracks an output contributing to my excess value (if it needs to + /// be kept between invocations + pub fn add_output(&mut self, output_id: &Identifier) { + self.output_ids.push(output_id.clone()); + } + + /// Returns all stored outputs + pub fn get_outputs(&self) -> Vec { + self.output_ids.clone() + } + + /// Tracks IDs of my inputs into the transaction + /// be kept between invocations + pub fn add_input(&mut self, input_id: &Identifier) { + self.input_ids.push(input_id.clone()); + } + + /// Returns all stored input identifiers + pub fn get_inputs(&self) -> Vec { + self.input_ids.clone() + } + + /// Returns private key, private nonce + pub fn get_private_keys(&self) -> (SecretKey, SecretKey) { + (self.sec_key.clone(), self.sec_nonce.clone()) + } + + /// Returns public key, public nonce + pub fn get_public_keys(&self, secp: &Secp256k1) -> (PublicKey, PublicKey) { + ( + PublicKey::from_secret_key(secp, &self.sec_key).unwrap(), + PublicKey::from_secret_key(secp, &self.sec_nonce).unwrap(), + ) + } +} + +impl ser::Writeable for Context { + fn write(&self, writer: &mut W) -> Result<(), ser::Error> { + writer.write_bytes(&serde_json::to_vec(self).map_err(|_| ser::Error::CorruptedData)?) + } +} + +impl ser::Readable for Context { + fn read(reader: &mut ser::Reader) -> Result { + let data = reader.read_vec()?; + serde_json::from_slice(&data[..]).map_err(|_| ser::Error::CorruptedData) + } +} + /// Block Identifier #[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)] pub struct BlockIdentifier(pub Hash); diff --git a/wallet/src/lmdb_wallet.rs b/wallet/src/lmdb_wallet.rs index 94c6eeccc..4287e96da 100644 --- a/wallet/src/lmdb_wallet.rs +++ b/wallet/src/lmdb_wallet.rs @@ -33,6 +33,7 @@ const COMMITMENT_PREFIX: u8 = 'C' as u8; const OUTPUT_PREFIX: u8 = 'o' as u8; const DERIV_PREFIX: u8 = 'd' as u8; const CONFIRMED_HEIGHT_PREFIX: u8 = 'c' as u8; +const PRIVATE_TX_CONTEXT_PREFIX: u8 = 'p' as u8; const TX_LOG_ENTRY_PREFIX: u8 = 't' as u8; const TX_LOG_ID_PREFIX: u8 = 'i' as u8; @@ -161,6 +162,14 @@ where Box::new(self.db.iter(&[TX_LOG_ENTRY_PREFIX]).unwrap()) } + fn get_private_context(&mut self, slate_id: &[u8]) -> Result { + let ctx_key = to_key(PRIVATE_TX_CONTEXT_PREFIX, &mut slate_id.to_vec()); + option_to_not_found( + self.db.get_ser(&ctx_key), + &format!("Slate id: {:x?}", slate_id.to_vec()), + ).map_err(|e| e.into()) + } + fn batch<'a>(&'a mut self) -> Result + 'a>, Error> { Ok(Box::new(Batch { _store: self, @@ -336,6 +345,22 @@ where self.save(out.clone()) } + fn save_private_context(&mut self, slate_id: &[u8], ctx: &Context) -> Result<(), Error> { + let ctx_key = to_key(PRIVATE_TX_CONTEXT_PREFIX, &mut slate_id.to_vec()); + self.db.borrow().as_ref().unwrap().put_ser(&ctx_key, &ctx)?; + Ok(()) + } + + fn delete_private_context(&mut self, slate_id: &[u8]) -> Result<(), Error> { + let ctx_key = to_key(PRIVATE_TX_CONTEXT_PREFIX, &mut slate_id.to_vec()); + self.db + .borrow() + .as_ref() + .unwrap() + .delete(&ctx_key) + .map_err(|e| e.into()) + } + fn commit(&self) -> Result<(), Error> { let db = self.db.replace(None); db.unwrap().commit()?; diff --git a/wallet/tests/libwallet.rs b/wallet/tests/libwallet.rs index 81db7eae6..82cb37349 100644 --- a/wallet/tests/libwallet.rs +++ b/wallet/tests/libwallet.rs @@ -24,7 +24,7 @@ use keychain::{BlindSum, BlindingFactor, ExtKeychain, Keychain}; use util::secp::key::{PublicKey, SecretKey}; use util::{kernel_sig_msg, secp}; use wallet::libtx::{aggsig, proof}; -use wallet::libwallet::internal::sigcontext; +use wallet::libwallet::types::Context; use rand::thread_rng; @@ -46,9 +46,11 @@ fn aggsig_sender_receiver_interaction() { let keychain = ExtKeychain::from_random_seed().unwrap(); let blinding_factor = keychain - .blind_sum(&BlindSum::new() - .sub_blinding_factor(BlindingFactor::from_secret_key(skey1)) - .add_blinding_factor(BlindingFactor::from_secret_key(skey2))) + .blind_sum( + &BlindSum::new() + .sub_blinding_factor(BlindingFactor::from_secret_key(skey1)) + .add_blinding_factor(BlindingFactor::from_secret_key(skey2)), + ) .unwrap(); keychain @@ -76,7 +78,7 @@ fn aggsig_sender_receiver_interaction() { let blind = blinding_factor.secret_key(&keychain.secp()).unwrap(); - s_cx = sigcontext::Context::new(&keychain.secp(), blind); + s_cx = Context::new(&keychain.secp(), blind); s_cx.get_public_keys(&keychain.secp()) }; @@ -89,7 +91,7 @@ fn aggsig_sender_receiver_interaction() { // let blind = blind_sum.secret_key(&keychain.secp())?; let blind = keychain.derived_key(&key_id).unwrap(); - rx_cx = sigcontext::Context::new(&keychain.secp(), blind); + rx_cx = Context::new(&keychain.secp(), blind); let (pub_excess, pub_nonce) = rx_cx.get_public_keys(&keychain.secp()); rx_cx.add_output(&key_id); @@ -234,12 +236,14 @@ fn aggsig_sender_receiver_interaction_offset() { let keychain = ExtKeychain::from_random_seed().unwrap(); let blinding_factor = keychain - .blind_sum(&BlindSum::new() + .blind_sum( + &BlindSum::new() .sub_blinding_factor(BlindingFactor::from_secret_key(skey1)) .add_blinding_factor(BlindingFactor::from_secret_key(skey2)) // subtract the kernel offset here like as would when // verifying a kernel signature - .sub_blinding_factor(BlindingFactor::from_secret_key(kernel_offset))) + .sub_blinding_factor(BlindingFactor::from_secret_key(kernel_offset)), + ) .unwrap(); keychain @@ -261,16 +265,18 @@ fn aggsig_sender_receiver_interaction_offset() { // dealing with an input here so we need to negate the blinding_factor // rather than use it as is let blinding_factor = keychain - .blind_sum(&BlindSum::new() + .blind_sum( + &BlindSum::new() .sub_blinding_factor(BlindingFactor::from_secret_key(skey)) // subtract the kernel offset to create an aggsig context // with our "split" key - .sub_blinding_factor(BlindingFactor::from_secret_key(kernel_offset))) + .sub_blinding_factor(BlindingFactor::from_secret_key(kernel_offset)), + ) .unwrap(); let blind = blinding_factor.secret_key(&keychain.secp()).unwrap(); - s_cx = sigcontext::Context::new(&keychain.secp(), blind); + s_cx = Context::new(&keychain.secp(), blind); s_cx.get_public_keys(&keychain.secp()) }; @@ -282,7 +288,7 @@ fn aggsig_sender_receiver_interaction_offset() { let blind = keychain.derived_key(&key_id).unwrap(); - rx_cx = sigcontext::Context::new(&keychain.secp(), blind); + rx_cx = Context::new(&keychain.secp(), blind); let (pub_excess, pub_nonce) = rx_cx.get_public_keys(&keychain.secp()); rx_cx.add_output(&key_id);