Skip to content

Commit

Permalink
Merge branch 'development' into comms-peer-manager-signed-peers
Browse files Browse the repository at this point in the history
  • Loading branch information
sdbondi authored Dec 2, 2021
2 parents 37210a0 + c53be9b commit aa5439a
Show file tree
Hide file tree
Showing 10 changed files with 247 additions and 170 deletions.
49 changes: 39 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ they are not enabled already:
```
```
[base_node.weatherwax]
transport = "tor"
transpo*_r_*t = "tor"
allow_test_addresses = false
grpc_enabled = true
grpc_base_node_address = "127.0.0.1:18142"
Expand All @@ -627,7 +627,14 @@ And then depending on if you are using solo mining or self-select mining you wil
- For the Tari Merge Mining Proxy, under section **`merge_mining_proxy.weatherwax`**
```
[merge_mining_proxy.weatherwax]
monerod_url = "http://monero-stagenet.exan.tech:38081"
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",
]
proxy_host_address = "127.0.0.1:7878"
proxy_submit_to_origin = true
monerod_use_auth = false
Expand All @@ -640,7 +647,14 @@ And then depending on if you are using solo mining or self-select mining you wil
- For the Tari Merge Mining Proxy, under section **`merge_mining_proxy.weatherwax`**
```
[merge_mining_proxy.weatherwax]
monerod_url = "http://18.132.124.81:18081"
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",
]
proxy_host_address = "127.0.0.1:7878"
proxy_submit_to_origin = false
monerod_use_auth = false
Expand All @@ -651,8 +665,8 @@ And then depending on if you are using solo mining or self-select mining you wil
**Note:** The ports `7878`, `18142` and `18143` shown in the example above should not be in use by other processes. If
they are, choose different ports. You will need to update the ports in the steps below as well.

The `monerod_url` must be set to a valid address (`host:port`) for `monerod` that is running Monero mainnet (e.g.
`http://18.132.124.81:18081`) or stagenet (e.g. `http://monero-stagenet.exan.tech:38081`), which can be a
The `monerod_url` set must contain valid addresses (`host:port`) for `monerod` that is running Monero mainnet (e.g.
`["http://18.132.124.81:18081"]`) or stagenet (e.g. `["http://monero-stagenet.exan.tech:38081"]`), which can be a
[public node hosted by XMR.to](https://community.xmr.to/nodes.html), or to a local instance. To test if the
`monerod_url` address is working properly, try to paste `host:port/get_height` in an internet browser, for example:

Expand Down Expand Up @@ -688,7 +702,7 @@ in via the command line upon runtime.
being a subaddress. It is possible to do with the self-select configuration since the template is requested by the miner
with the wallet address of the pool.

###### Solo mining
###### Solo-mining

The [XMRig configuration wizard](https://xmrig.com/wizard) can be used to create a solo mining configuration file
in JSON format:
Expand Down Expand Up @@ -832,8 +846,19 @@ Monero wallet address:

```
# URL to monerod
#monerod_url = "http://18.132.124.81:18081" # mainnet
monerod_url = "http://monero-stagenet.exan.tech:38081" # stagenet
monerod_url = [ # mainnet
"http://18.132.124.81:18081",
"http://xmr.support:18081",
"http://node1.xmr-tw.org:18081",
"http://xmr.nthrow.nyc:18081",
]
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",
]
```

###### Runtime
Expand Down Expand Up @@ -891,8 +916,12 @@ The `monerod_url` field in the `config.toml` should be enabled for the mainnet v

```
# URL to monerod
monerod_url = "http://18.132.124.81:18081" # mainnet
#monerod_url = "http://monero-stagenet.exan.tech:38081" # stagenet
monerod_url = [ # mainnet
"http://18.132.124.81:18081",
"http://xmr.support:18081",
"http://node1.xmr-tw.org:18081",
"http://xmr.nthrow.nyc:18081",
]
```

###### Runtime
Expand Down
5 changes: 1 addition & 4 deletions applications/launchpad/docker_rig/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ services:
TARI_NETWORK: ${TARI_NETWORK}
TARI_BASE_NODE__WEATHERWAX__GRPC_BASE_NODE_ADDRESS: "/dns4/base_node/tcp/18142"
TARI_WALLET__GRPC_ADDRESS: "/dns4/wallet/tcp/18143"
TARI_MERGE_MINING_PROXY__WEATHERWAX__MONEROD_URL: ${TARI_MONEROD_URL:-http://monero-stagenet.exan.tech:38081}
TARI_MERGE_MINING_PROXY__WEATHERWAX__MONEROD_URL: ${TARI_MONEROD_URL:-["http://stagenet.community.xmr.to:38081","http://monero-stagenet.exan.tech:38081","http://stagenet.xmr-tw.org:38081","http://xmr-lux.boldsuck.org:38081","http://singapore.node.xmr.pm:38081"]}
TARI_MERGE_MINING_PROXY__WEATHERWAX__MONEROD_USERNAME: ${TARI_MONEROD_USERNAME}
TARI_MERGE_MINING_PROXY__WEATHERWAX__MONEROD_PASSWORD: ${TARI_MONEROD_PASSWORD}
TARI_MERGE_MINING_PROXY__WEATHERWAX__MONEROD_USE_AUTH: ${TARI_MONEROD_USE_AUTH:-0}
Expand All @@ -179,6 +179,3 @@ volumes:
# `docker run --rm -v $(pwd):/backup -v blockchain:/blockchain ubuntu tar czvf /backup/backup.tar.gz /blockchain`
blockchain:
monero-blockchain:



2 changes: 2 additions & 0 deletions applications/tari_merge_mining_proxy/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ pub enum MmProxyError {
InvalidHeaderValue(#[from] InvalidHeaderValue),
#[error("Block was lost due to a failed precondition, and should be retried")]
FailedPreconditionBlockLostRetry,
#[error("No reachable servers in configuration")]
ServersUnavailable,
}

impl From<tonic::Status> for MmProxyError {
Expand Down
109 changes: 74 additions & 35 deletions applications/tari_merge_mining_proxy/src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ use std::{
sync::{
atomic::{AtomicBool, Ordering},
Arc,
RwLock,
},
task::{Context, Poll},
time::Instant,
Expand All @@ -61,7 +62,7 @@ const TARI_CHAIN_ID: &str = "xtr";
#[derive(Debug, Clone)]
pub struct MergeMiningProxyConfig {
pub network: Network,
pub monerod_url: String,
pub monerod_url: Vec<String>,
pub monerod_username: String,
pub monerod_password: String,
pub monerod_use_auth: bool,
Expand Down Expand Up @@ -114,6 +115,7 @@ impl MergeMiningProxyService {
base_node_client,
wallet_client,
initial_sync_achieved: Arc::new(AtomicBool::new(false)),
last_available_server: Arc::new(RwLock::new(None)),
},
}
}
Expand All @@ -135,7 +137,7 @@ impl Service<Request<Body>> for MergeMiningProxyService {
let bytes = match proxy::read_body_until_end(request.body_mut()).await {
Ok(b) => b,
Err(err) => {
eprintln!("Method: Unknown, Failed to read request: {}", err);
eprintln!("Method: Unknown, Failed to read request: {:?}", err);
let resp = proxy::json_response(
StatusCode::BAD_REQUEST,
&json_rpc::standard_error_response(
Expand All @@ -153,8 +155,8 @@ impl Service<Request<Body>> for MergeMiningProxyService {
match inner.handle(&method_name, request).await {
Ok(resp) => Ok(resp),
Err(err) => {
error!(target: LOG_TARGET, "Error handling request: {}", err);
eprintln!("Method: {}, Failed to handle request: {}", method_name, err);
error!(target: LOG_TARGET, "Error handling request: {:?}", err);
eprintln!("Method: {}, Failed to handle request: {:?}", method_name, err);
Ok(proxy::json_response(
StatusCode::INTERNAL_SERVER_ERROR,
&json_rpc::standard_error_response(
Expand All @@ -180,6 +182,7 @@ 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>>>,
}

impl InnerService {
Expand Down Expand Up @@ -582,17 +585,44 @@ impl InnerService {
Ok(proxy::into_response(parts, &resp))
}

fn get_fully_qualified_monerod_url(&self, uri: &Uri) -> Result<Url, MmProxyError> {
let uri = format!("{}{}", self.config.monerod_url, uri.path()).parse::<Url>()?;
Ok(uri)
async fn get_fully_qualified_monerod_url(&self, uri: &Uri) -> Result<Url, MmProxyError> {
{
let lock = self
.last_available_server
.read()
.expect("Read lock should not fail")
.clone();
if let Some(server) = lock {
let uri = format!("{}{}", server, uri.path()).parse::<Url>()?;
return Ok(uri);
}
}

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;
},
}
}

Err(MmProxyError::ServersUnavailable)
}

/// Proxy a request received by this server to Monerod
async fn proxy_request_to_monerod(
&self,
request: Request<Bytes>,
) -> Result<(Request<Bytes>, Response<json::Value>), MmProxyError> {
let monerod_uri = self.get_fully_qualified_monerod_url(request.uri())?;
let monerod_uri = self.get_fully_qualified_monerod_url(request.uri()).await?;

let mut headers = request.headers().clone();
// Some public monerod setups (e.g. those that are reverse proxied by nginx) require the Host header.
Expand Down Expand Up @@ -744,34 +774,43 @@ impl InnerService {
.join(","),
);

let (request, monerod_resp) = self.proxy_request_to_monerod(request).await?;
// Any failed (!= 200 OK) responses from Monero are immediately returned to the requester
let monerod_status = monerod_resp.status();
if !monerod_status.is_success() {
// we dont break on xmrig returned error.
warn!(
target: LOG_TARGET,
"Monerod returned an error: {}",
monerod_resp.status()
);
println!(
"Method: {}, MoneroD Status: {}, Proxy Status: N/A, Response Time: {}ms",
method_name,
monerod_status,
start.elapsed().as_millis()
);
return Ok(monerod_resp.map(|json| json.to_string().into()));
}
match self.proxy_request_to_monerod(request).await {
Ok((request, monerod_resp)) => {
// Any failed (!= 200 OK) responses from Monero are immediately returned to the requester
let monerod_status = monerod_resp.status();
if !monerod_status.is_success() {
// we dont break on monerod returning an error code.
warn!(
target: LOG_TARGET,
"Monerod returned an error: {}",
monerod_resp.status()
);
println!(
"Method: {}, MoneroD Status: {}, Proxy Status: N/A, Response Time: {}ms",
method_name,
monerod_status,
start.elapsed().as_millis()
);
return Ok(monerod_resp.map(|json| json.to_string().into()));
}

let response = self.get_proxy_response(request, monerod_resp).await?;
println!(
"Method: {}, MoneroD Status: {}, Proxy Status: {}, Response Time: {}ms",
method_name,
monerod_status,
response.status(),
start.elapsed().as_millis()
);
Ok(response)
let response = self.get_proxy_response(request, monerod_resp).await?;
println!(
"Method: {}, MoneroD Status: {}, Proxy Status: {}, Response Time: {}ms",
method_name,
monerod_status,
response.status(),
start.elapsed().as_millis()
);
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");
*lock = None;
Err(e)
},
}
}
}

Expand Down
Loading

0 comments on commit aa5439a

Please sign in to comment.