Skip to content

Commit 75363a9

Browse files
author
Yeastplume
authored
Invoice owner API update (#701)
1 parent f28b8c6 commit 75363a9

File tree

4 files changed

+108
-67
lines changed

4 files changed

+108
-67
lines changed

controller/tests/invoice.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,45 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
207207
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), mask1, 3, false);
208208
//bh += 3;
209209

210+
// As above, but use owner API to finalize
211+
let mut slate = Slate::blank(2, true);
212+
213+
wallet::controller::owner_single_use(Some(wallet2.clone()), mask2, None, |api, m| {
214+
// Wallet 2 inititates an invoice transaction, requesting payment
215+
let args = IssueInvoiceTxArgs {
216+
amount: reward * 2,
217+
..Default::default()
218+
};
219+
slate = api.issue_invoice_tx(m, args)?;
220+
Ok(())
221+
})?;
222+
assert_eq!(slate.state, SlateState::Invoice1);
223+
224+
wallet::controller::owner_single_use(Some(wallet1.clone()), mask1, None, |api, m| {
225+
// Wallet 1 receives the invoice transaction
226+
let args = InitTxArgs {
227+
src_acct_name: None,
228+
amount: slate.amount,
229+
minimum_confirmations: 2,
230+
max_outputs: 500,
231+
num_change_outputs: 1,
232+
selection_strategy_is_use_all: true,
233+
..Default::default()
234+
};
235+
slate = api.process_invoice_tx(m, &slate, args)?;
236+
api.tx_lock_outputs(m, &slate)?;
237+
Ok(())
238+
})?;
239+
assert_eq!(slate.state, SlateState::Invoice2);
240+
241+
// wallet 2 finalizes via owner API
242+
wallet::controller::owner_single_use(Some(wallet2.clone()), mask2, None, |api, m| {
243+
// Wallet 2 receives the invoice transaction
244+
slate = api.finalize_tx(m, &slate)?;
245+
Ok(())
246+
})?;
247+
assert_eq!(slate.state, SlateState::Invoice3);
248+
210249
// let logging finish
211250
stopper.store(false, Ordering::Relaxed);
212251
thread::sleep(Duration::from_millis(200));

libwallet/src/api_impl/foreign.rs

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
//! Generic implementation of owner API functions
1616
use strum::IntoEnumIterator;
1717

18-
use crate::api_impl::owner::finalize_tx as owner_finalize;
1918
use crate::api_impl::owner::{check_ttl, post_tx};
2019
use crate::grin_core::core::FeeFields;
2120
use crate::grin_keychain::Keychain;
@@ -27,6 +26,8 @@ use crate::{
2726
WalletBackend,
2827
};
2928

29+
use super::owner::tx_lock_outputs;
30+
3031
const FOREIGN_API_VERSION: u16 = 2;
3132

3233
/// Return the version info
@@ -144,10 +145,9 @@ where
144145
K: Keychain + 'a,
145146
{
146147
let mut sl = slate.clone();
147-
let context = w.get_private_context(keychain_mask, sl.id.as_bytes())?;
148+
let mut context = w.get_private_context(keychain_mask, sl.id.as_bytes())?;
149+
check_ttl(w, &sl)?;
148150
if sl.state == SlateState::Invoice2 {
149-
check_ttl(w, &sl)?;
150-
151151
// Add our contribution to the offset
152152
sl.adjust_offset(&w.keychain(keychain_mask)?, &context)?;
153153

@@ -165,8 +165,66 @@ where
165165
}
166166
sl.state = SlateState::Invoice3;
167167
sl.amount = 0;
168+
} else if sl.state == SlateState::Standard2 {
169+
let keychain = w.keychain(keychain_mask)?;
170+
let parent_key_id = w.parent_key_id();
171+
172+
if let Some(args) = context.late_lock_args.take() {
173+
// Transaction was late locked, select inputs+change now
174+
// and insert into original context
175+
176+
let current_height = w.w2n_client().get_chain_tip()?.0;
177+
let mut temp_sl =
178+
tx::new_tx_slate(&mut *w, context.amount, false, 2, false, args.ttl_blocks)?;
179+
let temp_context = selection::build_send_tx(
180+
w,
181+
&keychain,
182+
keychain_mask,
183+
&mut temp_sl,
184+
current_height,
185+
args.minimum_confirmations,
186+
args.max_outputs as usize,
187+
args.num_change_outputs as usize,
188+
args.selection_strategy_is_use_all,
189+
Some(context.fee.map(|f| f.fee()).unwrap_or(0)),
190+
parent_key_id.clone(),
191+
false,
192+
true,
193+
false,
194+
)?;
195+
196+
// Add inputs and outputs to original context
197+
context.input_ids = temp_context.input_ids;
198+
context.output_ids = temp_context.output_ids;
199+
200+
// Store the updated context
201+
{
202+
let mut batch = w.batch(keychain_mask)?;
203+
batch.save_private_context(sl.id.as_bytes(), &context)?;
204+
batch.commit()?;
205+
}
206+
207+
// Now do the actual locking
208+
tx_lock_outputs(w, keychain_mask, &sl)?;
209+
}
210+
211+
// Add our contribution to the offset
212+
sl.adjust_offset(&keychain, &context)?;
213+
214+
selection::repopulate_tx(&mut *w, keychain_mask, &mut sl, &context, true)?;
215+
216+
tx::complete_tx(&mut *w, keychain_mask, &mut sl, &context)?;
217+
tx::verify_slate_payment_proof(&mut *w, keychain_mask, &parent_key_id, &context, &sl)?;
218+
tx::update_stored_tx(&mut *w, keychain_mask, &context, &sl, false)?;
219+
{
220+
let mut batch = w.batch(keychain_mask)?;
221+
batch.delete_private_context(sl.id.as_bytes())?;
222+
batch.commit()?;
223+
}
224+
sl.state = SlateState::Standard3;
225+
sl.amount = 0;
168226
} else {
169-
sl = owner_finalize(w, keychain_mask, slate)?;
227+
return Err(Error::SlateState);
170228
}
171229
if post_automatically {
172230
post_tx(w.w2n_client(), sl.tx_or_err()?, true)?;

libwallet/src/api_impl/owner.rs

Lines changed: 2 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
1717
use uuid::Uuid;
1818

19+
use crate::api_impl::foreign::finalize_tx as foreign_finalize;
1920
use crate::grin_core::core::hash::Hashed;
2021
use crate::grin_core::core::{Output, OutputFeatures, Transaction};
2122
use crate::grin_core::libtx::proof;
@@ -807,68 +808,7 @@ where
807808
C: NodeClient + 'a,
808809
K: Keychain + 'a,
809810
{
810-
let mut sl = slate.clone();
811-
check_ttl(w, &sl)?;
812-
let mut context = w.get_private_context(keychain_mask, sl.id.as_bytes())?;
813-
let keychain = w.keychain(keychain_mask)?;
814-
let parent_key_id = w.parent_key_id();
815-
816-
if let Some(args) = context.late_lock_args.take() {
817-
// Transaction was late locked, select inputs+change now
818-
// and insert into original context
819-
820-
let current_height = w.w2n_client().get_chain_tip()?.0;
821-
let mut temp_sl =
822-
tx::new_tx_slate(&mut *w, context.amount, false, 2, false, args.ttl_blocks)?;
823-
let temp_context = selection::build_send_tx(
824-
w,
825-
&keychain,
826-
keychain_mask,
827-
&mut temp_sl,
828-
current_height,
829-
args.minimum_confirmations,
830-
args.max_outputs as usize,
831-
args.num_change_outputs as usize,
832-
args.selection_strategy_is_use_all,
833-
Some(context.fee.map(|f| f.fee()).unwrap_or(0)),
834-
parent_key_id.clone(),
835-
false,
836-
true,
837-
false,
838-
)?;
839-
840-
// Add inputs and outputs to original context
841-
context.input_ids = temp_context.input_ids;
842-
context.output_ids = temp_context.output_ids;
843-
844-
// Store the updated context
845-
{
846-
let mut batch = w.batch(keychain_mask)?;
847-
batch.save_private_context(sl.id.as_bytes(), &context)?;
848-
batch.commit()?;
849-
}
850-
851-
// Now do the actual locking
852-
tx_lock_outputs(w, keychain_mask, &sl)?;
853-
}
854-
855-
// Add our contribution to the offset
856-
sl.adjust_offset(&keychain, &context)?;
857-
858-
selection::repopulate_tx(&mut *w, keychain_mask, &mut sl, &context, true)?;
859-
860-
tx::complete_tx(&mut *w, keychain_mask, &mut sl, &context)?;
861-
tx::verify_slate_payment_proof(&mut *w, keychain_mask, &parent_key_id, &context, &sl)?;
862-
tx::update_stored_tx(&mut *w, keychain_mask, &context, &sl, false)?;
863-
{
864-
let mut batch = w.batch(keychain_mask)?;
865-
batch.delete_private_context(sl.id.as_bytes())?;
866-
batch.commit()?;
867-
}
868-
sl.state = SlateState::Standard3;
869-
sl.amount = 0;
870-
871-
Ok(sl)
811+
foreign_finalize(w, keychain_mask, slate, false)
872812
}
873813

874814
/// cancel tx

libwallet/src/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ pub enum Error {
189189
#[error("Can't Deserialize slate")]
190190
SlateDeser,
191191

192+
/// Invalid slate state
193+
#[error("Invalid slate state")]
194+
SlateState,
195+
192196
/// Can't serialize slate pack
193197
#[error("Can't Serialize slatepack")]
194198
SlatepackSer,

0 commit comments

Comments
 (0)