Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fix merge mining proxy pool mining #3814

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
101 changes: 87 additions & 14 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 All @@ -122,7 +148,8 @@ impl MergeMiningProxyService {
base_node_client,
wallet_client,
initial_sync_achieved: Arc::new(AtomicBool::new(false)),
last_available_server: Arc::new(RwLock::new(None)),
current_monerod_server: Arc::new(RwLock::new(None)),
last_assigned_monerod_server: Arc::new(RwLock::new(None)),
},
}
}
Expand Down Expand Up @@ -189,7 +216,8 @@ struct InnerService {
base_node_client: grpc::base_node_client::BaseNodeClient<tonic::transport::Channel>,
wallet_client: grpc::wallet_client::WalletClient<tonic::transport::Channel>,
initial_sync_achieved: Arc<AtomicBool>,
last_available_server: Arc<RwLock<Option<String>>>,
current_monerod_server: Arc<RwLock<Option<String>>>,
last_assigned_monerod_server: Arc<RwLock<Option<String>>>,
}

impl InnerService {
Expand Down Expand Up @@ -305,6 +333,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 +382,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 @@ -595,7 +634,7 @@ impl InnerService {
async fn get_fully_qualified_monerod_url(&self, uri: &Uri) -> Result<Url, MmProxyError> {
{
let lock = self
.last_available_server
.current_monerod_server
.read()
.expect("Read lock should not fail")
.clone();
Expand All @@ -605,18 +644,45 @@ impl InnerService {
}
}

for monerod_url in self.config.monerod_url.iter() {
let uri = format!("{}{}", monerod_url, uri.path()).parse::<Url>()?;
let last_used_url = {
let lock = self
.last_assigned_monerod_server
.read()
.expect("Read lock should not fail")
.clone();
match lock {
Some(url) => url,
None => "".to_string(),
}
};

// Query the list twice before giving up, starting after the last used entry
let pos = if let Some(index) = self.config.monerod_url.iter().position(|x| x == &last_used_url) {
index
} else {
0
};
let (left, right) = self.config.monerod_url.split_at(pos);
let left = left.to_vec();
let right = right.to_vec();
let iter = right.iter().chain(left.iter()).chain(right.iter()).chain(left.iter());

for next_url in iter {
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(monerod_url.to_string());
let mut lock = self.current_monerod_server.write().expect("Write lock should not fail");
*lock = Some(next_url.to_string());
let mut lock = self
.last_assigned_monerod_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);
continue;
},
}
}
Expand Down Expand Up @@ -666,12 +732,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 Expand Up @@ -812,8 +885,8 @@ impl InnerService {
Ok(response)
},
Err(e) => {
// Monero Server encountered a problem processing the request, reset the last_available_server
let mut lock = self.last_available_server.write().expect("Write lock should not fail");
// Monero Server encountered a problem processing the request, reset the current monerod server
let mut lock = self.current_monerod_server.write().expect("Write lock should not fail");
*lock = None;
Err(e)
},
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