mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-10-01 01:45:40 -04:00
8754a9931b
Previously we were testing the protocol by manually driving Alice and Bob's state machines. This logic has now be moved to an async state transition function that can take any possible state as input. The state transition function is called in a loop until it returns the desired state. This allows use to interrupt midway through the protocol and perform refund and punish tests. This design was chosen over a generator based implementation because the the generator based implementation results in a impure state transition function that is difficult to reason about and prone to bugs. Test related code was extracted into the tests folder. The 2b and 4b states were renamed to be consistent with the rest. Macros were used to reduce code duplication when converting child states to their parent states and vice versa. Todos were added were neccessary.
126 lines
3.5 KiB
Rust
126 lines
3.5 KiB
Rust
use anyhow::{bail, Result};
|
|
use async_trait::async_trait;
|
|
use monero::{Address, Network, PrivateKey};
|
|
use monero_harness::Monero;
|
|
use std::str::FromStr;
|
|
use xmr_btc::monero::{
|
|
Amount, CheckTransfer, ImportOutput, PrivateViewKey, PublicKey, PublicViewKey, Transfer,
|
|
TransferProof, TxHash,
|
|
};
|
|
|
|
#[derive(Debug)]
|
|
pub struct AliceWallet<'c>(pub &'c Monero<'c>);
|
|
|
|
#[async_trait]
|
|
impl Transfer for AliceWallet<'_> {
|
|
async fn transfer(
|
|
&self,
|
|
public_spend_key: PublicKey,
|
|
public_view_key: PublicViewKey,
|
|
amount: Amount,
|
|
) -> Result<(TransferProof, Amount)> {
|
|
let destination_address =
|
|
Address::standard(Network::Mainnet, public_spend_key, public_view_key.into());
|
|
|
|
let res = self
|
|
.0
|
|
.transfer_from_alice(amount.as_piconero(), &destination_address.to_string())
|
|
.await?;
|
|
|
|
let tx_hash = TxHash(res.tx_hash);
|
|
let tx_key = PrivateKey::from_str(&res.tx_key)?;
|
|
|
|
let fee = Amount::from_piconero(res.fee);
|
|
|
|
Ok((TransferProof::new(tx_hash, tx_key), fee))
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl ImportOutput for AliceWallet<'_> {
|
|
async fn import_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
|
|
.alice_wallet_rpc_client()
|
|
.generate_from_keys(
|
|
&address.to_string(),
|
|
&private_spend_key.to_string(),
|
|
&PrivateKey::from(private_view_key).to_string(),
|
|
)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct BobWallet<'c>(pub &'c Monero<'c>);
|
|
|
|
#[async_trait]
|
|
impl CheckTransfer for BobWallet<'_> {
|
|
async fn check_transfer(
|
|
&self,
|
|
public_spend_key: PublicKey,
|
|
public_view_key: PublicViewKey,
|
|
transfer_proof: TransferProof,
|
|
amount: Amount,
|
|
) -> Result<()> {
|
|
let address = Address::standard(Network::Mainnet, public_spend_key, public_view_key.into());
|
|
|
|
let cli = self.0.bob_wallet_rpc_client();
|
|
|
|
let res = cli
|
|
.check_tx_key(
|
|
&String::from(transfer_proof.tx_hash()),
|
|
&transfer_proof.tx_key().to_string(),
|
|
&address.to_string(),
|
|
)
|
|
.await?;
|
|
|
|
if res.received != u64::from(amount) {
|
|
bail!(
|
|
"tx_lock doesn't pay enough: expected {:?}, got {:?}",
|
|
res.received,
|
|
amount
|
|
)
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl ImportOutput for BobWallet<'_> {
|
|
async fn import_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(())
|
|
}
|
|
}
|