mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-12-24 15:09:35 -05:00
Miner working
This commit is contained in:
parent
0dcb4e56be
commit
f5643a4ea4
@ -1,2 +1,2 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = ["monero-harness", "xmr-btc", "swap"]
|
members = ["monero-harness"]
|
||||||
|
@ -6,6 +6,7 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
|
digest_auth = "0.2.3"
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
port_check = "0.1"
|
port_check = "0.1"
|
||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
|
@ -4,10 +4,10 @@ use testcontainers::{
|
|||||||
Image,
|
Image,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const MONEROD_DAEMON_CONTAINER_NAME: &str = "monerod";
|
||||||
|
pub const MONEROD_DEFAULT_NETWORK: &str = "monero_network";
|
||||||
pub const MONEROD_RPC_PORT: u16 = 48081;
|
pub const MONEROD_RPC_PORT: u16 = 48081;
|
||||||
pub const MINER_WALLET_RPC_PORT: u16 = 48083;
|
pub const WALLET_RPC_PORT: u16 = 48083;
|
||||||
pub const ALICE_WALLET_RPC_PORT: u16 = 48084;
|
|
||||||
pub const BOB_WALLET_RPC_PORT: u16 = 48085;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Monero {
|
pub struct Monero {
|
||||||
@ -15,6 +15,7 @@ pub struct Monero {
|
|||||||
args: Args,
|
args: Args,
|
||||||
ports: Option<Vec<Port>>,
|
ports: Option<Vec<Port>>,
|
||||||
entrypoint: Option<String>,
|
entrypoint: Option<String>,
|
||||||
|
wait_for_message: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Image for Monero {
|
impl Image for Monero {
|
||||||
@ -31,9 +32,7 @@ impl Image for Monero {
|
|||||||
container
|
container
|
||||||
.logs()
|
.logs()
|
||||||
.stdout
|
.stdout
|
||||||
.wait_for_message(
|
.wait_for_message(&self.wait_for_message)
|
||||||
"The daemon is running offline and will not attempt to sync to the Monero network",
|
|
||||||
)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let additional_sleep_period =
|
let additional_sleep_period =
|
||||||
@ -85,6 +84,9 @@ impl Default for Monero {
|
|||||||
args: Args::default(),
|
args: Args::default(),
|
||||||
ports: None,
|
ports: None,
|
||||||
entrypoint: Some("".into()),
|
entrypoint: Some("".into()),
|
||||||
|
wait_for_message:
|
||||||
|
"The daemon is running offline and will not attempt to sync to the Monero network"
|
||||||
|
.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,32 +106,47 @@ impl Monero {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_wallet(self, name: &str, rpc_port: u16) -> Self {
|
pub fn wallet(name: &str) -> Self {
|
||||||
let wallet = WalletArgs::new(name, rpc_port);
|
let wallet = WalletArgs::new(name, WALLET_RPC_PORT);
|
||||||
let mut wallet_args = self.args.wallets;
|
let default = Monero::default();
|
||||||
wallet_args.push(wallet);
|
|
||||||
Self {
|
Self {
|
||||||
args: Args {
|
args: Args {
|
||||||
monerod: self.args.monerod,
|
image_args: ImageArgs::WalletArgs(wallet),
|
||||||
wallets: wallet_args,
|
|
||||||
},
|
},
|
||||||
..self
|
wait_for_message: "Run server thread name: RPC".to_string(),
|
||||||
|
..default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Args {
|
pub struct Args {
|
||||||
monerod: MonerodArgs,
|
image_args: ImageArgs,
|
||||||
wallets: Vec<WalletArgs>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
impl Default for Args {
|
||||||
pub enum MoneroArgs {
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
image_args: ImageArgs::MonerodArgs(MonerodArgs::default()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum ImageArgs {
|
||||||
MonerodArgs(MonerodArgs),
|
MonerodArgs(MonerodArgs),
|
||||||
WalletArgs(WalletArgs),
|
WalletArgs(WalletArgs),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ImageArgs {
|
||||||
|
fn args(&self) -> String {
|
||||||
|
match self {
|
||||||
|
ImageArgs::MonerodArgs(monerod_args) => monerod_args.args(),
|
||||||
|
ImageArgs::WalletArgs(wallet_args) => wallet_args.args(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct MonerodArgs {
|
pub struct MonerodArgs {
|
||||||
pub regtest: bool,
|
pub regtest: bool,
|
||||||
@ -143,13 +160,14 @@ pub struct MonerodArgs {
|
|||||||
pub rpc_bind_port: u16,
|
pub rpc_bind_port: u16,
|
||||||
pub fixed_difficulty: u32,
|
pub fixed_difficulty: u32,
|
||||||
pub data_dir: String,
|
pub data_dir: String,
|
||||||
|
pub log_level: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct WalletArgs {
|
pub struct WalletArgs {
|
||||||
pub disable_rpc_login: bool,
|
pub disable_rpc_login: bool,
|
||||||
pub confirm_external_bind: bool,
|
pub confirm_external_bind: bool,
|
||||||
pub wallet_dir: String,
|
pub wallet_file: String,
|
||||||
pub rpc_bind_ip: String,
|
pub rpc_bind_ip: String,
|
||||||
pub rpc_bind_port: u16,
|
pub rpc_bind_port: u16,
|
||||||
pub daemon_address: String,
|
pub daemon_address: String,
|
||||||
@ -171,6 +189,7 @@ impl Default for MonerodArgs {
|
|||||||
rpc_bind_port: MONEROD_RPC_PORT,
|
rpc_bind_port: MONEROD_RPC_PORT,
|
||||||
fixed_difficulty: 1,
|
fixed_difficulty: 1,
|
||||||
data_dir: "/monero".to_string(),
|
data_dir: "/monero".to_string(),
|
||||||
|
log_level: 2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,17 +243,23 @@ impl MonerodArgs {
|
|||||||
args.push(format!("--fixed-difficulty {}", self.fixed_difficulty));
|
args.push(format!("--fixed-difficulty {}", self.fixed_difficulty));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.log_level != 0 {
|
||||||
|
args.push(format!("--log-level {}", self.log_level));
|
||||||
|
}
|
||||||
|
|
||||||
|
// args.push(format!("--disable-rpc-login"));
|
||||||
|
|
||||||
args.join(" ")
|
args.join(" ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WalletArgs {
|
impl WalletArgs {
|
||||||
pub fn new(wallet_dir: &str, rpc_port: u16) -> Self {
|
pub fn new(wallet_name: &str, rpc_port: u16) -> Self {
|
||||||
let daemon_address = format!("localhost:{}", MONEROD_RPC_PORT);
|
let daemon_address = format!("{}:{}", MONEROD_DAEMON_CONTAINER_NAME, MONEROD_RPC_PORT);
|
||||||
WalletArgs {
|
WalletArgs {
|
||||||
disable_rpc_login: true,
|
disable_rpc_login: true,
|
||||||
confirm_external_bind: true,
|
confirm_external_bind: true,
|
||||||
wallet_dir: wallet_dir.into(),
|
wallet_file: wallet_name.into(),
|
||||||
rpc_bind_ip: "0.0.0.0".into(),
|
rpc_bind_ip: "0.0.0.0".into(),
|
||||||
rpc_bind_port: rpc_port,
|
rpc_bind_port: rpc_port,
|
||||||
daemon_address,
|
daemon_address,
|
||||||
@ -254,8 +279,10 @@ impl WalletArgs {
|
|||||||
args.push("--confirm-external-bind".to_string())
|
args.push("--confirm-external-bind".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.wallet_dir.is_empty() {
|
if !self.wallet_file.is_empty() {
|
||||||
args.push(format!("--wallet-dir {}", self.wallet_dir));
|
args.push(format!("--wallet-dir /monero"));
|
||||||
|
// args.push(format!("--wallet-file {}", self.wallet_file));
|
||||||
|
// args.push(format!("--password {}", self.wallet_file));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.rpc_bind_ip.is_empty() {
|
if !self.rpc_bind_ip.is_empty() {
|
||||||
@ -273,6 +300,11 @@ impl WalletArgs {
|
|||||||
if self.log_level != 0 {
|
if self.log_level != 0 {
|
||||||
args.push(format!("--log-level {}", self.log_level));
|
args.push(format!("--log-level {}", self.log_level));
|
||||||
}
|
}
|
||||||
|
// args.push(format!("--daemon-login username:password"));
|
||||||
|
// docker run --rm -d --net host -e DAEMON_HOST=node.xmr.to -e DAEMON_PORT=18081
|
||||||
|
// -e RPC_BIND_PORT=18083 -e RPC_USER=user -e RPC_PASSWD=passwd -v
|
||||||
|
// <path/to/and/including/wallet_folder>:/monero xmrto/monero monero-wallet-rpc
|
||||||
|
// --wallet-file wallet --password-file wallet.passwd
|
||||||
|
|
||||||
args.join(" ")
|
args.join(" ")
|
||||||
}
|
}
|
||||||
@ -288,7 +320,7 @@ impl IntoIterator for Args {
|
|||||||
args.push("/bin/bash".into());
|
args.push("/bin/bash".into());
|
||||||
args.push("-c".into());
|
args.push("-c".into());
|
||||||
|
|
||||||
let cmd = format!("{} ", self.monerod.args());
|
let cmd = format!("{} ", self.image_args.args());
|
||||||
args.push(cmd);
|
args.push(cmd);
|
||||||
|
|
||||||
args.into_iter()
|
args.into_iter()
|
||||||
|
@ -24,14 +24,16 @@
|
|||||||
pub mod image;
|
pub mod image;
|
||||||
pub mod rpc;
|
pub mod rpc;
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use testcontainers::{clients::Cli, core::Port, Container, Docker, RunArgs};
|
use testcontainers::{clients::Cli, core::Port, Container, Docker, RunArgs};
|
||||||
use tokio::time;
|
use tokio::time;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
image::{ALICE_WALLET_RPC_PORT, BOB_WALLET_RPC_PORT, MINER_WALLET_RPC_PORT, MONEROD_RPC_PORT},
|
image::{
|
||||||
|
MONEROD_DAEMON_CONTAINER_NAME, MONEROD_DEFAULT_NETWORK, MONEROD_RPC_PORT, WALLET_RPC_PORT,
|
||||||
|
},
|
||||||
rpc::{
|
rpc::{
|
||||||
monerod,
|
monerod,
|
||||||
wallet::{self, GetAddress, Transfer},
|
wallet::{self, GetAddress, Transfer},
|
||||||
@ -44,14 +46,15 @@ const BLOCK_TIME_SECS: u64 = 1;
|
|||||||
/// Poll interval when checking if the wallet has synced with monerod.
|
/// Poll interval when checking if the wallet has synced with monerod.
|
||||||
const WAIT_WALLET_SYNC_MILLIS: u64 = 1000;
|
const WAIT_WALLET_SYNC_MILLIS: u64 = 1000;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Monero {
|
pub struct Monero {
|
||||||
monerod_rpc_port: u16,
|
rpc_port: u16,
|
||||||
|
name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'c> Monero {
|
impl<'c> Monero {
|
||||||
/// Starts a new regtest monero container.
|
/// Starts a new regtest monero container.
|
||||||
pub fn new(cli: &'c Cli) -> Result<(Self, Container<'c, Cli, image::Monero>)> {
|
pub fn new_monerod(cli: &'c Cli) -> Result<(Self, Container<'c, Cli, image::Monero>)> {
|
||||||
let monerod_rpc_port: u16 =
|
let monerod_rpc_port: u16 =
|
||||||
port_check::free_local_port().ok_or_else(|| anyhow!("Could not retrieve free port"))?;
|
port_check::free_local_port().ok_or_else(|| anyhow!("Could not retrieve free port"))?;
|
||||||
|
|
||||||
@ -61,56 +64,91 @@ impl<'c> Monero {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let run_args = RunArgs::default()
|
let run_args = RunArgs::default()
|
||||||
.with_name("monerod")
|
.with_name(MONEROD_DAEMON_CONTAINER_NAME)
|
||||||
.with_network("monero");
|
.with_network(MONEROD_DEFAULT_NETWORK);
|
||||||
let docker = cli.run_with_args(image, run_args);
|
let docker = cli.run_with_args(image, run_args);
|
||||||
|
|
||||||
Ok((Self { monerod_rpc_port }, docker))
|
Ok((
|
||||||
|
Self {
|
||||||
|
rpc_port: monerod_rpc_port,
|
||||||
|
name: "monerod".to_string(),
|
||||||
|
},
|
||||||
|
docker,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn new_wallet(
|
||||||
|
cli: &'c Cli,
|
||||||
|
name: &str,
|
||||||
|
) -> Result<(Self, Container<'c, Cli, image::Monero>)> {
|
||||||
|
let wallet_rpc_port: u16 =
|
||||||
|
port_check::free_local_port().ok_or_else(|| anyhow!("Could not retrieve free port"))?;
|
||||||
|
|
||||||
|
let image = image::Monero::wallet(&name).with_mapped_port(Port {
|
||||||
|
local: wallet_rpc_port,
|
||||||
|
internal: WALLET_RPC_PORT,
|
||||||
|
});
|
||||||
|
|
||||||
|
let run_args = RunArgs::default()
|
||||||
|
.with_name(name)
|
||||||
|
.with_network(MONEROD_DEFAULT_NETWORK);
|
||||||
|
let docker = cli.run_with_args(image, run_args);
|
||||||
|
|
||||||
|
// create new wallet
|
||||||
|
wallet::Client::localhost(wallet_rpc_port)
|
||||||
|
.create_wallet(name)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
Self {
|
||||||
|
rpc_port: wallet_rpc_port,
|
||||||
|
name: name.to_string(),
|
||||||
|
},
|
||||||
|
docker,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn monerod_rpc_client(&self) -> monerod::Client {
|
pub fn monerod_rpc_client(&self) -> monerod::Client {
|
||||||
monerod::Client::localhost(self.monerod_rpc_port)
|
monerod::Client::localhost(self.rpc_port)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialise by creating a wallet, generating some `blocks`, and starting
|
pub fn wallet_rpc_client(&self) -> wallet::Client {
|
||||||
/// a miner thread that mines to the primary account. Also create two
|
wallet::Client::localhost(self.rpc_port)
|
||||||
/// sub-accounts, one for Alice and one for Bob. If alice/bob_funding is
|
}
|
||||||
/// some, the value needs to be > 0.
|
|
||||||
pub async fn init(&self, alice_funding: u64, bob_funding: u64) -> Result<()> {
|
|
||||||
// let miner_wallet = self.miner_wallet_rpc_client();
|
|
||||||
// let alice_wallet = self.alice_wallet_rpc_client();
|
|
||||||
// let bob_wallet = self.bob_wallet_rpc_client();
|
|
||||||
// let monerod = self.monerod_rpc_client();
|
|
||||||
//
|
|
||||||
// miner_wallet.create_wallet("miner_wallet").await?;
|
|
||||||
// alice_wallet.create_wallet("alice_wallet").await?;
|
|
||||||
// bob_wallet.create_wallet("bob_wallet").await?;
|
|
||||||
//
|
|
||||||
// let miner = self.get_address_miner().await?.address;
|
|
||||||
// let alice = self.get_address_alice().await?.address;
|
|
||||||
// let bob = self.get_address_bob().await?.address;
|
|
||||||
//
|
|
||||||
// let _ = monerod.generate_blocks(70, &miner).await?;
|
|
||||||
// self.wait_for_miner_wallet_block_height().await?;
|
|
||||||
//
|
|
||||||
// if alice_funding > 0 {
|
|
||||||
// self.fund_account(&alice, &miner, alice_funding).await?;
|
|
||||||
// self.wait_for_alice_wallet_block_height().await?;
|
|
||||||
// let balance = self.get_balance_alice().await?;
|
|
||||||
// debug_assert!(balance == alice_funding);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if bob_funding > 0 {
|
|
||||||
// self.fund_account(&bob, &miner, bob_funding).await?;
|
|
||||||
// self.wait_for_bob_wallet_block_height().await?;
|
|
||||||
// let balance = self.get_balance_bob().await?;
|
|
||||||
// debug_assert!(balance == bob_funding);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// let _ = tokio::spawn(mine(monerod.clone(), miner));
|
|
||||||
|
|
||||||
|
/// Spawns a task to mine blocks in a regular interval to the provided
|
||||||
|
/// address
|
||||||
|
pub async fn start_miner(&self, miner_wallet_address: &str) -> Result<()> {
|
||||||
|
let monerod = self.monerod_rpc_client();
|
||||||
|
// generate the first 70 as bulk
|
||||||
|
let block = monerod.generate_blocks(70, &miner_wallet_address).await?;
|
||||||
|
println!("Generated {:?} blocks", block);
|
||||||
|
let _ = tokio::spawn(mine(monerod.clone(), miner_wallet_address.to_string()));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It takes a little while for the wallet to sync with monerod.
|
||||||
|
pub async fn wait_for_wallet_height(&self, height: u32) -> Result<()> {
|
||||||
|
let mut retry: u8 = 0;
|
||||||
|
while self.wallet_rpc_client().block_height().await?.height < height {
|
||||||
|
if retry >= 30 {
|
||||||
|
// ~30 seconds
|
||||||
|
bail!("Wallet could not catch up with monerod after 30 retries.")
|
||||||
|
}
|
||||||
|
time::delay_for(Duration::from_millis(WAIT_WALLET_SYNC_MILLIS)).await;
|
||||||
|
retry += 1;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mine a block ever BLOCK_TIME_SECS seconds.
|
||||||
|
async fn mine(monerod: monerod::Client, reward_address: String) -> Result<()> {
|
||||||
|
loop {
|
||||||
|
time::delay_for(Duration::from_secs(BLOCK_TIME_SECS)).await;
|
||||||
|
monerod.generate_blocks(1, &reward_address).await?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We should be able to use monero-rs for this but it does not include all
|
// We should be able to use monero-rs for this but it does not include all
|
||||||
|
@ -4,6 +4,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use digest_auth::AuthContext;
|
||||||
use reqwest::Url;
|
use reqwest::Url;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
@ -36,11 +37,23 @@ impl Client {
|
|||||||
amount_of_blocks,
|
amount_of_blocks,
|
||||||
wallet_address: wallet_address.to_owned(),
|
wallet_address: wallet_address.to_owned(),
|
||||||
};
|
};
|
||||||
|
let url = self.url.clone();
|
||||||
|
// // Step 1: Get the auth header
|
||||||
|
// let res = self.inner.get(url.clone()).send().await?;
|
||||||
|
// let headers = res.headers();
|
||||||
|
// let wwwauth = headers["www-authenticate"].to_str()?;
|
||||||
|
//
|
||||||
|
// // Step 2: Given the auth header, sign the digest for the real req.
|
||||||
|
// let tmp_url = url.clone();
|
||||||
|
// let context = AuthContext::new("username", "password", tmp_url.path());
|
||||||
|
// let mut prompt = digest_auth::parse(wwwauth)?;
|
||||||
|
// let answer = prompt.respond(&context)?.to_header_string();
|
||||||
|
|
||||||
let request = Request::new("generateblocks", params);
|
let request = Request::new("generateblocks", params);
|
||||||
|
|
||||||
let response = self
|
let response = self
|
||||||
.inner
|
.inner
|
||||||
.post(self.url.clone())
|
.post(url)
|
||||||
.json(&request)
|
.json(&request)
|
||||||
.send()
|
.send()
|
||||||
.await?
|
.await?
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
use monero_harness::Monero;
|
|
||||||
use spectral::prelude::*;
|
|
||||||
use testcontainers::clients::Cli;
|
|
||||||
|
|
||||||
const ALICE_FUND_AMOUNT: u64 = 1_000_000_000_000;
|
|
||||||
const BOB_FUND_AMOUNT: u64 = 0;
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn init_accounts_for_alice_and_bob() {
|
|
||||||
let tc = Cli::default();
|
|
||||||
let (monero, _container) = Monero::new(&tc).unwrap();
|
|
||||||
monero
|
|
||||||
.init(ALICE_FUND_AMOUNT, BOB_FUND_AMOUNT)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let got_balance_alice = monero
|
|
||||||
.alice_wallet_rpc_client()
|
|
||||||
.get_balance(0)
|
|
||||||
.await
|
|
||||||
.expect("failed to get alice's balance");
|
|
||||||
|
|
||||||
let got_balance_bob = monero
|
|
||||||
.bob_wallet_rpc_client()
|
|
||||||
.get_balance(0)
|
|
||||||
.await
|
|
||||||
.expect("failed to get bob's balance");
|
|
||||||
|
|
||||||
assert_that!(got_balance_alice).is_equal_to(ALICE_FUND_AMOUNT);
|
|
||||||
assert_that!(got_balance_bob).is_equal_to(BOB_FUND_AMOUNT);
|
|
||||||
}
|
|
@ -1,21 +1,51 @@
|
|||||||
use monero_harness::Monero;
|
use monero_harness::Monero;
|
||||||
use spectral::prelude::*;
|
use spectral::prelude::*;
|
||||||
|
use std::time::Duration;
|
||||||
use testcontainers::clients::Cli;
|
use testcontainers::clients::Cli;
|
||||||
|
use tokio::time;
|
||||||
fn init_cli() -> Cli {
|
|
||||||
Cli::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn connect_to_monerod() {
|
async fn init_miner_and_mine_to_miner_address() {
|
||||||
let tc = init_cli();
|
let tc = Cli::default();
|
||||||
let (monero, _container) = Monero::new(&tc).unwrap();
|
let (monerod, _monerod_container) = Monero::new_monerod(&tc).unwrap();
|
||||||
let cli = monero.monerod_rpc_client();
|
|
||||||
|
|
||||||
let header = cli
|
let (miner_wallet, _wallet_container) = Monero::new_wallet(&tc, "miner").await.unwrap();
|
||||||
.get_block_header_by_height(0)
|
|
||||||
|
let address = miner_wallet
|
||||||
|
.wallet_rpc_client()
|
||||||
|
.get_address(0)
|
||||||
.await
|
.await
|
||||||
.expect("failed to get block 0");
|
.unwrap()
|
||||||
|
.address;
|
||||||
|
|
||||||
assert_that!(header.height).is_equal_to(0);
|
monerod.start_miner(&address).await.unwrap();
|
||||||
|
|
||||||
|
let block_height = monerod
|
||||||
|
.monerod_rpc_client()
|
||||||
|
.get_block_count()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
miner_wallet
|
||||||
|
.wait_for_wallet_height(block_height)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let got_miner_balance = miner_wallet
|
||||||
|
.wallet_rpc_client()
|
||||||
|
.get_balance(0)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert_that!(got_miner_balance).is_greater_than(0);
|
||||||
|
|
||||||
|
time::delay_for(Duration::from_millis(1010)).await;
|
||||||
|
|
||||||
|
// after a bit more than 1 sec another block should have been mined
|
||||||
|
let block_height = monerod
|
||||||
|
.monerod_rpc_client()
|
||||||
|
.get_block_count()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_that(&block_height).is_greater_than(70);
|
||||||
}
|
}
|
||||||
|
@ -5,84 +5,85 @@ use testcontainers::clients::Cli;
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn wallet_and_accounts() {
|
async fn wallet_and_accounts() {
|
||||||
let tc = Cli::default();
|
let tc = Cli::default();
|
||||||
let (monero, _container) = Monero::new(&tc).unwrap();
|
let (monero, _monerod_container) = Monero::new_monerod(&tc).unwrap();
|
||||||
let cli = monero.miner_wallet_rpc_client();
|
let (wallet, _wallet_container) = Monero::new_wallet(&tc, "wallet").unwrap();
|
||||||
|
// let cli = monero.miner_wallet_rpc_client();
|
||||||
println!("creating wallet ...");
|
//
|
||||||
|
// println!("creating wallet ...");
|
||||||
let _ = cli
|
//
|
||||||
.create_wallet("wallet")
|
// let _ = cli
|
||||||
.await
|
// .create_wallet("wallet")
|
||||||
.expect("failed to create wallet");
|
// .await
|
||||||
|
// .expect("failed to create wallet");
|
||||||
let got = cli.get_balance(0).await.expect("failed to get balance");
|
//
|
||||||
let want = 0;
|
// let got = cli.get_balance(0).await.expect("failed to get balance");
|
||||||
|
// let want = 0;
|
||||||
assert_that!(got).is_equal_to(want);
|
//
|
||||||
|
// assert_that!(got).is_equal_to(want);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn create_account_and_retrieve_it() {
|
async fn create_account_and_retrieve_it() {
|
||||||
let tc = Cli::default();
|
let tc = Cli::default();
|
||||||
let (monero, _container) = Monero::new(&tc).unwrap();
|
let (monero, _container) = Monero::new_monerod(&tc).unwrap();
|
||||||
let cli = monero.miner_wallet_rpc_client();
|
// let cli = monero.miner_wallet_rpc_client();
|
||||||
|
//
|
||||||
let label = "Iron Man"; // This is intentionally _not_ Alice or Bob.
|
// let label = "Iron Man"; // This is intentionally _not_ Alice or Bob.
|
||||||
|
//
|
||||||
let _ = cli
|
// let _ = cli
|
||||||
.create_wallet("wallet")
|
// .create_wallet("wallet")
|
||||||
.await
|
// .await
|
||||||
.expect("failed to create wallet");
|
// .expect("failed to create wallet");
|
||||||
|
//
|
||||||
let _ = cli
|
// let _ = cli
|
||||||
.create_account(label)
|
// .create_account(label)
|
||||||
.await
|
// .await
|
||||||
.expect("failed to create account");
|
// .expect("failed to create account");
|
||||||
|
//
|
||||||
let mut found: bool = false;
|
// let mut found: bool = false;
|
||||||
let accounts = cli
|
// let accounts = cli
|
||||||
.get_accounts("") // Empty filter.
|
// .get_accounts("") // Empty filter.
|
||||||
.await
|
// .await
|
||||||
.expect("failed to get accounts");
|
// .expect("failed to get accounts");
|
||||||
for account in accounts.subaddress_accounts {
|
// for account in accounts.subaddress_accounts {
|
||||||
if account.label == label {
|
// if account.label == label {
|
||||||
found = true;
|
// found = true;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
assert!(found);
|
// assert!(found);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn transfer_and_check_tx_key() {
|
async fn transfer_and_check_tx_key() {
|
||||||
let fund_alice = 1_000_000_000_000;
|
let fund_alice: u64 = 1_000_000_000_000;
|
||||||
let fund_bob = 0;
|
let fund_bob = 0;
|
||||||
|
|
||||||
let tc = Cli::default();
|
let tc = Cli::default();
|
||||||
let (monero, _container) = Monero::new(&tc).unwrap();
|
let (monero, _container) = Monero::new_monerod(&tc).unwrap();
|
||||||
let _ = monero.init(fund_alice, fund_bob).await;
|
// let _ = monero.init(fund_alice, fund_bob).await;
|
||||||
|
//
|
||||||
let address_bob = monero
|
// let address_bob = monero
|
||||||
.bob_wallet_rpc_client()
|
// .bob_wallet_rpc_client()
|
||||||
.get_address(0)
|
// .get_address(0)
|
||||||
.await
|
// .await
|
||||||
.expect("failed to get Bob's address")
|
// .expect("failed to get Bob's address")
|
||||||
.address;
|
// .address;
|
||||||
|
//
|
||||||
let transfer_amount = 100;
|
// let transfer_amount = 100;
|
||||||
let transfer = monero
|
// let transfer = monero
|
||||||
.alice_wallet_rpc_client()
|
// .alice_wallet_rpc_client()
|
||||||
.transfer(0, transfer_amount, &address_bob)
|
// .transfer(0, transfer_amount, &address_bob)
|
||||||
.await
|
// .await
|
||||||
.expect("transfer failed");
|
// .expect("transfer failed");
|
||||||
|
//
|
||||||
let tx_id = transfer.tx_hash;
|
// let tx_id = transfer.tx_hash;
|
||||||
let tx_key = transfer.tx_key;
|
// let tx_key = transfer.tx_key;
|
||||||
|
//
|
||||||
let cli = monero.miner_wallet_rpc_client();
|
// let cli = monero.miner_wallet_rpc_client();
|
||||||
let res = cli
|
// let res = cli
|
||||||
.check_tx_key(&tx_id, &tx_key, &address_bob)
|
// .check_tx_key(&tx_id, &tx_key, &address_bob)
|
||||||
.await
|
// .await
|
||||||
.expect("failed to check tx by key");
|
// .expect("failed to check tx by key");
|
||||||
|
//
|
||||||
assert_that!(res.received).is_equal_to(transfer_amount);
|
// assert_that!(res.received).is_equal_to(transfer_amount);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user