mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-10-01 01:45:40 -04:00
04611ee9e1
The message `JOINING all threads` is unfortunately not deterministic, it can happen that it just is not printed in the logs. For Monerod container the message is set to `RPC server started ok`. This message appears in both a test run that was hanging with `JOINING all threads` and a successful run. Initially the message was set to `core RPC server started ok` with `core` being a variable value. We assume that `core` does not change, but did not to further code analysis what values it can be. For Monero Wallet RPC container the message is set to `Run server thread name: RPC` which is what it was set to initially. After several container runs this message seems to be reasonable - there are no recorded issues of the Wallet RPC container hanging, but we had problems with Monerod in the past.
267 lines
6.7 KiB
Rust
267 lines
6.7 KiB
Rust
use std::collections::HashMap;
|
|
use testcontainers::{
|
|
core::{Container, Docker, WaitForMessage},
|
|
Image,
|
|
};
|
|
|
|
pub const MONEROD_DAEMON_CONTAINER_NAME: &str = "monerod";
|
|
pub const MONEROD_DEFAULT_NETWORK: &str = "monero_network";
|
|
|
|
/// The port we use for all RPC communication.
|
|
///
|
|
/// This is the default when running monerod.
|
|
/// For `monero-wallet-rpc` we always need to specify a port. To make things
|
|
/// simpler, we just specify the same one. They are in different containers so
|
|
/// this doesn't matter.
|
|
pub const RPC_PORT: u16 = 18081;
|
|
|
|
#[derive(Debug)]
|
|
pub struct Monerod {
|
|
args: MonerodArgs,
|
|
}
|
|
|
|
impl Image for Monerod {
|
|
type Args = MonerodArgs;
|
|
type EnvVars = HashMap<String, String>;
|
|
type Volumes = HashMap<String, String>;
|
|
type EntryPoint = str;
|
|
|
|
fn descriptor(&self) -> String {
|
|
"xmrto/monero:v0.17.2.0".to_owned()
|
|
}
|
|
|
|
fn wait_until_ready<D: Docker>(&self, container: &Container<'_, D, Self>) {
|
|
container
|
|
.logs()
|
|
.stdout
|
|
.wait_for_message("RPC server started ok")
|
|
.unwrap();
|
|
}
|
|
|
|
fn args(&self) -> <Self as Image>::Args {
|
|
self.args.clone()
|
|
}
|
|
|
|
fn volumes(&self) -> Self::Volumes {
|
|
HashMap::new()
|
|
}
|
|
|
|
fn env_vars(&self) -> Self::EnvVars {
|
|
HashMap::new()
|
|
}
|
|
|
|
fn with_args(self, args: <Self as Image>::Args) -> Self {
|
|
Self { args }
|
|
}
|
|
|
|
fn entrypoint(&self) -> Option<String> {
|
|
Some("".to_owned()) // an empty entrypoint disables the entrypoint
|
|
// script and gives us full control
|
|
}
|
|
}
|
|
|
|
impl Default for Monerod {
|
|
fn default() -> Self {
|
|
Self {
|
|
args: MonerodArgs::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct MoneroWalletRpc {
|
|
args: MoneroWalletRpcArgs,
|
|
}
|
|
|
|
impl Image for MoneroWalletRpc {
|
|
type Args = MoneroWalletRpcArgs;
|
|
type EnvVars = HashMap<String, String>;
|
|
type Volumes = HashMap<String, String>;
|
|
type EntryPoint = str;
|
|
|
|
fn descriptor(&self) -> String {
|
|
"xmrto/monero:v0.17.2.0".to_owned()
|
|
}
|
|
|
|
fn wait_until_ready<D: Docker>(&self, container: &Container<'_, D, Self>) {
|
|
container
|
|
.logs()
|
|
.stdout
|
|
.wait_for_message("Run server thread name: RPC")
|
|
.unwrap();
|
|
}
|
|
|
|
fn args(&self) -> <Self as Image>::Args {
|
|
self.args.clone()
|
|
}
|
|
|
|
fn volumes(&self) -> Self::Volumes {
|
|
HashMap::new()
|
|
}
|
|
|
|
fn env_vars(&self) -> Self::EnvVars {
|
|
HashMap::new()
|
|
}
|
|
|
|
fn with_args(self, args: <Self as Image>::Args) -> Self {
|
|
Self { args }
|
|
}
|
|
|
|
fn entrypoint(&self) -> Option<String> {
|
|
Some("".to_owned()) // an empty entrypoint disables the entrypoint
|
|
// script and gives us full control
|
|
}
|
|
}
|
|
|
|
impl Default for MoneroWalletRpc {
|
|
fn default() -> Self {
|
|
Self {
|
|
args: MoneroWalletRpcArgs::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl MoneroWalletRpc {
|
|
pub fn new(name: &str, daemon_address: String) -> Self {
|
|
Self {
|
|
args: MoneroWalletRpcArgs::new(name, daemon_address),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct MonerodArgs {
|
|
pub regtest: bool,
|
|
pub offline: bool,
|
|
pub rpc_payment_allow_free_loopback: bool,
|
|
pub confirm_external_bind: bool,
|
|
pub no_igd: bool,
|
|
pub hide_my_port: bool,
|
|
pub rpc_bind_ip: String,
|
|
pub fixed_difficulty: u32,
|
|
pub data_dir: String,
|
|
}
|
|
|
|
impl Default for MonerodArgs {
|
|
fn default() -> Self {
|
|
Self {
|
|
regtest: true,
|
|
offline: true,
|
|
rpc_payment_allow_free_loopback: true,
|
|
confirm_external_bind: true,
|
|
no_igd: true,
|
|
hide_my_port: true,
|
|
rpc_bind_ip: "0.0.0.0".to_string(),
|
|
fixed_difficulty: 1,
|
|
data_dir: "/monero".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl IntoIterator for MonerodArgs {
|
|
type Item = String;
|
|
type IntoIter = ::std::vec::IntoIter<String>;
|
|
|
|
fn into_iter(self) -> <Self as IntoIterator>::IntoIter {
|
|
let mut args = vec![
|
|
"monerod".to_string(),
|
|
"--log-level=4".to_string(),
|
|
"--non-interactive".to_string(),
|
|
];
|
|
|
|
if self.regtest {
|
|
args.push("--regtest".to_string())
|
|
}
|
|
|
|
if self.offline {
|
|
args.push("--offline".to_string())
|
|
}
|
|
|
|
if self.rpc_payment_allow_free_loopback {
|
|
args.push("--rpc-payment-allow-free-loopback".to_string())
|
|
}
|
|
|
|
if self.confirm_external_bind {
|
|
args.push("--confirm-external-bind".to_string())
|
|
}
|
|
|
|
if self.no_igd {
|
|
args.push("--no-igd".to_string())
|
|
}
|
|
|
|
if self.hide_my_port {
|
|
args.push("--hide-my-port".to_string())
|
|
}
|
|
|
|
if !self.rpc_bind_ip.is_empty() {
|
|
args.push(format!("--rpc-bind-ip={}", self.rpc_bind_ip));
|
|
}
|
|
|
|
if !self.data_dir.is_empty() {
|
|
args.push(format!("--data-dir={}", self.data_dir));
|
|
}
|
|
|
|
if self.fixed_difficulty != 0 {
|
|
args.push(format!("--fixed-difficulty={}", self.fixed_difficulty));
|
|
}
|
|
|
|
args.into_iter()
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct MoneroWalletRpcArgs {
|
|
pub disable_rpc_login: bool,
|
|
pub confirm_external_bind: bool,
|
|
pub wallet_dir: String,
|
|
pub rpc_bind_ip: String,
|
|
pub daemon_address: String,
|
|
}
|
|
|
|
impl Default for MoneroWalletRpcArgs {
|
|
fn default() -> Self {
|
|
unimplemented!("A default instance for `MoneroWalletRpc` doesn't make sense because we always need to connect to a node.")
|
|
}
|
|
}
|
|
|
|
impl MoneroWalletRpcArgs {
|
|
pub fn new(wallet_name: &str, daemon_address: String) -> Self {
|
|
Self {
|
|
disable_rpc_login: true,
|
|
confirm_external_bind: true,
|
|
wallet_dir: wallet_name.into(),
|
|
rpc_bind_ip: "0.0.0.0".into(),
|
|
daemon_address,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl IntoIterator for MoneroWalletRpcArgs {
|
|
type Item = String;
|
|
type IntoIter = ::std::vec::IntoIter<String>;
|
|
|
|
fn into_iter(self) -> <Self as IntoIterator>::IntoIter {
|
|
let mut args = vec![
|
|
"monero-wallet-rpc".to_string(),
|
|
format!("--wallet-dir={}", self.wallet_dir),
|
|
format!("--daemon-address={}", self.daemon_address),
|
|
format!("--rpc-bind-port={}", RPC_PORT),
|
|
"--log-level=4".to_string(),
|
|
];
|
|
|
|
if self.disable_rpc_login {
|
|
args.push("--disable-rpc-login".to_string())
|
|
}
|
|
|
|
if self.confirm_external_bind {
|
|
args.push("--confirm-external-bind".to_string())
|
|
}
|
|
|
|
if !self.rpc_bind_ip.is_empty() {
|
|
args.push(format!("--rpc-bind-ip={}", self.rpc_bind_ip));
|
|
}
|
|
|
|
args.into_iter()
|
|
}
|
|
}
|