Skip to content

Commit

Permalink
feat: improve monerod offline handling (#6793)
Browse files Browse the repository at this point in the history
Description
---
- Improved monerod offline handling:
  - when static responses need to be used;
  - consistent timeouts for acquiring a new monerod server;
  - consistent timeouts when waiting for a monerod response;
- improved logic for consecutive calls to monerod when another process
is busy acquiring a new monerod server.
- Added the tari monerod server(s) to the monerofail list.

Closes #6791

Motivation and Context
---
See #6791

How Has This Been Tested?
---
System-level testing

What process can a PR reviewer use to test or verify this change?
---
Code review
System-level testing

<!-- Checklist -->
<!-- 1. Is the title of your PR in the form that would make nice release
notes? The title, excluding the conventional commit
tag, will be included exactly as is in the CHANGELOG, so please think
about it carefully. -->


Breaking Changes
---

- [x] None
- [ ] Requires data directory on base node to be deleted
- [ ] Requires hard fork
- [ ] Other - Please specify

<!-- Does this include a breaking change? If so, include this line as a
footer -->
<!-- BREAKING CHANGE: Description what the user should do, e.g. delete a
database, resync the chain -->
  • Loading branch information
hansieodendaal authored Feb 7, 2025
1 parent 9e3ef5b commit d3ea51f
Show file tree
Hide file tree
Showing 7 changed files with 232 additions and 144 deletions.
72 changes: 37 additions & 35 deletions applications/minotari_merge_mining_proxy/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ use tari_comms::multiaddr::Multiaddr;
use tari_core::transactions::transaction_components::RangeProofType;

// The default Monero fail URL for mainnet
const MONERO_FAIL_MAINNET_URL: &str = "https://monero.fail/?chain=monero&network=mainnet&all=true";
pub(crate) const MONERO_FAIL_MAINNET_URL: &str = "https://monero.fail/?chain=monero&network=mainnet&all=true";
pub(crate) const TARI_MONEROD_SERVERS: [&str; 1] = ["https://xmr-01.tari.com"];

#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
Expand Down Expand Up @@ -117,44 +118,45 @@ pub(crate) enum MonerodFallback {

impl Default for MergeMiningProxyConfig {
fn default() -> Self {
let mut monerod_servers = TARI_MONEROD_SERVERS.iter().map(|v| v.to_string()).collect::<Vec<_>>();
monerod_servers.append(&mut vec![
"http://node.c3pool.org:18081".to_string(),
"http://xmr-full.p2pool.uk:18089".to_string(),
"http://monero.stackwallet.com:18081".to_string(),
"http://xmr.support:18081".to_string(),
"http://node1.xmr-tw.org:18081".to_string(),
"http://monero-g2.hexhex.online:18081".to_string(),
"http://137.220.120.19:18089".to_string(),
"http://185.218.124.120:18489".to_string(),
"http://185.218.124.120:18789".to_string(),
"https://xmr-de-2.boldsuck.org:18081".to_string(),
"http://46.32.46.171:18081".to_string(),
"http://185.218.124.120:18089".to_string(),
"http://185.218.124.120:18589".to_string(),
"http://xmr-de-1.boldsuck.org:18081".to_string(),
"http://185.218.124.120:18889".to_string(),
"http://pinodexmr.hopto.org:18081".to_string(),
"http://node.tincloud.eu:18081".to_string(),
"http://183.6.24.33:18081".to_string(),
"http://147.45.196.232:18089".to_string(),
"http://h-helix.com:18089".to_string(),
"http://185.218.124.120:18689".to_string(),
"http://185.218.124.120:18289".to_string(),
"https://node.tincloud.eu".to_string(),
"https://xmr-de.boldsuck.org:18081".to_string(),
"https://monero.booze.org".to_string(),
"https://xmr.mailia.be:18088".to_string(),
"https://xmr.lolfox.au".to_string(),
"https://xmr1.doggett.tech:18089".to_string(),
"https://node.icefiles.nz:18081".to_string(),
"http://45.8.132.220:18089".to_string(),
"http://82.147.85.13:18089".to_string(),
]);
Self {
override_from: None,
use_dynamic_fail_data: true,
monero_fail_url: MONERO_FAIL_MAINNET_URL.into(),
monerod_url: StringList::from(vec![
"http://node.c3pool.org:18081".to_string(),
"http://xmr-full.p2pool.uk:18089".to_string(),
"http://monero.stackwallet.com:18081".to_string(),
"http://xmr.support:18081".to_string(),
"https://xmr-01.tari.com".to_string(),
"http://node1.xmr-tw.org:18081".to_string(),
"http://monero-g2.hexhex.online:18081".to_string(),
"http://137.220.120.19:18089".to_string(),
"http://185.218.124.120:18489".to_string(),
"http://185.218.124.120:18789".to_string(),
"https://xmr-de-2.boldsuck.org:18081".to_string(),
"http://46.32.46.171:18081".to_string(),
"http://185.218.124.120:18089".to_string(),
"http://185.218.124.120:18589".to_string(),
"http://xmr-de-1.boldsuck.org:18081".to_string(),
"http://185.218.124.120:18889".to_string(),
"http://pinodexmr.hopto.org:18081".to_string(),
"http://node.tincloud.eu:18081".to_string(),
"http://183.6.24.33:18081".to_string(),
"http://147.45.196.232:18089".to_string(),
"http://h-helix.com:18089".to_string(),
"http://185.218.124.120:18689".to_string(),
"http://185.218.124.120:18289".to_string(),
"https://node.tincloud.eu".to_string(),
"https://xmr-de.boldsuck.org:18081".to_string(),
"https://monero.booze.org".to_string(),
"https://xmr.mailia.be:18088".to_string(),
"https://xmr.lolfox.au".to_string(),
"https://xmr1.doggett.tech:18089".to_string(),
"https://node.icefiles.nz:18081".to_string(),
"http://45.8.132.220:18089".to_string(),
"http://82.147.85.13:18089".to_string(),
]),
monerod_url: StringList::from(monerod_servers),
monerod_username: String::new(),
monerod_password: String::new(),
monerod_use_auth: false,
Expand Down
2 changes: 2 additions & 0 deletions applications/minotari_merge_mining_proxy/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ pub enum MmProxyError {
MaxSizeBytesError(#[from] MaxSizeBytesError),
#[error("Max sized vector error: {0}")]
MaxSizeVecError(#[from] MaxSizeVecError),
#[error("Monerod timeout: {0}")]
MonerodTimeout(String),
}

impl From<tonic::Status> for MmProxyError {
Expand Down
47 changes: 33 additions & 14 deletions applications/minotari_merge_mining_proxy/src/monero_fail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pub async fn get_monerod_info(
number_of_entries: usize,
connection_test_timeout: Duration,
monero_fail_url: &str,
tari_monerod_entries: Vec<MonerodEntry>,
) -> Result<Vec<MonerodEntry>, MmProxyError> {
let document = get_monerod_html(monero_fail_url).await?;
let table_structure = extract_table_structure(&document);
Expand Down Expand Up @@ -216,19 +217,25 @@ pub async fn get_monerod_info(
});
// Only retain non-tor and non-i2p nodes
entries.retain(|entry| entry.address_type != *"tor" && entry.address_type != *"i2p");
// Give preference to nodes with the best height
entries.sort_by(|a, b| b.height.cmp(&a.height));
// Determine connection times - use slightly more nodes than requested
entries.truncate(number_of_entries + 10);

let entries = order_and_select_monerod_info(number_of_entries, connection_test_timeout, &entries).await?;

if entries.is_empty() {
return Err(MmProxyError::HtmlParseError(
"No public monero servers available".to_string(),
));
}
Ok(entries)
// Give preference to nodes with the best height - use slightly more nodes than requested
entries.sort_by(|a, b| b.height.cmp(&a.height));
entries.truncate(number_of_entries + 10);
// Insert Tari monerod entries at the beginning
let mut pre_ordered_entries = tari_monerod_entries;
pre_ordered_entries.extend(entries);
// Dedup entries (if the Tari monerod entries are already in the list)
pre_ordered_entries.sort_by(|a, b| a.url.cmp(&b.url));
pre_ordered_entries.dedup_by(|a, b| a.url == b.url);
// Determine connection times
let ordered_entries =
order_and_select_monerod_info(number_of_entries, connection_test_timeout, &pre_ordered_entries).await?;

Ok(ordered_entries)
}

pub async fn order_and_select_monerod_info(
Expand All @@ -242,13 +249,9 @@ pub async fn order_and_select_monerod_info(
let start = std::time::Instant::now();
if (timeout(connection_test_timeout, reqwest::get(url.clone())).await).is_ok() {
entry.response_time = Some(start.elapsed());
debug!(
target: LOG_TARGET, "Response time '{:.2?}' for Monerod server at: {}",
entry.response_time, url.as_str()
);
} else {
debug!(
target: LOG_TARGET, "Response time 'n/a' for Monerod server at: {}, timed out",
target: LOG_TARGET, "Response for Monerod server at {} timed out",
url.as_str()
);
}
Expand All @@ -264,6 +267,14 @@ pub async fn order_and_select_monerod_info(
});
// Truncate to the requested number of entries
entries.truncate(number_of_entries);
for entry in &mut entries {
if let Ok(url) = format!("{}/getheight", entry.url).parse::<Url>() {
debug!(
target: LOG_TARGET, "Response time '{:.2?}' for Monerod server at: {}",
entry.response_time, url.as_str()
);
}
}
Ok(entries)
}

Expand Down Expand Up @@ -345,14 +356,22 @@ mod test {
order_and_select_monerod_info,
MonerodEntry,
},
run_merge_miner::get_tari_monerod_entries,
};

async fn get_monerod_info_if_online(
number_of_entries: usize,
connection_test_timeout: Duration,
monero_fail_url: &str,
) -> Vec<MonerodEntry> {
match get_monerod_info(number_of_entries, connection_test_timeout, monero_fail_url).await {
match get_monerod_info(
number_of_entries,
connection_test_timeout,
monero_fail_url,
get_tari_monerod_entries(monero_fail_url),
)
.await
{
Ok(val) => val,
Err(HtmlParseError(val)) => {
if val.contains("No public monero servers available") {
Expand Down
Loading

0 comments on commit d3ea51f

Please sign in to comment.