Wallet self-send (#1939)
* add self send function to wallet * rustfmt * add destination to self send method * update usage doc * doc clarification * remove localhost send restriction
This commit is contained in:
@@ -181,6 +181,7 @@ where
|
||||
num_change_outputs,
|
||||
selection_strategy_is_use_all,
|
||||
&parent_key_id,
|
||||
false,
|
||||
)?;
|
||||
|
||||
lock_fn_out = lock_fn;
|
||||
@@ -204,6 +205,50 @@ where
|
||||
Ok(slate_out)
|
||||
}
|
||||
|
||||
/// Issues a send transaction to the same wallet, without needing communication
|
||||
/// good for consolidating outputs, or can be extended to split outputs to multiple
|
||||
/// accounts
|
||||
pub fn issue_self_tx(
|
||||
&mut self,
|
||||
amount: u64,
|
||||
minimum_confirmations: u64,
|
||||
max_outputs: usize,
|
||||
num_change_outputs: usize,
|
||||
selection_strategy_is_use_all: bool,
|
||||
src_acct_name: &str,
|
||||
dest_acct_name: &str,
|
||||
) -> Result<Slate, Error> {
|
||||
let mut w = self.wallet.lock();
|
||||
w.open_with_credentials()?;
|
||||
let orig_parent_key_id = w.parent_key_id();
|
||||
w.set_parent_key_id_by_name(src_acct_name)?;
|
||||
let parent_key_id = w.parent_key_id();
|
||||
|
||||
let (mut slate, context, lock_fn) = tx::create_send_tx(
|
||||
&mut **w,
|
||||
amount,
|
||||
minimum_confirmations,
|
||||
max_outputs,
|
||||
num_change_outputs,
|
||||
selection_strategy_is_use_all,
|
||||
&parent_key_id,
|
||||
true,
|
||||
)?;
|
||||
|
||||
w.set_parent_key_id_by_name(dest_acct_name)?;
|
||||
let parent_key_id = w.parent_key_id();
|
||||
tx::receive_tx(&mut **w, &mut slate, &parent_key_id, true)?;
|
||||
|
||||
tx::complete_tx(&mut **w, &mut slate, &context)?;
|
||||
let tx_hex = util::to_hex(ser::ser_vec(&slate.tx).unwrap());
|
||||
|
||||
// lock our inputs
|
||||
lock_fn(&mut **w, &tx_hex)?;
|
||||
w.set_parent_key_id(orig_parent_key_id);
|
||||
w.close()?;
|
||||
Ok(slate)
|
||||
}
|
||||
|
||||
/// Write a transaction to send to file so a user can transmit it to the
|
||||
/// receiver in whichever way they see fit (aka carrier pigeon mode).
|
||||
pub fn send_tx(
|
||||
@@ -228,6 +273,7 @@ where
|
||||
num_change_outputs,
|
||||
selection_strategy_is_use_all,
|
||||
&parent_key_id,
|
||||
false,
|
||||
)?;
|
||||
if write_to_disk {
|
||||
let mut pub_tx = File::create(dest)?;
|
||||
@@ -507,8 +553,12 @@ where
|
||||
let parent_key_id = wallet.parent_key_id();
|
||||
|
||||
// create an output using the amount in the slate
|
||||
let (_, mut context, receiver_create_fn) =
|
||||
selection::build_recipient_output_with_slate(&mut **wallet, &mut slate, parent_key_id)?;
|
||||
let (_, mut context, receiver_create_fn) = selection::build_recipient_output_with_slate(
|
||||
&mut **wallet,
|
||||
&mut slate,
|
||||
parent_key_id,
|
||||
false,
|
||||
)?;
|
||||
|
||||
// fill public keys
|
||||
let _ = slate.fill_round_1(
|
||||
@@ -535,7 +585,7 @@ where
|
||||
let mut w = self.wallet.lock();
|
||||
w.open_with_credentials()?;
|
||||
let parent_key_id = w.parent_key_id();
|
||||
let res = tx::receive_tx(&mut **w, slate, &parent_key_id);
|
||||
let res = tx::receive_tx(&mut **w, slate, &parent_key_id, false);
|
||||
w.close()?;
|
||||
|
||||
if let Err(e) = res {
|
||||
|
||||
@@ -36,6 +36,7 @@ pub fn build_send_tx_slate<T: ?Sized, C, K>(
|
||||
change_outputs: usize,
|
||||
selection_strategy_is_use_all: bool,
|
||||
parent_key_id: Identifier,
|
||||
is_self: bool,
|
||||
) -> Result<
|
||||
(
|
||||
Slate,
|
||||
@@ -98,6 +99,9 @@ where
|
||||
let mut batch = wallet.batch()?;
|
||||
let log_id = batch.next_tx_log_id(&parent_key_id)?;
|
||||
let mut t = TxLogEntry::new(parent_key_id.clone(), TxLogEntryType::TxSent, log_id);
|
||||
if is_self {
|
||||
t.tx_type = TxLogEntryType::TxSentSelf;
|
||||
}
|
||||
t.tx_slate_id = Some(slate_id);
|
||||
t.fee = Some(fee);
|
||||
t.tx_hex = Some(tx_hex.to_owned());
|
||||
@@ -144,6 +148,7 @@ pub fn build_recipient_output_with_slate<T: ?Sized, C, K>(
|
||||
wallet: &mut T,
|
||||
slate: &mut Slate,
|
||||
parent_key_id: Identifier,
|
||||
is_self: bool,
|
||||
) -> Result<
|
||||
(
|
||||
Identifier,
|
||||
@@ -185,6 +190,9 @@ where
|
||||
let mut batch = wallet.batch()?;
|
||||
let log_id = batch.next_tx_log_id(&parent_key_id)?;
|
||||
let mut t = TxLogEntry::new(parent_key_id.clone(), TxLogEntryType::TxReceived, log_id);
|
||||
if is_self {
|
||||
t.tx_type = TxLogEntryType::TxReceivedSelf;
|
||||
}
|
||||
t.tx_slate_id = Some(slate_id);
|
||||
t.amount_credited = amount;
|
||||
t.num_outputs = 1;
|
||||
|
||||
@@ -32,6 +32,7 @@ pub fn receive_tx<T: ?Sized, C, K>(
|
||||
wallet: &mut T,
|
||||
slate: &mut Slate,
|
||||
parent_key_id: &Identifier,
|
||||
is_self: bool,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
T: WalletBackend<C, K>,
|
||||
@@ -39,8 +40,12 @@ where
|
||||
K: Keychain,
|
||||
{
|
||||
// create an output using the amount in the slate
|
||||
let (_, mut context, receiver_create_fn) =
|
||||
selection::build_recipient_output_with_slate(wallet, slate, parent_key_id.clone())?;
|
||||
let (_, mut context, receiver_create_fn) = selection::build_recipient_output_with_slate(
|
||||
wallet,
|
||||
slate,
|
||||
parent_key_id.clone(),
|
||||
is_self,
|
||||
)?;
|
||||
|
||||
// fill public keys
|
||||
let _ = slate.fill_round_1(
|
||||
@@ -69,6 +74,7 @@ pub fn create_send_tx<T: ?Sized, C, K>(
|
||||
num_change_outputs: usize,
|
||||
selection_strategy_is_use_all: bool,
|
||||
parent_key_id: &Identifier,
|
||||
is_self: bool,
|
||||
) -> Result<
|
||||
(
|
||||
Slate,
|
||||
@@ -107,6 +113,7 @@ where
|
||||
num_change_outputs,
|
||||
selection_strategy_is_use_all,
|
||||
parent_key_id.clone(),
|
||||
is_self,
|
||||
)?;
|
||||
|
||||
// Generate a kernel offset and subtract from our context's secret key. Store
|
||||
|
||||
@@ -546,6 +546,10 @@ pub enum TxLogEntryType {
|
||||
TxReceived,
|
||||
/// Inputs locked + change outputs when a transaction is created
|
||||
TxSent,
|
||||
/// As above, but self-transaction
|
||||
TxReceivedSelf,
|
||||
/// As Above
|
||||
TxSentSelf,
|
||||
/// Received transaction that was rolled back by user
|
||||
TxReceivedCancelled,
|
||||
/// Sent transaction that was rolled back by user
|
||||
@@ -558,6 +562,8 @@ impl fmt::Display for TxLogEntryType {
|
||||
TxLogEntryType::ConfirmedCoinbase => write!(f, "Confirmed \nCoinbase"),
|
||||
TxLogEntryType::TxReceived => write!(f, "Received Tx"),
|
||||
TxLogEntryType::TxSent => write!(f, "Sent Tx"),
|
||||
TxLogEntryType::TxReceivedSelf => write!(f, "Received Tx (Self)"),
|
||||
TxLogEntryType::TxSentSelf => write!(f, "Sent Tx (Self)"),
|
||||
TxLogEntryType::TxReceivedCancelled => write!(f, "Received Tx\n- Cancelled"),
|
||||
TxLogEntryType::TxSentCancelled => write!(f, "Send Tx\n- Cancelled"),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user