Simplify xmr-btc/tests Monero wallet

- Make it the same for Alice and Bob.
- Make it contain a wallet client instead of the `Monero` struct.

Also:

Remove `Container` from inside `Monero` struct. The caller of `new`
can simply ensure that `Container` is not dropped to keep the
container alive.

This makes the `Monero` struct easier to work with, as it just holds
the data necessary to create the different clients created during
`init`, and does not have any lifetime restrictions.
This commit is contained in:
Lucas Soriano del Pino 2020-10-20 12:18:27 +11:00
parent 55629838f4
commit 50ed74319f
8 changed files with 88 additions and 207 deletions

View file

@ -5,18 +5,18 @@ use xmr_btc::{alice, bob};
// TODO: merge this with bob node
// This struct is responsible for I/O
pub struct AliceNode<'a> {
pub struct AliceNode {
transport: Transport<alice::Message, bob::Message>,
pub bitcoin_wallet: wallet::bitcoin::Wallet,
pub monero_wallet: wallet::monero::AliceWallet<'a>,
pub monero_wallet: wallet::monero::Wallet,
}
impl<'a> AliceNode<'a> {
impl AliceNode {
pub fn new(
transport: Transport<alice::Message, bob::Message>,
bitcoin_wallet: wallet::bitcoin::Wallet,
monero_wallet: wallet::monero::AliceWallet<'a>,
) -> AliceNode<'a> {
monero_wallet: wallet::monero::Wallet,
) -> AliceNode {
Self {
transport,
bitcoin_wallet,
@ -25,8 +25,8 @@ impl<'a> AliceNode<'a> {
}
}
pub async fn run_alice_until<'a, R: RngCore + CryptoRng>(
alice: &mut AliceNode<'a>,
pub async fn run_alice_until<R: RngCore + CryptoRng>(
alice: &mut AliceNode,
initial_state: alice::State,
is_state: fn(&alice::State) -> bool,
rng: &mut R,
@ -49,18 +49,18 @@ pub async fn run_alice_until<'a, R: RngCore + CryptoRng>(
// TODO: merge this with alice node
// This struct is responsible for I/O
pub struct BobNode<'a> {
pub struct BobNode {
transport: Transport<bob::Message, alice::Message>,
pub bitcoin_wallet: wallet::bitcoin::Wallet,
pub monero_wallet: wallet::monero::BobWallet<'a>,
pub monero_wallet: wallet::monero::Wallet,
}
impl<'a> BobNode<'a> {
impl BobNode {
pub fn new(
transport: Transport<bob::Message, alice::Message>,
bitcoin_wallet: wallet::bitcoin::Wallet,
monero_wallet: wallet::monero::BobWallet<'a>,
) -> BobNode<'a> {
monero_wallet: wallet::monero::Wallet,
) -> BobNode {
Self {
transport,
bitcoin_wallet,
@ -69,8 +69,8 @@ impl<'a> BobNode<'a> {
}
}
pub async fn run_bob_until<'a, R: RngCore + CryptoRng>(
bob: &mut BobNode<'a>,
pub async fn run_bob_until<R: RngCore + CryptoRng>(
bob: &mut BobNode,
initial_state: bob::State,
is_state: fn(&bob::State) -> bool,
rng: &mut R,

View file

@ -2,18 +2,17 @@ use anyhow::Result;
use async_trait::async_trait;
use backoff::{future::FutureOperation as _, ExponentialBackoff};
use monero::{Address, Network, PrivateKey};
use monero_harness::Monero;
use monero_harness::rpc::wallet;
use std::str::FromStr;
use xmr_btc::monero::{
Amount, CreateWalletForOutput, InsufficientFunds, PrivateViewKey, PublicKey, PublicViewKey,
Transfer, TransferProof, TxHash, WatchForTransfer,
};
#[derive(Debug)]
pub struct AliceWallet<'c>(pub &'c Monero<'c>);
pub struct Wallet(pub wallet::Client);
#[async_trait]
impl Transfer for AliceWallet<'_> {
impl Transfer for Wallet {
async fn transfer(
&self,
public_spend_key: PublicKey,
@ -25,7 +24,7 @@ impl Transfer for AliceWallet<'_> {
let res = self
.0
.transfer_from_alice(amount.as_piconero(), &destination_address.to_string())
.transfer(0, amount.as_piconero(), &destination_address.to_string())
.await?;
let tx_hash = TxHash(res.tx_hash);
@ -38,7 +37,7 @@ impl Transfer for AliceWallet<'_> {
}
#[async_trait]
impl CreateWalletForOutput for AliceWallet<'_> {
impl CreateWalletForOutput for Wallet {
async fn create_and_load_wallet_for_output(
&self,
private_spend_key: PrivateKey,
@ -51,7 +50,6 @@ impl CreateWalletForOutput for AliceWallet<'_> {
let _ = self
.0
.alice_wallet_rpc_client()
.generate_from_keys(
&address.to_string(),
&private_spend_key.to_string(),
@ -63,11 +61,8 @@ impl CreateWalletForOutput for AliceWallet<'_> {
}
}
#[derive(Debug)]
pub struct BobWallet<'c>(pub &'c Monero<'c>);
#[async_trait]
impl WatchForTransfer for BobWallet<'_> {
impl WatchForTransfer for Wallet {
async fn watch_for_transfer(
&self,
public_spend_key: PublicKey,
@ -82,14 +77,14 @@ impl WatchForTransfer for BobWallet<'_> {
InsufficientFunds { expected: Amount, actual: Amount },
}
let wallet = self.0.bob_wallet_rpc_client();
let address = Address::standard(Network::Mainnet, public_spend_key, public_view_key.into());
let res = (|| async {
// NOTE: Currently, this is conflating IO errors with the transaction not being
// in the blockchain yet, or not having enough confirmations on it. All these
// errors warrant a retry, but the strategy should probably differ per case
let proof = wallet
let proof = self
.0
.check_tx_key(
&String::from(transfer_proof.tx_hash()),
&transfer_proof.tx_key().to_string(),
@ -124,29 +119,3 @@ impl WatchForTransfer for BobWallet<'_> {
Ok(())
}
}
#[async_trait]
impl CreateWalletForOutput for BobWallet<'_> {
async fn create_and_load_wallet_for_output(
&self,
private_spend_key: PrivateKey,
private_view_key: PrivateViewKey,
) -> Result<()> {
let public_spend_key = PublicKey::from_private_key(&private_spend_key);
let public_view_key = PublicKey::from_private_key(&private_view_key.into());
let address = Address::standard(Network::Mainnet, public_spend_key, public_view_key);
let _ = self
.0
.bob_wallet_rpc_client()
.generate_from_keys(
&address.to_string(),
&private_spend_key.to_string(),
&PrivateKey::from(private_view_key).to_string(),
)
.await?;
Ok(())
}
}