Add participant ID as part of key to stored private transaction context data (#117)

* add participant_id to saved tranasction context data

* rustfmt?

* change participant id for command line pay command
This commit is contained in:
Yeastplume 2019-05-23 16:27:57 +01:00 committed by GitHub
parent db818ac8b7
commit 85b55f5ca7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 144 additions and 59 deletions

View file

@ -482,7 +482,7 @@ where
/// // Send slate somehow
/// // ...
/// // Lock our outputs if we're happy the slate was (or is being) sent
/// api_owner.tx_lock_outputs(&slate);
/// api_owner.tx_lock_outputs(&slate, 0);
/// }
/// ```
@ -513,7 +513,7 @@ where
))?;
}
}
self.tx_lock_outputs(&slate)?;
self.tx_lock_outputs(&slate, 0)?;
let slate = match sa.finalize {
true => self.finalize_tx(&slate)?,
false => slate,
@ -645,6 +645,8 @@ where
///
/// # Arguments
/// * `slate` - The transaction [`Slate`](../grin_wallet_libwallet/slate/struct.Slate.html). All
/// * `participant_id` - The participant id, generally 0 for the party putting in funds, 1 for the
/// party receiving.
/// elements in the `input` vector of the `tx` field that are found in the wallet's currently
/// active account will be set to status `Locked`
///
@ -676,14 +678,14 @@ where
/// // Send slate somehow
/// // ...
/// // Lock our outputs if we're happy the slate was (or is being) sent
/// api_owner.tx_lock_outputs(&slate);
/// api_owner.tx_lock_outputs(&slate, 0);
/// }
/// ```
pub fn tx_lock_outputs(&self, slate: &Slate) -> Result<(), Error> {
pub fn tx_lock_outputs(&self, slate: &Slate, participant_id: usize) -> Result<(), Error> {
let mut w = self.wallet.lock();
w.open_with_credentials()?;
let res = owner::tx_lock_outputs(&mut *w, slate);
let res = owner::tx_lock_outputs(&mut *w, slate, participant_id);
w.close()?;
res
}
@ -734,7 +736,7 @@ where
/// // Send slate somehow
/// // ...
/// // Lock our outputs if we're happy the slate was (or is being) sent
/// let res = api_owner.tx_lock_outputs(&slate);
/// let res = api_owner.tx_lock_outputs(&slate, 0);
/// //
/// // Retrieve slate back from recipient
/// //
@ -791,7 +793,7 @@ where
/// // Send slate somehow
/// // ...
/// // Lock our outputs if we're happy the slate was (or is being) sent
/// let res = api_owner.tx_lock_outputs(&slate);
/// let res = api_owner.tx_lock_outputs(&slate, 0);
/// //
/// // Retrieve slate back from recipient
/// //
@ -852,7 +854,7 @@ where
/// // Send slate somehow
/// // ...
/// // Lock our outputs if we're happy the slate was (or is being) sent
/// let res = api_owner.tx_lock_outputs(&slate);
/// let res = api_owner.tx_lock_outputs(&slate, 0);
/// //
/// // We didn't get the slate back, or something else went wrong
/// //
@ -945,7 +947,7 @@ where
/// // Send slate somehow
/// // ...
/// // Lock our outputs if we're happy the slate was (or is being) sent
/// let res = api_owner.tx_lock_outputs(&slate);
/// let res = api_owner.tx_lock_outputs(&slate, 0);
/// //
/// // Retrieve slate back from recipient
/// //

View file

@ -690,7 +690,8 @@ pub trait OwnerRpc {
"orig_version": 2,
"version": 2
}
}
},
0
]
}
# "#
@ -708,7 +709,7 @@ pub trait OwnerRpc {
```
*/
fn tx_lock_outputs(&self, slate: Slate) -> Result<(), ErrorKind>;
fn tx_lock_outputs(&self, slate: Slate, participant_id: usize) -> Result<(), ErrorKind>;
/**
Networked version of [Owner::finalize_tx](struct.Owner.html#method.finalize_tx).
@ -1293,8 +1294,8 @@ where
Owner::finalize_tx(self, &mut slate).map_err(|e| e.kind())
}
fn tx_lock_outputs(&self, mut slate: Slate) -> Result<(), ErrorKind> {
Owner::tx_lock_outputs(self, &mut slate).map_err(|e| e.kind())
fn tx_lock_outputs(&self, mut slate: Slate, participant_id: usize) -> Result<(), ErrorKind> {
Owner::tx_lock_outputs(self, &mut slate, participant_id).map_err(|e| e.kind())
}
fn cancel_tx(&self, tx_id: Option<u32>, tx_slate_id: Option<Uuid>) -> Result<(), ErrorKind> {
@ -1420,7 +1421,7 @@ pub fn run_doctest_owner(
// Spit out slate for input to finalize_tx
println!("{}", serde_json::to_string_pretty(&slate).unwrap());
if lock_tx {
api_impl::owner::tx_lock_outputs(&mut *w, &slate).unwrap();
api_impl::owner::tx_lock_outputs(&mut *w, &slate, 0).unwrap();
}
if finalize_tx {
api_impl::owner::finalize_tx(&mut *w, &slate).unwrap();

View file

@ -300,7 +300,7 @@ pub fn send(
};
if adapter.supports_sync() {
slate = adapter.send_tx_sync(&args.dest, &slate)?;
api.tx_lock_outputs(&slate)?;
api.tx_lock_outputs(&slate, 0)?;
if args.method == "self" {
controller::foreign_single_use(wallet, |api| {
slate = api.receive_tx(&slate, Some(&args.dest), None)?;
@ -314,7 +314,7 @@ pub fn send(
slate = api.finalize_tx(&slate)?;
} else {
adapter.send_tx_async(&args.dest, &slate)?;
api.tx_lock_outputs(&slate)?;
api.tx_lock_outputs(&slate, 0)?;
}
if adapter.supports_sync() {
let result = api.post_tx(&slate.tx, args.fluff);
@ -536,7 +536,7 @@ pub fn process_invoice(
};
if adapter.supports_sync() {
slate = adapter.send_tx_sync(&args.dest, &slate)?;
api.tx_lock_outputs(&slate)?;
api.tx_lock_outputs(&slate, 0)?;
if args.method == "self" {
controller::foreign_single_use(wallet, |api| {
slate = api.finalize_invoice_tx(&slate)?;
@ -545,7 +545,7 @@ pub fn process_invoice(
}
} else {
adapter.send_tx_async(&args.dest, &slate)?;
api.tx_lock_outputs(&slate)?;
api.tx_lock_outputs(&slate, 0)?;
}
}
Ok(())

View file

@ -400,7 +400,7 @@ where
))?;
}
}
api.tx_lock_outputs(&slate)?;
api.tx_lock_outputs(&slate, 0)?;
if args.method != "file" {
slate = api.finalize_tx(&slate)?;
}

View file

@ -191,7 +191,7 @@ fn accounts_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
};
let mut slate = api.init_send_tx(args)?;
slate = client1.send_tx_slate_direct("wallet2", &slate)?;
api.tx_lock_outputs(&slate)?;
api.tx_lock_outputs(&slate, 0)?;
slate = api.finalize_tx(&slate)?;
api.post_tx(&slate.tx, false)?;
Ok(())

View file

@ -192,7 +192,7 @@ fn check_repair_impl(test_dir: &str) -> Result<(), libwallet::Error> {
let file_adapter = FileWalletCommAdapter::new();
let send_file = format!("{}/part_tx_1.tx", test_dir);
file_adapter.send_tx_async(&send_file, &mut slate)?;
api.tx_lock_outputs(&slate)?;
api.tx_lock_outputs(&slate, 0)?;
Ok(())
})?;

View file

@ -121,7 +121,7 @@ fn file_exchange_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
// output tx file
let file_adapter = FileWalletCommAdapter::new();
file_adapter.send_tx_async(&send_file, &mut slate)?;
api.tx_lock_outputs(&slate)?;
api.tx_lock_outputs(&slate, 0)?;
Ok(())
})?;

View file

@ -124,7 +124,7 @@ fn invoice_tx_impl(test_dir: &str) -> Result<(), libwallet::Error> {
..Default::default()
};
slate = api.process_invoice_tx(&slate, args)?;
api.tx_lock_outputs(&slate)?;
api.tx_lock_outputs(&slate, 0)?;
Ok(())
})?;
@ -160,9 +160,6 @@ fn invoice_tx_impl(test_dir: &str) -> Result<(), libwallet::Error> {
Ok(())
})?;
// let logging finish
thread::sleep(Duration::from_millis(200));
// Check transaction log for wallet 1, ensure only 1 entry
// exists
wallet::controller::owner_single_use(wallet1.clone(), |api| {
@ -176,7 +173,44 @@ fn invoice_tx_impl(test_dir: &str) -> Result<(), libwallet::Error> {
);
Ok(())
})?;
// Test self-sending
wallet::controller::owner_single_use(wallet1.clone(), |api| {
// Wallet 1 inititates an invoice transaction, requesting payment
let args = IssueInvoiceTxArgs {
amount: reward * 2,
..Default::default()
};
slate = api.issue_invoice_tx(args)?;
// Wallet 1 receives the invoice transaction
let args = InitTxArgs {
src_acct_name: None,
amount: slate.amount,
minimum_confirmations: 2,
max_outputs: 500,
num_change_outputs: 1,
selection_strategy_is_use_all: true,
..Default::default()
};
slate = api.process_invoice_tx(&slate, args)?;
api.tx_lock_outputs(&slate, 0)?;
Ok(())
})?;
// wallet 1 finalizes and posts
wallet::controller::foreign_single_use(wallet1.clone(), |api| {
// Wallet 2 receives the invoice transaction
slate = api.finalize_invoice_tx(&slate)?;
Ok(())
})?;
let _ = test_framework::award_blocks_to_wallet(&chain, wallet1.clone(), 3, false);
//bh += 3;
// let logging finish
thread::sleep(Duration::from_millis(200));
}
teardown(test_dir);
Ok(())
}

View file

@ -116,7 +116,7 @@ fn file_repost_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
// output tx file
let file_adapter = FileWalletCommAdapter::new();
file_adapter.send_tx_async(&send_file, &mut slate)?;
api.tx_lock_outputs(&slate)?;
api.tx_lock_outputs(&slate, 0)?;
Ok(())
})?;
@ -211,7 +211,7 @@ fn file_repost_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
};
let slate_i = sender_api.init_send_tx(args)?;
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate)?;
sender_api.tx_lock_outputs(&slate, 0)?;
slate = sender_api.finalize_tx(&mut slate)?;
Ok(())
})?;

View file

@ -247,7 +247,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> {
};
let slate_i = sender_api.init_send_tx(args)?;
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate)?;
sender_api.tx_lock_outputs(&slate, 0)?;
slate = sender_api.finalize_tx(&slate)?;
sender_api.post_tx(&slate.tx, false)?;
Ok(())
@ -270,7 +270,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> {
};
let slate_i = sender_api.init_send_tx(args)?;
slate = client1.send_tx_slate_direct("wallet3", &slate_i)?;
sender_api.tx_lock_outputs(&slate)?;
sender_api.tx_lock_outputs(&slate, 0)?;
slate = sender_api.finalize_tx(&slate)?;
sender_api.post_tx(&slate.tx, false)?;
Ok(())
@ -293,7 +293,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> {
};
let slate_i = sender_api.init_send_tx(args)?;
slate = client3.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate)?;
sender_api.tx_lock_outputs(&slate, 0)?;
slate = sender_api.finalize_tx(&slate)?;
sender_api.post_tx(&slate.tx, false)?;
Ok(())
@ -322,7 +322,7 @@ fn setup_restore(test_dir: &str) -> Result<(), libwallet::Error> {
};
let slate_i = sender_api.init_send_tx(args)?;
slate = client3.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate)?;
sender_api.tx_lock_outputs(&slate, 0)?;
slate = sender_api.finalize_tx(&slate)?;
sender_api.post_tx(&slate.tx, false)?;
Ok(())

View file

@ -97,7 +97,7 @@ fn self_send_test_impl(test_dir: &str) -> Result<(), libwallet::Error> {
..Default::default()
};
let mut slate = api.init_send_tx(args)?;
api.tx_lock_outputs(&slate)?;
api.tx_lock_outputs(&slate, 0)?;
// Send directly to self
wallet::controller::foreign_single_use(wallet1.clone(), |api| {
slate = api.receive_tx(&slate, Some("listener"), None)?;

View file

@ -115,7 +115,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> {
assert_eq!(0, slate.lock_height);
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate)?;
sender_api.tx_lock_outputs(&slate, 0)?;
slate = sender_api.finalize_tx(&slate)?;
// Check we have a single kernel and that it is a Plain kernel (no lock_height).
@ -297,7 +297,7 @@ fn basic_transaction_api(test_dir: &str) -> Result<(), libwallet::Error> {
};
let slate_i = sender_api.init_send_tx(args)?;
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate)?;
sender_api.tx_lock_outputs(&slate, 0)?;
slate = sender_api.finalize_tx(&slate)?;
Ok(())
})?;
@ -397,7 +397,7 @@ fn tx_rollback(test_dir: &str) -> Result<(), libwallet::Error> {
let slate_i = sender_api.init_send_tx(args)?;
slate = client1.send_tx_slate_direct("wallet2", &slate_i)?;
sender_api.tx_lock_outputs(&slate)?;
sender_api.tx_lock_outputs(&slate, 0)?;
slate = sender_api.finalize_tx(&slate)?;
Ok(())
})?;

View file

@ -250,8 +250,16 @@ where
Box::new(self.db.iter(&[TX_LOG_ENTRY_PREFIX]).unwrap().map(|o| o.1))
}
fn get_private_context(&mut self, slate_id: &[u8]) -> Result<Context, Error> {
let ctx_key = to_key(PRIVATE_TX_CONTEXT_PREFIX, &mut slate_id.to_vec());
fn get_private_context(
&mut self,
slate_id: &[u8],
participant_id: usize,
) -> Result<Context, Error> {
let ctx_key = to_key_u64(
PRIVATE_TX_CONTEXT_PREFIX,
&mut slate_id.to_vec(),
participant_id as u64,
);
let (blind_xor_key, nonce_xor_key) = private_ctx_xor_keys(self.keychain(), slate_id)?;
let mut ctx: Context = option_to_not_found(
@ -538,8 +546,17 @@ 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());
fn save_private_context(
&mut self,
slate_id: &[u8],
participant_id: usize,
ctx: &Context,
) -> Result<(), Error> {
let ctx_key = to_key_u64(
PRIVATE_TX_CONTEXT_PREFIX,
&mut slate_id.to_vec(),
participant_id as u64,
);
let (blind_xor_key, nonce_xor_key) = private_ctx_xor_keys(self.keychain(), slate_id)?;
let mut s_ctx = ctx.clone();
@ -556,8 +573,16 @@ where
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());
fn delete_private_context(
&mut self,
slate_id: &[u8],
participant_id: usize,
) -> Result<(), Error> {
let ctx_key = to_key_u64(
PRIVATE_TX_CONTEXT_PREFIX,
&mut slate_id.to_vec(),
participant_id as u64,
);
self.db
.borrow()
.as_ref()

View file

@ -207,7 +207,7 @@ where
};
let slate_i = owner::init_send_tx(&mut *w, args, test_mode)?;
let slate = client.send_tx_slate_direct(dest, &slate_i)?;
owner::tx_lock_outputs(&mut *w, &slate)?;
owner::tx_lock_outputs(&mut *w, &slate, 0)?;
let slate = owner::finalize_tx(&mut *w, &slate)?;
w.close()?;
slate

View file

@ -118,13 +118,13 @@ where
K: Keychain,
{
let mut sl = slate.clone();
let context = w.get_private_context(sl.id.as_bytes())?;
let context = w.get_private_context(sl.id.as_bytes(), 1)?;
tx::complete_tx(&mut *w, &mut sl, 1, &context)?;
tx::update_stored_tx(&mut *w, &mut sl, true)?;
tx::update_message(&mut *w, &mut sl)?;
{
let mut batch = w.batch()?;
batch.delete_private_context(sl.id.as_bytes())?;
batch.delete_private_context(sl.id.as_bytes(), 1)?;
batch.commit()?;
}
Ok(sl)

View file

@ -201,7 +201,7 @@ where
// recieve the transaction back
{
let mut batch = w.batch()?;
batch.save_private_context(slate.id.as_bytes(), &context)?;
batch.save_private_context(slate.id.as_bytes(), 0, &context)?;
batch.commit()?;
}
if let Some(v) = args.target_slate_version {
@ -255,7 +255,7 @@ where
// recieve the transaction back
{
let mut batch = w.batch()?;
batch.save_private_context(slate.id.as_bytes(), &context)?;
batch.save_private_context(slate.id.as_bytes(), 1, &context)?;
batch.commit()?;
}
@ -329,7 +329,7 @@ where
// recieve the transaction back
{
let mut batch = w.batch()?;
batch.save_private_context(slate.id.as_bytes(), &context)?;
batch.save_private_context(slate.id.as_bytes(), 0, &context)?;
batch.commit()?;
}
@ -337,13 +337,17 @@ where
}
/// Lock sender outputs
pub fn tx_lock_outputs<T: ?Sized, C, K>(w: &mut T, slate: &Slate) -> Result<(), Error>
pub fn tx_lock_outputs<T: ?Sized, C, K>(
w: &mut T,
slate: &Slate,
participant_id: usize,
) -> Result<(), Error>
where
T: WalletBackend<C, K>,
C: NodeClient,
K: Keychain,
{
let context = w.get_private_context(slate.id.as_bytes())?;
let context = w.get_private_context(slate.id.as_bytes(), participant_id)?;
selection::lock_tx_context(&mut *w, slate, &context)
}
@ -355,13 +359,13 @@ where
K: Keychain,
{
let mut sl = slate.clone();
let context = w.get_private_context(sl.id.as_bytes())?;
let context = w.get_private_context(sl.id.as_bytes(), 0)?;
tx::complete_tx(&mut *w, &mut sl, 0, &context)?;
tx::update_stored_tx(&mut *w, &mut sl, false)?;
tx::update_message(&mut *w, &mut sl)?;
{
let mut batch = w.batch()?;
batch.delete_private_context(sl.id.as_bytes())?;
batch.delete_private_context(sl.id.as_bytes(), 0)?;
batch.commit()?;
}
Ok(sl)

View file

@ -66,6 +66,7 @@ where
blinding.secret_key(&keychain.secp()).unwrap(),
&parent_key_id,
use_test_nonce,
0,
);
context.fee = fee;
@ -199,6 +200,7 @@ where
.unwrap(),
&parent_key_id,
use_test_rng,
1,
);
context.add_output(&key_id, &None, amount);

View file

@ -95,7 +95,11 @@ where
fn get_tx_log_entry(&self, uuid: &Uuid) -> Result<Option<TxLogEntry>, Error>;
/// Retrieves the private context associated with a given slate id
fn get_private_context(&mut self, slate_id: &[u8]) -> Result<Context, Error>;
fn get_private_context(
&mut self,
slate_id: &[u8],
participant_id: usize,
) -> Result<Context, Error>;
/// Iterate over all output data stored by the backend
fn tx_log_iter<'a>(&'a self) -> Box<dyn Iterator<Item = TxLogEntry> + 'a>;
@ -181,10 +185,19 @@ where
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>;
fn save_private_context(
&mut self,
slate_id: &[u8],
participant_id: usize,
ctx: &Context,
) -> Result<(), Error>;
/// Delete the private context associated with the slate id
fn delete_private_context(&mut self, slate_id: &[u8]) -> Result<(), Error>;
fn delete_private_context(
&mut self,
slate_id: &[u8],
participant_id: usize,
) -> Result<(), Error>;
/// Write the wallet data to backend file
fn commit(&self) -> Result<(), Error>;
@ -391,6 +404,8 @@ pub struct Context {
pub input_ids: Vec<(Identifier, Option<u64>, u64)>,
/// store the calculated fee
pub fee: u64,
/// keep track of the participant id
pub participant_id: usize,
}
impl Context {
@ -400,6 +415,7 @@ impl Context {
sec_key: SecretKey,
parent_key_id: &Identifier,
use_test_rng: bool,
participant_id: usize,
) -> Context {
let sec_nonce = match use_test_rng {
false => aggsig::create_secnonce(secp).unwrap(),
@ -412,6 +428,7 @@ impl Context {
input_ids: vec![],
output_ids: vec![],
fee: 0,
participant_id: participant_id,
}
}
}

View file

@ -71,7 +71,7 @@ fn aggsig_sender_receiver_interaction() {
let blind = blinding_factor.secret_key(&keychain.secp()).unwrap();
s_cx = Context::new(&keychain.secp(), blind, &parent, false);
s_cx = Context::new(&keychain.secp(), blind, &parent, false, 0);
s_cx.get_public_keys(&keychain.secp())
};
@ -85,7 +85,7 @@ fn aggsig_sender_receiver_interaction() {
// let blind = blind_sum.secret_key(&keychain.secp())?;
let blind = keychain.derive_key(0, &key_id).unwrap();
rx_cx = Context::new(&keychain.secp(), blind, &parent, false);
rx_cx = Context::new(&keychain.secp(), blind, &parent, false, 1);
let (pub_excess, pub_nonce) = rx_cx.get_public_keys(&keychain.secp());
rx_cx.add_output(&key_id, &None, 0);
@ -289,7 +289,7 @@ fn aggsig_sender_receiver_interaction_offset() {
let blind = blinding_factor.secret_key(&keychain.secp()).unwrap();
s_cx = Context::new(&keychain.secp(), blind, &parent, false);
s_cx = Context::new(&keychain.secp(), blind, &parent, false, 0);
s_cx.get_public_keys(&keychain.secp())
};
@ -302,7 +302,7 @@ fn aggsig_sender_receiver_interaction_offset() {
let blind = keychain.derive_key(0, &key_id).unwrap();
rx_cx = Context::new(&keychain.secp(), blind, &parent, false);
rx_cx = Context::new(&keychain.secp(), blind, &parent, false, 1);
let (pub_excess, pub_nonce) = rx_cx.get_public_keys(&keychain.secp());
rx_cx.add_output(&key_id, &None, 0);