Skip to content

Commit

Permalink
Slatepack Workflow (mimblewimble#423)
Browse files Browse the repository at this point in the history
* debugging tor sends

* use fixed yeast version of hyper-socks2

* send command working according to slatepack

* changes to handling proof address

* modifications of recieve command to work with slatepack and to attempt to return to sender via TOR

* finalize command tested

* attempting to add invoice processing

* fixes to tests, propagation of test mode where needed

* modify return values of api functions that can send as sync

* cleanup, testing and post_tx function

* revert changes to API, many test fixes

* deprecate http on the command-line warning
  • Loading branch information
yeastplume authored Jun 3, 2020
1 parent 51e5e6c commit 7fb2db1
Show file tree
Hide file tree
Showing 28 changed files with 1,391 additions and 704 deletions.
175 changes: 87 additions & 88 deletions Cargo.lock

Large diffs are not rendered by default.

96 changes: 77 additions & 19 deletions api/src/foreign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@

//! Foreign API External Definition

use crate::config::TorConfig;
use crate::keychain::Keychain;
use crate::libwallet::api_impl::foreign;
use crate::libwallet::{
BlockFees, CbData, Error, NodeClient, NodeVersionInfo, Slate, VersionInfo, WalletInst,
WalletLCProvider,
};
use crate::try_slatepack_sync_workflow;
use crate::util::secp::key::SecretKey;
use crate::util::Mutex;
use std::sync::Arc;
Expand All @@ -38,8 +40,10 @@ pub enum ForeignCheckMiddlewareFn {
VerifySlateMessages,
/// receive_tx
ReceiveTx,
/// finalize_invoice_tx
/// finalize_invoice_tx (delete HF3)
FinalizeInvoiceTx,
/// finalize_tx
FinalizeTx,
}

/// Main interface into all wallet API functions.
Expand Down Expand Up @@ -70,6 +74,9 @@ where
middleware: Option<ForeignCheckMiddleware>,
/// Stored keychain mask (in case the stored wallet seed is tokenized)
keychain_mask: Option<SecretKey>,
/// Optional TOR configuration, holding address of sender and
/// data directory
tor_config: Mutex<Option<TorConfig>>,
}

impl<'a, L, C, K> Foreign<'a, L, C, K>
Expand Down Expand Up @@ -158,7 +165,7 @@ where
/// // All wallet functions operate on an Arc::Mutex to allow multithreading where needed
/// let mut wallet = Arc::new(Mutex::new(wallet));
///
/// let api_foreign = Foreign::new(wallet.clone(), None, None);
/// let api_foreign = Foreign::new(wallet.clone(), None, None, false);
/// // .. perform wallet operations
///
/// ```
Expand All @@ -167,15 +174,30 @@ where
wallet_inst: Arc<Mutex<Box<dyn WalletInst<'a, L, C, K>>>>,
keychain_mask: Option<SecretKey>,
middleware: Option<ForeignCheckMiddleware>,
doctest_mode: bool,
) -> Self {
Foreign {
wallet_inst,
doctest_mode: false,
doctest_mode,
middleware,
keychain_mask,
tor_config: Mutex::new(None),
}
}

/// Set the TOR configuration for this instance of the ForeignAPI, used during
/// `recieve_tx` when a return address is specified
///
/// # Arguments
/// * `tor_config` - The optional [TorConfig](#) to use
/// # Returns
/// * Nothing

pub fn set_tor_config(&self, tor_config: Option<TorConfig>) {
let mut lock = self.tor_config.lock();
*lock = tor_config;
}

/// Return the version capabilities of the running ForeignApi Node
/// # Arguments
/// None
Expand All @@ -186,7 +208,7 @@ where
/// ```
/// # grin_wallet_api::doctest_helper_setup_doc_env_foreign!(wallet, wallet_config);
///
/// let mut api_foreign = Foreign::new(wallet.clone(), None, None);
/// let mut api_foreign = Foreign::new(wallet.clone(), None, None, false);
///
/// let version_info = api_foreign.check_version();
/// // check and proceed accordingly
Expand Down Expand Up @@ -238,7 +260,7 @@ where
/// ```
/// # grin_wallet_api::doctest_helper_setup_doc_env_foreign!(wallet, wallet_config);
///
/// let mut api_foreign = Foreign::new(wallet.clone(), None, None);
/// let mut api_foreign = Foreign::new(wallet.clone(), None, None, false);
///
/// let block_fees = BlockFees {
/// fees: 800000,
Expand Down Expand Up @@ -294,6 +316,9 @@ where
/// excess value).
/// * `dest_acct_name` - The name of the account into which the slate should be received. If
/// `None`, the default account is used.
/// * `r_addr` - If included, attempt to send the slate back to the sender using the slatepack sync
/// send (TOR). If providing this argument, check the `state` field of the slate to see if the
/// sync_send was successful (it should be S3 if the synced send sent successfully).
///
/// # Returns
/// * a result containing:
Expand All @@ -310,20 +335,25 @@ where
/// ```
/// # grin_wallet_api::doctest_helper_setup_doc_env_foreign!(wallet, wallet_config);
///
/// let mut api_foreign = Foreign::new(wallet.clone(), None, None);
/// let mut api_foreign = Foreign::new(wallet.clone(), None, None, false);
/// # let slate = Slate::blank(2, false);
///
/// // . . .
/// // Obtain a sent slate somehow
/// let result = api_foreign.receive_tx(&slate, None);
/// let result = api_foreign.receive_tx(&slate, None, None);
///
/// if let Ok(slate) = result {
/// // Send back to recipient somehow
/// // ...
/// }
/// ```

pub fn receive_tx(&self, slate: &Slate, dest_acct_name: Option<&str>) -> Result<Slate, Error> {
pub fn receive_tx(
&self,
slate: &Slate,
dest_acct_name: Option<&str>,
r_addr: Option<String>,
) -> Result<Slate, Error> {
let mut w_lock = self.wallet_inst.lock();
let w = w_lock.lc_provider()?.wallet_inst()?;
if let Some(m) = self.middleware.as_ref() {
Expand All @@ -333,31 +363,50 @@ where
Some(slate),
)?;
}
foreign::receive_tx(
let ret_slate = foreign::receive_tx(
&mut **w,
(&self.keychain_mask).as_ref(),
slate,
dest_acct_name,
self.doctest_mode,
)
)?;
match r_addr {
Some(a) => {
let tor_config_lock = self.tor_config.lock();
let res = try_slatepack_sync_workflow(
&ret_slate,
&a,
tor_config_lock.clone(),
None,
true,
self.doctest_mode,
);
match res {
Ok(s) => return Ok(s.unwrap()),
Err(_) => return Ok(ret_slate),
}
}
None => Ok(ret_slate),
}
}

/// Finalizes an invoice transaction initiated by this wallet's Owner api.
/// Finalizes a (standard or invoice) transaction initiated by this wallet's Owner api.
/// This step assumes the paying party has completed round 1 and 2 of slate
/// creation, and added their partial signatures. The invoicer will verify
/// creation, and added their partial signatures. This wallet will verify
/// and add their partial sig, then create the finalized transaction,
/// ready to post to a node.
///
/// Note that this function DOES NOT POST the transaction to a node
/// for validation. This is done in separately via the
/// This function posts to the node if the `post_automatically`
/// argument is sent to true. Posting can be done in separately via the
/// [`post_tx`](struct.Owner.html#method.post_tx) function.
///
/// This function also stores the final transaction in the user's wallet files for retrieval
/// via the [`get_stored_tx`](struct.Owner.html#method.get_stored_tx) function.
///
/// # Arguments
/// * `slate` - The transaction [`Slate`](../grin_wallet_libwallet/slate/struct.Slate.html). The
/// payer should have filled in round 1 and 2.
/// * `post_automatically` - If true, post the finalized transaction to the configured listening
/// node
///
/// # Returns
/// * Ok([`slate`](../grin_wallet_libwallet/slate/struct.Slate.html)) if successful,
Expand All @@ -370,7 +419,7 @@ where
/// # grin_wallet_api::doctest_helper_setup_doc_env_foreign!(wallet, wallet_config);
///
/// let mut api_owner = Owner::new(wallet.clone(), None);
/// let mut api_foreign = Foreign::new(wallet.clone(), None, None);
/// let mut api_foreign = Foreign::new(wallet.clone(), None, None, false);
///
/// // . . .
/// // Issue the invoice tx via the owner API
Expand All @@ -385,11 +434,11 @@ where
/// // ...
/// # let slate = Slate::blank(2, true);
///
/// let slate = api_foreign.finalize_invoice_tx(&slate);
/// let slate = api_foreign.finalize_tx(&slate, true);
/// // if okay, then post via the owner API
/// ```

pub fn finalize_invoice_tx(&self, slate: &Slate) -> Result<Slate, Error> {
pub fn finalize_tx(&self, slate: &Slate, post_automatically: bool) -> Result<Slate, Error> {
let mut w_lock = self.wallet_inst.lock();
let w = w_lock.lc_provider()?.wallet_inst()?;
if let Some(m) = self.middleware.as_ref() {
Expand All @@ -399,7 +448,16 @@ where
Some(slate),
)?;
}
foreign::finalize_invoice_tx(&mut **w, (&self.keychain_mask).as_ref(), slate)
let post_automatically = match self.doctest_mode {
true => false,
false => post_automatically,
};
foreign::finalize_tx(
&mut **w,
(&self.keychain_mask).as_ref(),
slate,
post_automatically,
)
}
}

Expand Down
28 changes: 19 additions & 9 deletions api/src/foreign_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,12 @@ pub trait ForeignRpc {
&self,
slate: VersionedSlate,
dest_acct_name: Option<String>,
//TODO: Remove post-HF3
message: Option<String>,
dest: Option<String>,
) -> Result<VersionedSlate, ErrorKind>;

/**
Networked version of [Foreign::finalize_invoice_tx](struct.Foreign.html#method.finalize_invoice_tx).
Networked version of [Foreign::finalize_tx](struct.Foreign.html#method.finalize_tx).
# Json rpc example
Expand All @@ -198,7 +197,7 @@ pub trait ForeignRpc {
# r#"
{
"jsonrpc": "2.0",
"method": "finalize_invoice_tx",
"method": "finalize_tx",
"id": 1,
"params": [{
"ver": "4:2",
Expand Down Expand Up @@ -279,6 +278,9 @@ pub trait ForeignRpc {
# ,false, 5, false, true);
```
*/
fn finalize_tx(&self, slate: VersionedSlate) -> Result<VersionedSlate, ErrorKind>;

/// For backwards-compatibility. Remove HF3
fn finalize_invoice_tx(&self, slate: VersionedSlate) -> Result<VersionedSlate, ErrorKind>;
}

Expand All @@ -301,24 +303,32 @@ where
&self,
in_slate: VersionedSlate,
dest_acct_name: Option<String>,
//TODO: Remove post HF3
_message: Option<String>,
dest: Option<String>,
) -> Result<VersionedSlate, ErrorKind> {
let version = in_slate.version();
let slate_from = Slate::from(in_slate);
let out_slate = Foreign::receive_tx(
self,
&slate_from,
dest_acct_name.as_ref().map(String::as_str),
dest,
)
.map_err(|e| e.kind())?;
Ok(VersionedSlate::into_version(out_slate, version).map_err(|e| e.kind())?)
}

fn finalize_tx(&self, in_slate: VersionedSlate) -> Result<VersionedSlate, ErrorKind> {
let version = in_slate.version();
let out_slate =
Foreign::finalize_tx(self, &Slate::from(in_slate), true).map_err(|e| e.kind())?;
Ok(VersionedSlate::into_version(out_slate, version).map_err(|e| e.kind())?)
}

//TODO: Delete HF3
fn finalize_invoice_tx(&self, in_slate: VersionedSlate) -> Result<VersionedSlate, ErrorKind> {
let version = in_slate.version();
let out_slate =
Foreign::finalize_invoice_tx(self, &Slate::from(in_slate)).map_err(|e| e.kind())?;
Foreign::finalize_tx(self, &Slate::from(in_slate), false).map_err(|e| e.kind())?;
Ok(VersionedSlate::into_version(out_slate, version).map_err(|e| e.kind())?)
}
}
Expand Down Expand Up @@ -513,8 +523,8 @@ pub fn run_doctest_foreign(
}

let mut api_foreign = match init_invoice_tx {
false => Foreign::new(wallet1, mask1, Some(test_check_middleware)),
true => Foreign::new(wallet2, mask2, Some(test_check_middleware)),
false => Foreign::new(wallet1, mask1, Some(test_check_middleware), true),
true => Foreign::new(wallet2, mask2, Some(test_check_middleware), true),
};
api_foreign.doctest_mode = true;
let foreign_api = &api_foreign as &dyn ForeignRpc;
Expand Down
2 changes: 1 addition & 1 deletion api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ mod types;

pub use crate::foreign::{Foreign, ForeignCheckMiddleware, ForeignCheckMiddlewareFn};
pub use crate::foreign_rpc::ForeignRpc;
pub use crate::owner::Owner;
pub use crate::owner::{try_slatepack_sync_workflow, Owner};
pub use crate::owner_rpc::OwnerRpc;

pub use crate::foreign_rpc::foreign_rpc as foreign_rpc_client;
Expand Down
Loading

0 comments on commit 7fb2db1

Please sign in to comment.