Skip to content

Commit d3ea51f

Browse files
feat: improve monerod offline handling (#6793)
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 -->
1 parent 9e3ef5b commit d3ea51f

File tree

7 files changed

+232
-144
lines changed

7 files changed

+232
-144
lines changed

applications/minotari_merge_mining_proxy/src/config.rs

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ use tari_comms::multiaddr::Multiaddr;
3636
use tari_core::transactions::transaction_components::RangeProofType;
3737

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

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

118119
impl Default for MergeMiningProxyConfig {
119120
fn default() -> Self {
121+
let mut monerod_servers = TARI_MONEROD_SERVERS.iter().map(|v| v.to_string()).collect::<Vec<_>>();
122+
monerod_servers.append(&mut vec![
123+
"http://node.c3pool.org:18081".to_string(),
124+
"http://xmr-full.p2pool.uk:18089".to_string(),
125+
"http://monero.stackwallet.com:18081".to_string(),
126+
"http://xmr.support:18081".to_string(),
127+
"http://node1.xmr-tw.org:18081".to_string(),
128+
"http://monero-g2.hexhex.online:18081".to_string(),
129+
"http://137.220.120.19:18089".to_string(),
130+
"http://185.218.124.120:18489".to_string(),
131+
"http://185.218.124.120:18789".to_string(),
132+
"https://xmr-de-2.boldsuck.org:18081".to_string(),
133+
"http://46.32.46.171:18081".to_string(),
134+
"http://185.218.124.120:18089".to_string(),
135+
"http://185.218.124.120:18589".to_string(),
136+
"http://xmr-de-1.boldsuck.org:18081".to_string(),
137+
"http://185.218.124.120:18889".to_string(),
138+
"http://pinodexmr.hopto.org:18081".to_string(),
139+
"http://node.tincloud.eu:18081".to_string(),
140+
"http://183.6.24.33:18081".to_string(),
141+
"http://147.45.196.232:18089".to_string(),
142+
"http://h-helix.com:18089".to_string(),
143+
"http://185.218.124.120:18689".to_string(),
144+
"http://185.218.124.120:18289".to_string(),
145+
"https://node.tincloud.eu".to_string(),
146+
"https://xmr-de.boldsuck.org:18081".to_string(),
147+
"https://monero.booze.org".to_string(),
148+
"https://xmr.mailia.be:18088".to_string(),
149+
"https://xmr.lolfox.au".to_string(),
150+
"https://xmr1.doggett.tech:18089".to_string(),
151+
"https://node.icefiles.nz:18081".to_string(),
152+
"http://45.8.132.220:18089".to_string(),
153+
"http://82.147.85.13:18089".to_string(),
154+
]);
120155
Self {
121156
override_from: None,
122157
use_dynamic_fail_data: true,
123158
monero_fail_url: MONERO_FAIL_MAINNET_URL.into(),
124-
monerod_url: StringList::from(vec![
125-
"http://node.c3pool.org:18081".to_string(),
126-
"http://xmr-full.p2pool.uk:18089".to_string(),
127-
"http://monero.stackwallet.com:18081".to_string(),
128-
"http://xmr.support:18081".to_string(),
129-
"https://xmr-01.tari.com".to_string(),
130-
"http://node1.xmr-tw.org:18081".to_string(),
131-
"http://monero-g2.hexhex.online:18081".to_string(),
132-
"http://137.220.120.19:18089".to_string(),
133-
"http://185.218.124.120:18489".to_string(),
134-
"http://185.218.124.120:18789".to_string(),
135-
"https://xmr-de-2.boldsuck.org:18081".to_string(),
136-
"http://46.32.46.171:18081".to_string(),
137-
"http://185.218.124.120:18089".to_string(),
138-
"http://185.218.124.120:18589".to_string(),
139-
"http://xmr-de-1.boldsuck.org:18081".to_string(),
140-
"http://185.218.124.120:18889".to_string(),
141-
"http://pinodexmr.hopto.org:18081".to_string(),
142-
"http://node.tincloud.eu:18081".to_string(),
143-
"http://183.6.24.33:18081".to_string(),
144-
"http://147.45.196.232:18089".to_string(),
145-
"http://h-helix.com:18089".to_string(),
146-
"http://185.218.124.120:18689".to_string(),
147-
"http://185.218.124.120:18289".to_string(),
148-
"https://node.tincloud.eu".to_string(),
149-
"https://xmr-de.boldsuck.org:18081".to_string(),
150-
"https://monero.booze.org".to_string(),
151-
"https://xmr.mailia.be:18088".to_string(),
152-
"https://xmr.lolfox.au".to_string(),
153-
"https://xmr1.doggett.tech:18089".to_string(),
154-
"https://node.icefiles.nz:18081".to_string(),
155-
"http://45.8.132.220:18089".to_string(),
156-
"http://82.147.85.13:18089".to_string(),
157-
]),
159+
monerod_url: StringList::from(monerod_servers),
158160
monerod_username: String::new(),
159161
monerod_password: String::new(),
160162
monerod_use_auth: false,

applications/minotari_merge_mining_proxy/src/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ pub enum MmProxyError {
124124
MaxSizeBytesError(#[from] MaxSizeBytesError),
125125
#[error("Max sized vector error: {0}")]
126126
MaxSizeVecError(#[from] MaxSizeVecError),
127+
#[error("Monerod timeout: {0}")]
128+
MonerodTimeout(String),
127129
}
128130

129131
impl From<tonic::Status> for MmProxyError {

applications/minotari_merge_mining_proxy/src/monero_fail.rs

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ pub async fn get_monerod_info(
6565
number_of_entries: usize,
6666
connection_test_timeout: Duration,
6767
monero_fail_url: &str,
68+
tari_monerod_entries: Vec<MonerodEntry>,
6869
) -> Result<Vec<MonerodEntry>, MmProxyError> {
6970
let document = get_monerod_html(monero_fail_url).await?;
7071
let table_structure = extract_table_structure(&document);
@@ -216,19 +217,25 @@ pub async fn get_monerod_info(
216217
});
217218
// Only retain non-tor and non-i2p nodes
218219
entries.retain(|entry| entry.address_type != *"tor" && entry.address_type != *"i2p");
219-
// Give preference to nodes with the best height
220-
entries.sort_by(|a, b| b.height.cmp(&a.height));
221-
// Determine connection times - use slightly more nodes than requested
222-
entries.truncate(number_of_entries + 10);
223-
224-
let entries = order_and_select_monerod_info(number_of_entries, connection_test_timeout, &entries).await?;
225-
226220
if entries.is_empty() {
227221
return Err(MmProxyError::HtmlParseError(
228222
"No public monero servers available".to_string(),
229223
));
230224
}
231-
Ok(entries)
225+
// Give preference to nodes with the best height - use slightly more nodes than requested
226+
entries.sort_by(|a, b| b.height.cmp(&a.height));
227+
entries.truncate(number_of_entries + 10);
228+
// Insert Tari monerod entries at the beginning
229+
let mut pre_ordered_entries = tari_monerod_entries;
230+
pre_ordered_entries.extend(entries);
231+
// Dedup entries (if the Tari monerod entries are already in the list)
232+
pre_ordered_entries.sort_by(|a, b| a.url.cmp(&b.url));
233+
pre_ordered_entries.dedup_by(|a, b| a.url == b.url);
234+
// Determine connection times
235+
let ordered_entries =
236+
order_and_select_monerod_info(number_of_entries, connection_test_timeout, &pre_ordered_entries).await?;
237+
238+
Ok(ordered_entries)
232239
}
233240

234241
pub async fn order_and_select_monerod_info(
@@ -242,13 +249,9 @@ pub async fn order_and_select_monerod_info(
242249
let start = std::time::Instant::now();
243250
if (timeout(connection_test_timeout, reqwest::get(url.clone())).await).is_ok() {
244251
entry.response_time = Some(start.elapsed());
245-
debug!(
246-
target: LOG_TARGET, "Response time '{:.2?}' for Monerod server at: {}",
247-
entry.response_time, url.as_str()
248-
);
249252
} else {
250253
debug!(
251-
target: LOG_TARGET, "Response time 'n/a' for Monerod server at: {}, timed out",
254+
target: LOG_TARGET, "Response for Monerod server at {} timed out",
252255
url.as_str()
253256
);
254257
}
@@ -264,6 +267,14 @@ pub async fn order_and_select_monerod_info(
264267
});
265268
// Truncate to the requested number of entries
266269
entries.truncate(number_of_entries);
270+
for entry in &mut entries {
271+
if let Ok(url) = format!("{}/getheight", entry.url).parse::<Url>() {
272+
debug!(
273+
target: LOG_TARGET, "Response time '{:.2?}' for Monerod server at: {}",
274+
entry.response_time, url.as_str()
275+
);
276+
}
277+
}
267278
Ok(entries)
268279
}
269280

@@ -345,14 +356,22 @@ mod test {
345356
order_and_select_monerod_info,
346357
MonerodEntry,
347358
},
359+
run_merge_miner::get_tari_monerod_entries,
348360
};
349361

350362
async fn get_monerod_info_if_online(
351363
number_of_entries: usize,
352364
connection_test_timeout: Duration,
353365
monero_fail_url: &str,
354366
) -> Vec<MonerodEntry> {
355-
match get_monerod_info(number_of_entries, connection_test_timeout, monero_fail_url).await {
367+
match get_monerod_info(
368+
number_of_entries,
369+
connection_test_timeout,
370+
monero_fail_url,
371+
get_tari_monerod_entries(monero_fail_url),
372+
)
373+
.await
374+
{
356375
Ok(val) => val,
357376
Err(HtmlParseError(val)) => {
358377
if val.contains("No public monero servers available") {

0 commit comments

Comments
 (0)