Skip to content

Commit

Permalink
Fix merge mining proxy pool mining
Browse files Browse the repository at this point in the history
Fixed merge mining proxy pool mining:
- config file was not read correctly;
- global config exited prematurely ;
- round robin for monerod_url - start at the next entry in the list when
  encountering connection errors instead of always starting at the beginning;
- updated cucumber integration test.
  • Loading branch information
hansieodendaal committed Feb 9, 2022
1 parent 2ccf9a8 commit 6bf8057
Show file tree
Hide file tree
Showing 14 changed files with 234 additions and 186 deletions.
2 changes: 2 additions & 0 deletions applications/tari_merge_mining_proxy/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ async fn main() -> Result<(), anyhow::Error> {
return Ok(());
},
};
println!("\n{}\n", config);

let addr = config.proxy_host_address;
let client = reqwest::Client::builder()
.connect_timeout(Duration::from_secs(5))
Expand Down
99 changes: 82 additions & 17 deletions applications/tari_merge_mining_proxy/src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use std::{
cmp,
convert::TryFrom,
fmt::{Display, Error, Formatter},
future::Future,
net::SocketAddr,
pin::Pin,
Expand Down Expand Up @@ -82,6 +83,8 @@ impl TryFrom<GlobalConfig> for MergeMiningProxyConfig {
let merge_mining_config = config
.merge_mining_config
.ok_or_else(|| "Merge mining config settings are missing".to_string())?;
let proxy_host_address = multiaddr_to_socketaddr(&merge_mining_config.proxy_host_address)
.map_err(|e| format!("Invalid proxy_host_address: {}", e))?;
let grpc_base_node_address = multiaddr_to_socketaddr(&merge_mining_config.base_node_grpc_address)
.map_err(|e| format!("Invalid base_node_grpc_address: {}", e))?;
let grpc_console_wallet_address = multiaddr_to_socketaddr(&merge_mining_config.wallet_grpc_address)
Expand All @@ -94,13 +97,35 @@ impl TryFrom<GlobalConfig> for MergeMiningProxyConfig {
monerod_use_auth: merge_mining_config.monerod_use_auth,
grpc_base_node_address,
grpc_console_wallet_address,
proxy_host_address: merge_mining_config.proxy_host_address,
proxy_submit_to_origin: config.proxy_submit_to_origin,
wait_for_initial_sync_at_startup: config.wait_for_initial_sync_at_startup,
proxy_host_address,
proxy_submit_to_origin: merge_mining_config.proxy_submit_to_origin,
wait_for_initial_sync_at_startup: merge_mining_config.wait_for_initial_sync_at_startup,
})
}
}

impl Display for MergeMiningProxyConfig {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
writeln!(
f,
"Configuration:\n network ({})\n proxy_host_address ({})\n grpc_base_node_address ({})\n \
grpc_console_wallet_address ({})\n proxy_submit_to_origin ({})\n wait_for_initial_sync_at_startup \
({})\n monerod_url ({:?})\n monerod_password ({})\n monerod_username ({})\n monerod_use_auth ({})",
self.network,
self.proxy_host_address,
self.grpc_base_node_address,
self.grpc_console_wallet_address,
self.proxy_submit_to_origin,
self.wait_for_initial_sync_at_startup,
self.monerod_url,
self.monerod_password,
self.monerod_username,
self.monerod_use_auth
)?;
Ok(())
}
}

#[derive(Debug, Clone)]
pub struct MergeMiningProxyService {
inner: InnerService,
Expand All @@ -114,6 +139,7 @@ impl MergeMiningProxyService {
wallet_client: grpc::wallet_client::WalletClient<tonic::transport::Channel>,
block_templates: BlockTemplateRepository,
) -> Self {
debug!(target: LOG_TARGET, "Config: {:?}", config);
Self {
inner: InnerService {
config,
Expand Down Expand Up @@ -305,6 +331,12 @@ impl InnerService {
if !self.config.proxy_submit_to_origin {
// self-select related, do not change.
json_resp = json_rpc::default_block_accept_response(request["id"].as_i64());
trace!(
target: LOG_TARGET,
"pool merged mining proxy_submit_to_origin({}) json_resp: {}",
self.config.proxy_submit_to_origin,
json_resp
);
} else {
json_resp = json_rpc::success_response(
request["id"].as_i64(),
Expand Down Expand Up @@ -348,7 +380,12 @@ impl InnerService {
self.block_templates.remove_outdated().await;
}

debug!(target: LOG_TARGET, "Sending submit_block response {}", json_resp);
debug!(
target: LOG_TARGET,
"Sending submit_block response (proxy_submit_to_origin({})): {}",
self.config.proxy_submit_to_origin,
json_resp
);
Ok(proxy::into_response(parts, &json_resp))
}

Expand Down Expand Up @@ -605,20 +642,41 @@ impl InnerService {
}
}

for monerod_url in self.config.monerod_url.iter() {
let uri = format!("{}{}", monerod_url, uri.path()).parse::<Url>()?;
match reqwest::get(uri.clone()).await {
Ok(_) => {
let mut lock = self.last_available_server.write().expect("Write lock should not fail");
*lock = Some(monerod_url.to_string());
info!(target: LOG_TARGET, "Monerod server available: {:?}", uri.clone());
return Ok(uri);
},
Err(_) => {
warn!(target: LOG_TARGET, "Monerod server unavailable: {:?}", uri);
continue;
},
let current_url = {
let lock = self
.last_available_server
.read()
.expect("Read lock should not fail")
.clone();
match lock {
Some(url) => url,
None => "".to_string(),
}
};
let mut iter = self.config.monerod_url.iter();
let _ = iter.find(|&x| x == &current_url);
let mut count = 0;
loop {
count += 1;
if count > self.config.monerod_url.len() * 2 {
break;
}
if let Some(next_url) = iter.next() {
let uri = format!("{}{}", next_url, uri.path()).parse::<Url>()?;
match reqwest::get(uri.clone()).await {
Ok(_) => {
let mut lock = self.last_available_server.write().expect("Write lock should not fail");
*lock = Some(next_url.to_string());
info!(target: LOG_TARGET, "Monerod server available: {:?}", uri.clone());
return Ok(uri);
},
Err(_) => {
warn!(target: LOG_TARGET, "Monerod server unavailable: {:?}", uri);
},
}
} else {
iter = self.config.monerod_url.iter();
};
}

Err(MmProxyError::ServersUnavailable)
Expand Down Expand Up @@ -666,12 +724,19 @@ impl InnerService {
let body: Bytes = request.body().clone();
let json = json::from_slice::<json::Value>(&body[..]).unwrap_or_default();
if let Some(method) = json["method"].as_str() {
trace!(target: LOG_TARGET, "json[\"method\"]: {}", method);
match method {
"submitblock" | "submit_block" => {
submit_block = true;
},
_ => {},
}
trace!(
target: LOG_TARGET,
"submitblock({}), proxy_submit_to_origin({})",
submit_block,
self.config.proxy_submit_to_origin
);
}

let json_response;
Expand Down
67 changes: 36 additions & 31 deletions common/config/presets/merge_mining_proxy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,52 @@
# #
########################################################################################################################

[merge_mining_proxy.dibbler]
[merge_mining_proxy]

# URL to monerod
monerod_url = [ # stagenet
"http://stagenet.xmr-tw.org:38081",
"http://stagenet.community.xmr.to:38081",
"http://monero-stagenet.exan.tech:38081",
"http://xmr-lux.boldsuck.org:38081",
"http://singapore.node.xmr.pm:38081",
]
#monerod_url = [ # mainnet
# "http://18.132.124.81:18081",
# "http://xmr.support:18081",
# "http://node1.xmr-tw.org:18081",
# "http://xmr.nthrow.nyc:18081",
#]
# Address of the tari_merge_mining_proxy application. (default = "127.0.0.1:7878")
#proxy_host_address = "/ip4/127.0.0.1/tcp/7878"

# GRPC address of base node. (default = "/ip4/127.0.0.1/tcp/18142")
#base_node_grpc_address = "/ip4/127.0.0.1/tcp/18142"

# Address of the tari_merge_mining_proxy application
proxy_host_address = "127.0.0.1:7878"
# GRPC address of console wallet. (default = "/ip4/127.0.0.1/tcp/18143")
#wallet_grpc_address = "/ip4/127.0.0.1/tcp/18143"

# In sole merged mining, the block solution is usually submitted to the Monero blockchain
# (monerod) as well as to the Tari blockchain, then this setting should be "true". With pool
# merged mining, there is no sense in submitting the solution to the Monero blockchain as the
# pool does that, then this setting should be "false". (default = true).
proxy_submit_to_origin = true

# If authentication is being used for curl
monerod_use_auth = false

# Username for curl
monerod_username = ""

# Password for curl
monerod_password = ""
#proxy_submit_to_origin = true

# The merge mining proxy can either wait for the base node to achieve initial sync at startup before it enables mining,
# or not. If merge mining starts before the base node has achieved initial sync, those Tari mined blocks will not be
# accepted. (Default value = true; will wait for base node initial sync).
#wait_for_initial_sync_at_startup = true

[merge_mining_proxy]
monerod_use_auth = false
monerod_username = ""
monerod_password = ""
[merge_mining_proxy.dibbler]

# URL to monerod (default = stagenet)
#monerod_url = [ # stagenet
# "http://stagenet.xmr-tw.org:38081",
# "http://stagenet.community.xmr.to:38081",
# "http://monero-stagenet.exan.tech:38081",
# "http://xmr-lux.boldsuck.org:38081",
# "http://singapore.node.xmr.pm:38081",
#]
#monerod_url = [ # mainnet
# "http://xmr.support:18081",
# "http://node1.xmr-tw.org:18081",
# "http://xmr.nthrow.nyc:18081",
# "http://node.xmrig.com:18081",
# "http://monero.exan.tech:18081",
# "http://18.132.124.81:18081",
#]

# If authentication is being used for curl. (default = false).
#monerod_use_auth = false

# Username for curl. (default = "").
#monerod_username = ""

# Password for curl. (default = "").
#monerod_password = ""
Loading

0 comments on commit 6bf8057

Please sign in to comment.