diff --git a/Cargo.lock b/Cargo.lock index 86694d42ee..6717ff4a2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5133,6 +5133,7 @@ dependencies = [ "tari_app_grpc", "tari_app_utilities", "tari_common", + "tari_common_types", "tari_comms", "tari_core", "tari_crypto", diff --git a/applications/tari_merge_mining_proxy/Cargo.toml b/applications/tari_merge_mining_proxy/Cargo.toml index 72c6a0fb8d..ea22b06b8a 100644 --- a/applications/tari_merge_mining_proxy/Cargo.toml +++ b/applications/tari_merge_mining_proxy/Cargo.toml @@ -14,6 +14,7 @@ envlog = ["env_logger"] [dependencies] tari_app_grpc = { path = "../tari_app_grpc" } tari_common = { path = "../../common" } +tari_common_types = { path = "../../base_layer/common_types" } tari_comms = { path = "../../comms/core" } tari_core = { path = "../../base_layer/core", default-features = false, features = ["transactions"] } tari_app_utilities = { path = "../tari_app_utilities" } diff --git a/applications/tari_merge_mining_proxy/src/block_template_protocol.rs b/applications/tari_merge_mining_proxy/src/block_template_protocol.rs index 29a48e6f2f..d7ccc67a6e 100644 --- a/applications/tari_merge_mining_proxy/src/block_template_protocol.rs +++ b/applications/tari_merge_mining_proxy/src/block_template_protocol.rs @@ -25,7 +25,7 @@ use std::cmp; use log::*; -use tari_app_grpc::tari_rpc as grpc; +use tari_app_grpc::{authentication::ClientAuthenticationInterceptor, tari_rpc as grpc}; use tari_core::proof_of_work::{monero_rx, monero_rx::FixedByteArray, Difficulty}; use crate::{ @@ -39,13 +39,17 @@ const LOG_TARGET: &str = "tari_mm_proxy::proxy::block_template_protocol"; /// Structure holding grpc connections. pub struct BlockTemplateProtocol<'a> { base_node_client: &'a mut grpc::base_node_client::BaseNodeClient, - wallet_client: &'a mut grpc::wallet_client::WalletClient, + wallet_client: &'a mut grpc::wallet_client::WalletClient< + tonic::codegen::InterceptedService, + >, } impl<'a> BlockTemplateProtocol<'a> { pub fn new( base_node_client: &'a mut grpc::base_node_client::BaseNodeClient, - wallet_client: &'a mut grpc::wallet_client::WalletClient, + wallet_client: &'a mut grpc::wallet_client::WalletClient< + tonic::codegen::InterceptedService, + >, ) -> Self { Self { base_node_client, diff --git a/applications/tari_merge_mining_proxy/src/config.rs b/applications/tari_merge_mining_proxy/src/config.rs index 23549aab1e..0bffda2fa9 100644 --- a/applications/tari_merge_mining_proxy/src/config.rs +++ b/applications/tari_merge_mining_proxy/src/config.rs @@ -22,6 +22,7 @@ use serde::{Deserialize, Serialize}; use tari_common::{configuration::StringList, SubConfigPath}; +use tari_common_types::grpc_authentication::GrpcAuthentication; use tari_comms::multiaddr::Multiaddr; #[derive(Clone, Debug, Deserialize, Serialize)] @@ -41,6 +42,8 @@ pub struct MergeMiningProxyConfig { pub base_node_grpc_address: Multiaddr, /// The Tari console wallet's GRPC address pub console_wallet_grpc_address: Multiaddr, + /// GRPC authentication for console wallet + pub console_wallet_grpc_authentication: GrpcAuthentication, /// Address of the tari_merge_mining_proxy application pub listener_address: Multiaddr, /// In sole merged mining, the block solution is usually submitted to the Monero blockchain (monerod) as well as to @@ -69,6 +72,7 @@ impl Default for MergeMiningProxyConfig { monerod_use_auth: false, base_node_grpc_address: "/ip4/127.0.0.1/tcp/18142".parse().unwrap(), console_wallet_grpc_address: "/ip4/127.0.0.1/tcp/18143".parse().unwrap(), + console_wallet_grpc_authentication: GrpcAuthentication::default(), listener_address: "/ip4/127.0.0.1/tcp/18081".parse().unwrap(), submit_to_origin: true, wait_for_initial_sync_at_startup: true, diff --git a/applications/tari_merge_mining_proxy/src/error.rs b/applications/tari_merge_mining_proxy/src/error.rs index 92fc25651c..0d308d3bf4 100644 --- a/applications/tari_merge_mining_proxy/src/error.rs +++ b/applications/tari_merge_mining_proxy/src/error.rs @@ -26,10 +26,11 @@ use std::io; use hex::FromHexError; use hyper::header::InvalidHeaderValue; +use tari_app_grpc::authentication::BasicAuthError; use tari_common::{ConfigError, ConfigurationError}; use tari_core::{proof_of_work::monero_rx::MergeMineError, transactions::CoinbaseBuildError}; use thiserror::Error; -use tonic::transport; +use tonic::{codegen::http::uri::InvalidUri, transport}; #[derive(Debug, Error)] pub enum MmProxyError { @@ -42,6 +43,8 @@ pub enum MmProxyError { #[from] source: MergeMineError, }, + #[error("Invalid URI: {0}")] + InvalidUriError(#[from] InvalidUri), #[error("Reqwest error: {0}")] ReqwestError(#[from] reqwest::Error), #[error("Missing data:{0}")] @@ -50,6 +53,8 @@ pub enum MmProxyError { IoError(#[from] io::Error), #[error("Tonic transport error: {0}")] TonicTransportError(#[from] transport::Error), + #[error("Grpc authentication error: {0}")] + GRPCAuthenticationError(#[from] BasicAuthError), #[error("GRPC response did not contain the expected field: `{0}`")] GrpcResponseMissingField(&'static str), #[error("Hyper error: {0}")] diff --git a/applications/tari_merge_mining_proxy/src/main.rs b/applications/tari_merge_mining_proxy/src/main.rs index bb5ea7992d..a58230850d 100644 --- a/applications/tari_merge_mining_proxy/src/main.rs +++ b/applications/tari_merge_mining_proxy/src/main.rs @@ -34,6 +34,7 @@ mod test; use std::{ convert::Infallible, io::{stdout, Write}, + str::FromStr, }; use clap::Parser; @@ -42,12 +43,16 @@ use futures::future; use hyper::{service::make_service_fn, Server}; use log::*; use proxy::MergeMiningProxyService; -use tari_app_grpc::tari_rpc as grpc; +use tari_app_grpc::{authentication::ClientAuthenticationInterceptor, tari_rpc as grpc}; use tari_app_utilities::consts; use tari_common::{initialize_logging, load_configuration, DefaultConfigLoader}; use tari_comms::utils::multiaddr::multiaddr_to_socketaddr; use tari_core::proof_of_work::randomx_factory::RandomXFactory; use tokio::time::Duration; +use tonic::{ + codegen::InterceptedService, + transport::{Channel, Endpoint}, +}; use crate::{ block_template_data::BlockTemplateRepository, @@ -57,6 +62,24 @@ use crate::{ }; const LOG_TARGET: &str = "tari_mm_proxy::proxy"; +pub(crate) type WalletGrpcClient = + grpc::wallet_client::WalletClient>; + +async fn connect_wallet_with_authenticator(config: &MergeMiningProxyConfig) -> Result { + let wallet_addr = format!( + "http://{}", + multiaddr_to_socketaddr(&config.console_wallet_grpc_address)? + ); + info!(target: LOG_TARGET, "👛 Connecting to wallet at {}", wallet_addr); + let channel = Endpoint::from_str(&wallet_addr)?.connect().await?; + let wallet_conn = grpc::wallet_client::WalletClient::with_interceptor( + channel, + ClientAuthenticationInterceptor::create(&config.console_wallet_grpc_authentication)?, + ); + + Ok(wallet_conn) +} + #[tokio::main] async fn main() -> Result<(), anyhow::Error> { let terminal_title = format!("Tari Merge Mining Proxy - Version {}", consts::APP_VERSION); @@ -90,7 +113,7 @@ async fn main() -> Result<(), anyhow::Error> { let wallet = multiaddr_to_socketaddr(&config.console_wallet_grpc_address)?; info!(target: LOG_TARGET, "Connecting to wallet at {}", wallet); println!("Connecting to wallet at {}", wallet); - let wallet_client = grpc::wallet_client::WalletClient::connect(format!("http://{}", wallet)).await?; + let wallet_client = connect_wallet_with_authenticator(&config).await?; let listen_addr = multiaddr_to_socketaddr(&config.listener_address)?; let randomx_factory = RandomXFactory::new(config.max_randomx_vms); let xmrig_service = MergeMiningProxyService::new( diff --git a/applications/tari_merge_mining_proxy/src/proxy.rs b/applications/tari_merge_mining_proxy/src/proxy.rs index e67c7fbd76..667cb21320 100644 --- a/applications/tari_merge_mining_proxy/src/proxy.rs +++ b/applications/tari_merge_mining_proxy/src/proxy.rs @@ -54,6 +54,7 @@ use crate::{ common::{json_rpc, monero_rpc::CoreRpcErrorCode, proxy, proxy::convert_json_to_hyper_json_response}, config::MergeMiningProxyConfig, error::MmProxyError, + WalletGrpcClient, }; const LOG_TARGET: &str = "tari_mm_proxy::proxy"; @@ -72,7 +73,7 @@ impl MergeMiningProxyService { config: MergeMiningProxyConfig, http_client: reqwest::Client, base_node_client: grpc::base_node_client::BaseNodeClient, - wallet_client: grpc::wallet_client::WalletClient, + wallet_client: WalletGrpcClient, block_templates: BlockTemplateRepository, randomx_factory: RandomXFactory, ) -> Self { @@ -154,7 +155,7 @@ struct InnerService { block_templates: BlockTemplateRepository, http_client: reqwest::Client, base_node_client: grpc::base_node_client::BaseNodeClient, - wallet_client: grpc::wallet_client::WalletClient, + wallet_client: WalletGrpcClient, initial_sync_achieved: Arc, current_monerod_server: Arc>>, last_assigned_monerod_server: Arc>>, diff --git a/common/config/presets/f_merge_mining_proxy.toml b/common/config/presets/f_merge_mining_proxy.toml index 17935f2129..52bab71161 100644 --- a/common/config/presets/f_merge_mining_proxy.toml +++ b/common/config/presets/f_merge_mining_proxy.toml @@ -42,6 +42,9 @@ monerod_url = [# stagenet # The Tari console wallet's GRPC address. (default = "/ip4/127.0.0.1/tcp/18143") #console_wallet_grpc_address = "/ip4/127.0.0.1/tcp/18143" +# GRPC authentication for the Tari console wallet (default = "none") +#wallet_grpc_authentication = { username: "miner", password: "$argon..." } + # Address of the tari_merge_mining_proxy application. (default = "/ip4/127.0.0.1/tcp/18081") #listener_address = "/ip4/127.0.0.1/tcp/18081"