mirror of
https://github.com/jwinterm/grin-wallet.git
synced 2026-10-27 10:58:37 +01:00
TTL Implementation (#261)
* refactor address generation code into libwallet, bool to flag whether to include proof, add sender address in init_send_tx * rustfmt * require payment proof addr as part of init_tx * rustfmt * store payment proof on sender transaction side * rustfmt * change sig to ed25519 sig * rustfmt * add message creation and signature * rustfmt * add payment proof verification function * rustfmt * validate proof on sender side, store proof * rustfmt * fix json tests * fixes and updates to tests * added API functions for converting and retrieving proof addresses * rustfmt * add payment proof to init_send_tx example * rustfmt * incorrect comment * add commands for requesting payment proofs * rustfmt * wire up payment proofs into command line * rustfmt * add address command * rustfmt * added tor sending from owner api * rustfmt * add TTL to slate, transaction log * ttl cutoff tests * add ttl check to recieve functions, add tests, modify doctests * rustfmt * fixes from upstream changes and test fixes * rustfmt * remove unnecessary block header version check
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
//! Generic implementation of owner API functions
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::api_impl::owner::check_ttl;
|
||||
use crate::grin_keychain::Keychain;
|
||||
use crate::grin_util::secp::key::SecretKey;
|
||||
use crate::internal::{tx, updater};
|
||||
@@ -70,6 +71,7 @@ where
|
||||
K: Keychain + 'a,
|
||||
{
|
||||
let mut ret_slate = slate.clone();
|
||||
check_ttl(w, &ret_slate)?;
|
||||
let parent_key_id = match dest_acct_name {
|
||||
Some(d) => {
|
||||
let pm = w.get_acct_path(d.to_owned())?;
|
||||
@@ -143,6 +145,7 @@ where
|
||||
K: Keychain + 'a,
|
||||
{
|
||||
let mut sl = slate.clone();
|
||||
check_ttl(w, &sl)?;
|
||||
let context = w.get_private_context(keychain_mask, sl.id.as_bytes(), 1)?;
|
||||
tx::complete_tx(&mut *w, keychain_mask, &mut sl, 1, &context)?;
|
||||
tx::update_stored_tx(&mut *w, keychain_mask, &context, &mut sl, true)?;
|
||||
|
||||
@@ -224,7 +224,7 @@ where
|
||||
None => None,
|
||||
};
|
||||
|
||||
let mut slate = tx::new_tx_slate(&mut *w, args.amount, 2, use_test_rng)?;
|
||||
let mut slate = tx::new_tx_slate(&mut *w, args.amount, 2, use_test_rng, args.ttl_blocks)?;
|
||||
|
||||
// if we just want to estimate, don't save a context, just send the results
|
||||
// back
|
||||
@@ -324,7 +324,7 @@ where
|
||||
None => None,
|
||||
};
|
||||
|
||||
let mut slate = tx::new_tx_slate(&mut *w, args.amount, 2, use_test_rng)?;
|
||||
let mut slate = tx::new_tx_slate(&mut *w, args.amount, 2, use_test_rng, None)?;
|
||||
let context = tx::add_output_to_slate(
|
||||
&mut *w,
|
||||
keychain_mask,
|
||||
@@ -366,6 +366,7 @@ where
|
||||
K: Keychain + 'a,
|
||||
{
|
||||
let mut ret_slate = slate.clone();
|
||||
check_ttl(w, &ret_slate)?;
|
||||
let parent_key_id = match args.src_acct_name {
|
||||
Some(d) => {
|
||||
let pm = w.get_acct_path(d.to_owned())?;
|
||||
@@ -401,6 +402,11 @@ where
|
||||
// update slate current height
|
||||
ret_slate.height = w.w2n_client().get_chain_tip()?.0;
|
||||
|
||||
// update ttl if desired
|
||||
if let Some(b) = args.ttl_blocks {
|
||||
ret_slate.ttl_cutoff_height = Some(ret_slate.height + b);
|
||||
}
|
||||
|
||||
let context = tx::add_inputs_to_slate(
|
||||
&mut *w,
|
||||
keychain_mask,
|
||||
@@ -459,6 +465,7 @@ where
|
||||
K: Keychain + 'a,
|
||||
{
|
||||
let mut sl = slate.clone();
|
||||
check_ttl(w, &sl)?;
|
||||
let context = w.get_private_context(keychain_mask, sl.id.as_bytes(), 0)?;
|
||||
let parent_key_id = w.parent_key_id();
|
||||
tx::complete_tx(&mut *w, keychain_mask, &mut sl, 0, &context)?;
|
||||
@@ -733,16 +740,46 @@ where
|
||||
|
||||
info.hash = tip.1;
|
||||
|
||||
wallet_lock!(wallet_inst, w);
|
||||
let mut batch = w.batch(keychain_mask)?;
|
||||
batch.save_last_scanned_block(info)?;
|
||||
// init considered complete after first successful update
|
||||
batch.save_init_status(WalletInitStatus::InitComplete)?;
|
||||
batch.commit()?;
|
||||
{
|
||||
wallet_lock!(wallet_inst, w);
|
||||
let mut batch = w.batch(keychain_mask)?;
|
||||
batch.save_last_scanned_block(info)?;
|
||||
// init considered complete after first successful update
|
||||
batch.save_init_status(WalletInitStatus::InitComplete)?;
|
||||
batch.commit()?;
|
||||
}
|
||||
|
||||
// Step 5: Cancel any transactions with an expired TTL
|
||||
for tx in txs {
|
||||
if let Some(e) = tx.ttl_cutoff_height {
|
||||
if e >= tip.0 {
|
||||
wallet_lock!(wallet_inst, w);
|
||||
let parent_key_id = w.parent_key_id();
|
||||
tx::cancel_tx(&mut **w, keychain_mask, &parent_key_id, Some(tx.id), None)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Check TTL
|
||||
pub fn check_ttl<'a, T: ?Sized, C, K>(w: &mut T, slate: &Slate) -> Result<(), Error>
|
||||
where
|
||||
T: WalletBackend<'a, C, K>,
|
||||
C: NodeClient + 'a,
|
||||
K: Keychain + 'a,
|
||||
{
|
||||
// Refuse if TTL is expired
|
||||
let last_confirmed_height = w.last_confirmed_height()?;
|
||||
if let Some(e) = slate.ttl_cutoff_height {
|
||||
if last_confirmed_height >= e {
|
||||
return Err(ErrorKind::TransactionExpired)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Attempt to update outputs in wallet, return whether it was successful
|
||||
fn update_outputs<'a, L, C, K>(
|
||||
wallet_inst: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
|
||||
|
||||
@@ -89,6 +89,9 @@ pub struct InitTxArgs {
|
||||
/// down to the minimum slate version compatible with the current. If `None` the slate
|
||||
/// is generated with the latest version.
|
||||
pub target_slate_version: Option<u16>,
|
||||
/// Number of blocks from current after which TX should be ignored
|
||||
#[serde(with = "secp_ser::opt_string_or_u64")]
|
||||
pub ttl_blocks: Option<u64>,
|
||||
/// If set, require a payment proof for the particular recipient
|
||||
#[serde(with = "dalek_ser::option_dalek_pubkey_serde")]
|
||||
pub payment_proof_recipient_address: Option<DalekPublicKey>,
|
||||
@@ -129,6 +132,7 @@ impl Default for InitTxArgs {
|
||||
selection_strategy_is_use_all: true,
|
||||
message: None,
|
||||
target_slate_version: None,
|
||||
ttl_blocks: None,
|
||||
estimate_only: Some(false),
|
||||
payment_proof_recipient_address: None,
|
||||
send_args: None,
|
||||
|
||||
Reference in New Issue
Block a user