diff --git a/applications/tari_base_node/src/builder.rs b/applications/tari_base_node/src/builder.rs index ed83c953c5..bf1e6c8632 100644 --- a/applications/tari_base_node/src/builder.rs +++ b/applications/tari_base_node/src/builder.rs @@ -154,6 +154,10 @@ impl BaseNodeContext { .expect_handle::() .get_status_info_watch() } + + pub fn get_report_grpc_error(&self) -> bool { + self.config.base_node.report_grpc_error + } } /// Sets up and initializes the base node, creating the context and database diff --git a/applications/tari_base_node/src/config.rs b/applications/tari_base_node/src/config.rs index 0a491a8613..9aa8aad27a 100644 --- a/applications/tari_base_node/src/config.rs +++ b/applications/tari_base_node/src/config.rs @@ -106,6 +106,7 @@ pub struct BaseNodeConfig { pub metadata_auto_ping_interval: Duration, pub state_machine: BaseNodeStateMachineConfig, pub resize_terminal_on_startup: bool, + pub report_grpc_error: bool, } impl Default for BaseNodeConfig { @@ -136,6 +137,7 @@ impl Default for BaseNodeConfig { metadata_auto_ping_interval: Duration::from_secs(30), state_machine: Default::default(), resize_terminal_on_startup: true, + report_grpc_error: false, } } } diff --git a/applications/tari_base_node/src/grpc/base_node_grpc_server.rs b/applications/tari_base_node/src/grpc/base_node_grpc_server.rs index f7865ede48..991a85eb22 100644 --- a/applications/tari_base_node/src/grpc/base_node_grpc_server.rs +++ b/applications/tari_base_node/src/grpc/base_node_grpc_server.rs @@ -92,6 +92,7 @@ pub struct BaseNodeGrpcServer { software_updater: SoftwareUpdaterHandle, comms: CommsNode, liveness: LivenessHandle, + report_grpc_error: bool, } impl BaseNodeGrpcServer { @@ -105,8 +106,21 @@ impl BaseNodeGrpcServer { software_updater: ctx.software_updater(), comms: ctx.base_node_comms().clone(), liveness: ctx.liveness(), + report_grpc_error: ctx.get_report_grpc_error(), } } + + pub fn report_error_flag(&self) -> bool { + self.report_grpc_error + } +} + +pub fn report_error(report: bool, status: Status) -> Status { + if report { + status + } else { + Status::new(status.code(), "Error has occurred. Details are obscured.") + } } pub async fn get_heights( @@ -134,6 +148,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); let request = request.into_inner(); debug!( target: LOG_TARGET, @@ -147,10 +162,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { // Overflow safety: checked in get_heights let num_requested = end_height - start_height; if num_requested > GET_DIFFICULTY_MAX_HEIGHTS { - return Err(Status::invalid_argument(format!( - "Number of headers requested exceeds maximum. Expected less than {} but got {}", - GET_DIFFICULTY_MAX_HEIGHTS, num_requested - ))); + return Err(report_error( + report_error_flag, + Status::invalid_argument(format!( + "Number of headers requested exceeds maximum. Expected less than {} but got {}", + GET_DIFFICULTY_MAX_HEIGHTS, num_requested + )), + )); } let (mut tx, rx) = mpsc::channel(cmp::min(num_requested as usize, GET_DIFFICULTY_PAGE_SIZE)); @@ -168,17 +186,20 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Base node service error: {:?}", err,); let _ = tx - .send(Err(Status::internal("Internal error when fetching blocks"))) + .send(Err(report_error( + report_error_flag, + Status::internal("Internal error when fetching blocks"), + ))) .await; return; }, }; if headers.is_empty() { - let _network_difficulty_response = tx.send(Err(Status::invalid_argument(format!( - "No blocks found within range {} - {}", - start, end - )))); + let _network_difficulty_response = tx.send(Err(report_error( + report_error_flag, + Status::invalid_argument(format!("No blocks found within range {} - {}", start, end)), + ))); return; } @@ -228,6 +249,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); let _request = request.into_inner(); debug!(target: LOG_TARGET, "Incoming GRPC request for GetMempoolTransactions",); @@ -250,7 +272,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { target: LOG_TARGET, "Error sending converting transaction for GRPC: {}", e ); - match tx.send(Err(Status::internal("Error converting transaction"))).await { + match tx + .send(Err(report_error( + report_error_flag, + Status::internal("Error converting transaction"), + ))) + .await + { Ok(_) => (), Err(send_err) => { warn!(target: LOG_TARGET, "Error sending error to GRPC client: {}", send_err) @@ -272,7 +300,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { target: LOG_TARGET, "Error sending mempool transaction via GRPC: {}", err ); - match tx.send(Err(Status::unknown("Error sending data"))).await { + match tx + .send(Err(report_error( + report_error_flag, + Status::unknown("Error sending data"), + ))) + .await + { Ok(_) => (), Err(send_err) => { warn!(target: LOG_TARGET, "Error sending error to GRPC client: {}", send_err) @@ -291,6 +325,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); let request = request.into_inner(); debug!( target: LOG_TARGET, @@ -304,7 +339,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { let tip = match handler.get_metadata().await { Err(err) => { warn!(target: LOG_TARGET, "Error communicating with base node: {}", err,); - return Err(Status::internal(err.to_string())); + return Err(report_error(report_error_flag, Status::internal(err.to_string()))); }, Ok(data) => data.height_of_longest_chain(), }; @@ -389,7 +424,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Ok(_) => (), Err(err) => { warn!(target: LOG_TARGET, "Error sending block header via GRPC: {}", err); - match tx.send(Err(Status::unknown("Error sending data"))).await { + match tx + .send(Err(report_error( + report_error_flag, + Status::unknown("Error sending data"), + ))) + .await + { Ok(_) => (), Err(send_err) => { warn!(target: LOG_TARGET, "Error sending error to GRPC client: {}", send_err) @@ -410,6 +451,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); let request = request.into_inner(); debug!( target: LOG_TARGET, @@ -423,8 +465,12 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { .join(",") ); - let pub_key = PublicKey::from_bytes(&request.asset_public_key) - .map_err(|err| Status::invalid_argument(format!("Asset public Key is not a valid public key:{}", err)))?; + let pub_key = PublicKey::from_bytes(&request.asset_public_key).map_err(|err| { + report_error( + report_error_flag, + Status::invalid_argument(format!("Asset public Key is not a valid public key:{}", err)), + ) + })?; let mut handler = self.node_service.clone(); let (mut tx, rx) = mpsc::channel(50); @@ -438,7 +484,8 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Ok(tokens) => tokens, Err(err) => { warn!(target: LOG_TARGET, "Error communicating with base node: {:?}", err,); - let _get_token_response = tx.send(Err(Status::internal("Internal error"))); + let _get_token_response = + tx.send(Err(report_error(report_error_flag, Status::internal("Internal error")))); return; }, }; @@ -455,8 +502,10 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Ok(f) => f, Err(err) => { warn!(target: LOG_TARGET, "Could not convert features: {}", err,); - let _get_token_response = - tx.send(Err(Status::internal(format!("Could not convert features:{}", err)))); + let _get_token_response = tx.send(Err(report_error( + report_error_flag, + Status::internal(format!("Could not convert features:{}", err)), + ))); break; }, }; @@ -479,7 +528,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Ok(_) => (), Err(err) => { warn!(target: LOG_TARGET, "Error sending token via GRPC: {}", err); - match tx.send(Err(Status::unknown("Error sending data"))).await { + match tx + .send(Err(report_error( + report_error_flag, + Status::unknown("Error sending data"), + ))) + .await + { Ok(_) => (), Err(send_err) => { warn!(target: LOG_TARGET, "Error sending error to GRPC client: {}", send_err) @@ -497,16 +552,19 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); let request = request.into_inner(); let mut handler = self.node_service.clone(); let metadata = handler - .get_asset_metadata( - PublicKey::from_bytes(&request.asset_public_key) - .map_err(|_e| Status::invalid_argument("Not a valid asset public key"))?, - ) + .get_asset_metadata(PublicKey::from_bytes(&request.asset_public_key).map_err(|_e| { + report_error( + report_error_flag, + Status::invalid_argument("Not a valid asset public key"), + ) + })?) .await - .map_err(|e| Status::internal(e.to_string()))?; + .map_err(|e| report_error(report_error_flag, Status::internal(e.to_string())))?; if let Some(m) = metadata { let mined_height = m.mined_height; @@ -515,7 +573,12 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { PrunedOutput::Pruned { output_hash: _, witness_hash: _, - } => return Err(Status::not_found("Output has been pruned")), + } => { + return Err(report_error( + report_error_flag, + Status::not_found("Output has been pruned"), + )) + }, PrunedOutput::NotPruned { output } => { if let Some(ref asset) = output.features.asset { const ASSET_METADATA_TEMPLATE_ID: u32 = 1; @@ -556,9 +619,12 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { })); }, }; - // Err(Status::unknown("Could not find a matching arm")) + // Err(report_error(report_error_flag, Status::unknown("Could not find a matching arm"))) } else { - Err(Status::not_found("Could not find any utxo")) + Err(report_error( + report_error_flag, + Status::not_found("Could not find any utxo"), + )) } } @@ -566,6 +632,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); let request = request.into_inner(); let mut handler = self.node_service.clone(); @@ -582,7 +649,8 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Ok(outputs) => outputs, Err(err) => { warn!(target: LOG_TARGET, "Error communicating with base node: {:?}", err,); - let _list_assest_registrations_response = tx.send(Err(Status::internal("Internal error"))); + let _list_assest_registrations_response = + tx.send(Err(report_error(report_error_flag, Status::internal("Internal error")))); return; }, }; @@ -602,8 +670,10 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Ok(f) => f, Err(err) => { warn!(target: LOG_TARGET, "Could not convert features: {}", err,); - let _list_assest_registrations_response = - tx.send(Err(Status::internal(format!("Could not convert features:{}", err)))); + let _list_assest_registrations_response = tx.send(Err(report_error( + report_error_flag, + Status::internal(format!("Could not convert features:{}", err)), + ))); break; }, }; @@ -635,17 +705,28 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); let request = request.into_inner(); debug!(target: LOG_TARGET, "Incoming GRPC request for get new block template"); trace!(target: LOG_TARGET, "Request {:?}", request); let algo: PowAlgorithm = (u64::try_from( (request.algo) - .ok_or_else(|| Status::invalid_argument("No valid pow algo selected".to_string()))? + .ok_or_else(|| { + report_error( + report_error_flag, + Status::invalid_argument("No valid pow algo selected".to_string()), + ) + })? .pow_algo, ) .unwrap()) .try_into() - .map_err(|_| Status::invalid_argument("No valid pow algo selected".to_string()))?; + .map_err(|_| { + report_error( + report_error_flag, + Status::invalid_argument("No valid pow algo selected".to_string()), + ) + })?; let mut handler = self.node_service.clone(); let new_template = handler @@ -657,7 +738,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { "Could not get new block template: {}", e.to_string() ); - Status::internal(e.to_string()) + report_error(report_error_flag, Status::internal(e.to_string())) })?; let status_watch = self.state_machine_handle.get_status_info_watch(); @@ -669,7 +750,11 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { total_fees: new_template.total_fees.into(), algo: Some(tari_rpc::PowAlgo { pow_algo: pow }), }), - new_block_template: Some(new_template.try_into().map_err(Status::internal)?), + new_block_template: Some( + new_template + .try_into() + .map_err(|e| report_error(report_error_flag, Status::internal(e)))?, + ), initial_sync_achieved: (*status_watch.borrow()).bootstrapped, }; @@ -682,18 +767,22 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); let request = request.into_inner(); debug!(target: LOG_TARGET, "Incoming GRPC request for get new block"); - let block_template: NewBlockTemplate = request - .try_into() - .map_err(|s| Status::invalid_argument(format!("Invalid block template: {}", s)))?; + let block_template: NewBlockTemplate = request.try_into().map_err(|s| { + report_error( + report_error_flag, + Status::invalid_argument(format!("Invalid block template: {}", s)), + ) + })?; let mut handler = self.node_service.clone(); let new_block = match handler.get_new_block(block_template).await { Ok(b) => b, Err(CommsInterfaceError::ChainStorageError(ChainStorageError::InvalidArguments { message, .. })) => { - return Err(Status::invalid_argument(message)); + return Err(report_error(report_error_flag, Status::invalid_argument(message))); }, Err(CommsInterfaceError::ChainStorageError(ChainStorageError::CannotCalculateNonTipMmr(msg))) => { let status = Status::with_details( @@ -701,14 +790,18 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { msg, Bytes::from_static(b"CannotCalculateNonTipMmr"), ); - return Err(status); + return Err(report_error(report_error_flag, status)); }, - Err(e) => return Err(Status::internal(e.to_string())), + Err(e) => return Err(report_error(report_error_flag, Status::internal(e.to_string()))), }; // construct response let block_hash = new_block.hash(); let mining_hash = new_block.header.merged_mining_hash(); - let block: Option = Some(new_block.try_into().map_err(Status::internal)?); + let block: Option = Some( + new_block + .try_into() + .map_err(|e| report_error(report_error_flag, Status::internal(e)))?, + ); let response = tari_rpc::GetNewBlockResult { block_hash, @@ -770,9 +863,14 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); let request = request.into_inner(); - let block = Block::try_from(request) - .map_err(|e| Status::invalid_argument(format!("Failed to convert arguments. Invalid block: {:?}", e)))?; + let block = Block::try_from(request).map_err(|e| { + report_error( + report_error_flag, + Status::invalid_argument(format!("Failed to convert arguments. Invalid block: {:?}", e)), + ) + })?; let block_height = block.header.height; debug!(target: LOG_TARGET, "Miner submitted block: {}", block); info!( @@ -784,7 +882,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { let block_hash = handler .submit_block(block) .await - .map_err(|e| Status::internal(e.to_string()))?; + .map_err(|e| report_error(report_error_flag, Status::internal(e.to_string())))?; debug!( target: LOG_TARGET, @@ -833,12 +931,18 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); let request = request.into_inner(); let txn: Transaction = request .transaction - .ok_or_else(|| Status::invalid_argument("Transaction is empty"))? + .ok_or_else(|| report_error(report_error_flag, Status::invalid_argument("Transaction is empty")))? .try_into() - .map_err(|e| Status::invalid_argument(format!("Failed to convert arguments. Invalid transaction.{}", e)))?; + .map_err(|e| { + report_error( + report_error_flag, + Status::invalid_argument(format!("Failed to convert arguments. Invalid transaction.{}", e)), + ) + })?; debug!( target: LOG_TARGET, "Received SubmitTransaction request from client ({} kernels, {} outputs, {} inputs)", @@ -850,7 +954,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { let mut handler = self.mempool_service.clone(); let res = handler.submit_transaction(txn).await.map_err(|e| { error!(target: LOG_TARGET, "Error submitting:{}", e); - Status::internal(e.to_string()) + report_error(report_error_flag, Status::internal(e.to_string())) })?; let response = match res { TxStorageResponse::UnconfirmedPool => tari_rpc::SubmitTransactionResponse { @@ -877,12 +981,23 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); let request = request.into_inner(); let excess_sig: Signature = request .excess_sig - .ok_or_else(|| Status::invalid_argument("excess_sig not provided".to_string()))? + .ok_or_else(|| { + report_error( + report_error_flag, + Status::invalid_argument("excess_sig not provided".to_string()), + ) + })? .try_into() - .map_err(|_| Status::invalid_argument("excess_sig could not be converted".to_string()))?; + .map_err(|_| { + report_error( + report_error_flag, + Status::invalid_argument("excess_sig could not be converted".to_string()), + ) + })?; debug!( target: LOG_TARGET, "Received TransactionState request from client ({} excess_sig)", @@ -898,7 +1013,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { .await .map_err(|e| { error!(target: LOG_TARGET, "Error submitting query:{}", e); - Status::internal(e.to_string()) + report_error(report_error_flag, Status::internal(e.to_string())) })?; if !base_node_response.is_empty() { @@ -918,7 +1033,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { .await .map_err(|e| { error!(target: LOG_TARGET, "Error submitting query:{}", e); - Status::internal(e.to_string()) + report_error(report_error_flag, Status::internal(e.to_string())) })?; let response = match res { TxStorageResponse::UnconfirmedPool => tari_rpc::TransactionStateResponse { @@ -950,6 +1065,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, _request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); debug!(target: LOG_TARGET, "Incoming GRPC request for get all peers"); let peers = self @@ -957,7 +1073,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { .peer_manager() .all() .await - .map_err(|e| Status::unknown(e.to_string()))?; + .map_err(|e| report_error(report_error_flag, Status::unknown(e.to_string())))?; let peers: Vec = peers.into_iter().map(|p| p.into()).collect(); let (mut tx, rx) = mpsc::channel(peers.len()); task::spawn(async move { @@ -967,7 +1083,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Ok(_) => (), Err(err) => { warn!(target: LOG_TARGET, "Error sending peer via GRPC: {}", err); - match tx.send(Err(Status::unknown("Error sending data"))).await { + match tx + .send(Err(report_error( + report_error_flag, + Status::unknown("Error sending data"), + ))) + .await + { Ok(_) => (), Err(send_err) => { warn!(target: LOG_TARGET, "Error sending error to GRPC client: {}", send_err) @@ -987,6 +1109,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); let request = request.into_inner(); debug!( target: LOG_TARGET, @@ -995,7 +1118,10 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { let mut heights = request.heights; if heights.is_empty() { - return Err(Status::invalid_argument("heights cannot be empty")); + return Err(report_error( + report_error_flag, + Status::invalid_argument("heights cannot be empty"), + )); } heights.truncate(GET_BLOCKS_MAX_HEIGHTS); @@ -1031,17 +1157,24 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { block.header().height ); match tx - .send( - block - .try_into() - .map_err(|err| Status::internal(format!("Could not provide block: {}", err))), - ) + .send(block.try_into().map_err(|err| { + report_error( + report_error_flag, + Status::internal(format!("Could not provide block: {}", err)), + ) + })) .await { Ok(_) => (), Err(err) => { warn!(target: LOG_TARGET, "Error sending header via GRPC: {}", err); - match tx.send(Err(Status::unknown("Error sending data"))).await { + match tx + .send(Err(report_error( + report_error_flag, + Status::unknown("Error sending data"), + ))) + .await + { Ok(_) => (), Err(send_err) => { warn!(target: LOG_TARGET, "Error sending error to GRPC client: {}", send_err) @@ -1062,6 +1195,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, _request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); debug!(target: LOG_TARGET, "Incoming GRPC request for BN tip data"); let mut handler = self.node_service.clone(); @@ -1069,7 +1203,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { let meta = handler .get_metadata() .await - .map_err(|e| Status::internal(e.to_string()))?; + .map_err(|e| report_error(report_error_flag, Status::internal(e.to_string())))?; // Determine if we are bootstrapped let status_watch = self.state_machine_handle.get_status_info_watch(); @@ -1088,11 +1222,17 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); debug!(target: LOG_TARGET, "Incoming GRPC request for SearchKernels"); let request = request.into_inner(); let converted: Result, _> = request.signatures.into_iter().map(|s| s.try_into()).collect(); - let kernels = converted.map_err(|_| Status::internal("Failed to convert one or more arguments."))?; + let kernels = converted.map_err(|_| { + report_error( + report_error_flag, + Status::internal("Failed to convert one or more arguments."), + ) + })?; let mut handler = self.node_service.clone(); @@ -1110,17 +1250,24 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { }; for block in blocks { match tx - .send( - block - .try_into() - .map_err(|err| Status::internal(format!("Could not provide block:{}", err))), - ) + .send(block.try_into().map_err(|err| { + report_error( + report_error_flag, + Status::internal(format!("Could not provide block:{}", err)), + ) + })) .await { Ok(_) => (), Err(err) => { warn!(target: LOG_TARGET, "Error sending header via GRPC: {}", err); - match tx.send(Err(Status::unknown("Error sending data"))).await { + match tx + .send(Err(report_error( + report_error_flag, + Status::unknown("Error sending data"), + ))) + .await + { Ok(_) => (), Err(send_err) => { warn!(target: LOG_TARGET, "Error sending error to GRPC client: {}", send_err) @@ -1140,6 +1287,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); debug!(target: LOG_TARGET, "Incoming GRPC request for SearchUtxos"); let request = request.into_inner(); @@ -1148,7 +1296,12 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { .into_iter() .map(|s| Commitment::from_bytes(&s)) .collect(); - let outputs = converted.map_err(|_| Status::internal("Failed to convert one or more arguments."))?; + let outputs = converted.map_err(|_| { + report_error( + report_error_flag, + Status::internal("Failed to convert one or more arguments."), + ) + })?; let mut handler = self.node_service.clone(); @@ -1166,17 +1319,24 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { }; for block in blocks { match tx - .send( - block - .try_into() - .map_err(|err| Status::internal(format!("Could not provide block:{}", err))), - ) + .send(block.try_into().map_err(|err| { + report_error( + report_error_flag, + Status::internal(format!("Could not provide block:{}", err)), + ) + })) .await { Ok(_) => (), Err(err) => { warn!(target: LOG_TARGET, "Error sending header via GRPC: {}", err); - match tx.send(Err(Status::unknown("Error sending data"))).await { + match tx + .send(Err(report_error( + report_error_flag, + Status::unknown("Error sending data"), + ))) + .await + { Ok(_) => (), Err(send_err) => { warn!(target: LOG_TARGET, "Error sending error to GRPC client: {}", send_err) @@ -1197,11 +1357,17 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); debug!(target: LOG_TARGET, "Incoming GRPC request for FetchMatchingUtxos"); let request = request.into_inner(); let converted: Result, _> = request.hashes.into_iter().map(|s| s.try_into()).collect(); - let hashes = converted.map_err(|_| Status::internal("Failed to convert one or more arguments."))?; + let hashes = converted.map_err(|_| { + report_error( + report_error_flag, + Status::internal("Failed to convert one or more arguments."), + ) + })?; let mut handler = self.node_service.clone(); @@ -1228,7 +1394,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Err(err) => { warn!(target: LOG_TARGET, "Error sending output via GRPC: {}", err); - match tx.send(Err(Status::unknown("Error sending data"))).await { + match tx + .send(Err(report_error( + report_error_flag, + Status::unknown("Error sending data"), + ))) + .await + { Ok(_) => (), Err(send_err) => { warn!(target: LOG_TARGET, "Error sending error to GRPC client: {}", send_err) @@ -1251,6 +1423,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); let request = request.into_inner(); debug!( target: LOG_TARGET, @@ -1271,7 +1444,10 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { num_requested, BLOCK_TIMING_MAX_BLOCKS ); - return Err(Status::invalid_argument("Max request size exceeded.")); + return Err(report_error( + report_error_flag, + Status::invalid_argument("Max request size exceeded."), + )); } let headers = match handler.get_headers(start..=end).await { @@ -1304,14 +1480,28 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { - get_block_group(self.node_service.clone(), request, BlockGroupType::BlockSize).await + let report_error_flag = self.report_error_flag(); + get_block_group( + self.node_service.clone(), + request, + BlockGroupType::BlockSize, + report_error_flag, + ) + .await } async fn get_block_fees( &self, request: Request, ) -> Result, Status> { - get_block_group(self.node_service.clone(), request, BlockGroupType::BlockFees).await + let report_error_flag = self.report_error_flag(); + get_block_group( + self.node_service.clone(), + request, + BlockGroupType::BlockFees, + report_error_flag, + ) + .await } async fn get_version(&self, _request: Request) -> Result, Status> { @@ -1338,6 +1528,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); debug!(target: LOG_TARGET, "Incoming GRPC request for GetTokensInCirculation",); let request = request.into_inner(); let mut heights = request.heights; @@ -1371,7 +1562,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Ok(_) => (), Err(err) => { warn!(target: LOG_TARGET, "Error sending value via GRPC: {}", err); - match tx.send(Err(Status::unknown("Error sending data"))).await { + match tx + .send(Err(report_error( + report_error_flag, + Status::unknown("Error sending data"), + ))) + .await + { Ok(_) => (), Err(send_err) => { warn!(target: LOG_TARGET, "Error sending error to GRPC client: {}", send_err) @@ -1467,13 +1664,14 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, request: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); let tari_rpc::GetHeaderByHashRequest { hash } = request.into_inner(); let mut node_service = self.node_service.clone(); let hash_hex = hash.to_hex(); let block = node_service .get_block_by_hash(hash) .await - .map_err(|err| Status::internal(err.to_string()))?; + .map_err(|err| report_error(report_error_flag, Status::internal(err.to_string())))?; match block { Some(block) => { @@ -1492,7 +1690,10 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { Ok(Response::new(resp)) }, - None => Err(Status::not_found(format!("Header not found with hash `{}`", hash_hex))), + None => Err(report_error( + report_error_flag, + Status::not_found(format!("Header not found with hash `{}`", hash_hex)), + )), } } @@ -1541,19 +1742,20 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, _: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); let status = self .comms .connectivity() .get_connectivity_status() .await - .map_err(|err| Status::internal(err.to_string()))?; + .map_err(|err| report_error(report_error_flag, Status::internal(err.to_string())))?; let latency = self .liveness .clone() .get_network_avg_latency() .await - .map_err(|err| Status::internal(err.to_string()))?; + .map_err(|err| report_error(report_error_flag, Status::internal(err.to_string())))?; let resp = tari_rpc::NetworkStatusResponse { status: tari_rpc::ConnectivityStatus::from(status) as i32, @@ -1570,12 +1772,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, _: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); let mut connectivity = self.comms.connectivity(); let peer_manager = self.comms.peer_manager(); let connected_peers = connectivity .get_active_connections() .await - .map_err(|err| Status::internal(err.to_string()))?; + .map_err(|err| report_error(report_error_flag, Status::internal(err.to_string())))?; let mut peers = Vec::with_capacity(connected_peers.len()); for peer in connected_peers { @@ -1583,8 +1786,13 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { peer_manager .find_by_node_id(peer.peer_node_id()) .await - .map_err(|err| Status::internal(err.to_string()))? - .ok_or_else(|| Status::not_found(format!("Peer {} not found", peer.peer_node_id())))?, + .map_err(|err| report_error(report_error_flag, Status::internal(err.to_string())))? + .ok_or_else(|| { + report_error( + report_error_flag, + Status::not_found(format!("Peer {} not found", peer.peer_node_id())), + ) + })?, ); } @@ -1599,11 +1807,12 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { &self, _: Request, ) -> Result, Status> { + let report_error_flag = self.report_error_flag(); let mut mempool_handle = self.mempool_service.clone(); let mempool_stats = mempool_handle.get_mempool_stats().await.map_err(|e| { error!(target: LOG_TARGET, "Error submitting query:{}", e); - Status::internal(e.to_string()) + report_error(report_error_flag, Status::internal(e.to_string())) })?; let response = tari_rpc::MempoolStatsResponse { @@ -1625,6 +1834,7 @@ async fn get_block_group( mut handler: LocalNodeCommsInterface, request: Request, block_group_type: BlockGroupType, + report_error_flag: bool, ) -> Result, Status> { let request = request.into_inner(); let calc_type_response = request.calc_type; @@ -1659,8 +1869,18 @@ async fn get_block_group( let value = match calc_type { CalcType::Median => median(values).map(|v| vec![v]), CalcType::Mean => mean(values).map(|v| vec![v]), - CalcType::Quantile => return Err(Status::unimplemented("Quantile has not been implemented")), - CalcType::Quartile => return Err(Status::unimplemented("Quartile has not been implemented")), + CalcType::Quantile => { + return Err(report_error( + report_error_flag, + Status::unimplemented("Quantile has not been implemented"), + )) + }, + CalcType::Quartile => { + return Err(report_error( + report_error_flag, + Status::unimplemented("Quartile has not been implemented"), + )) + }, } .unwrap_or_default(); debug!(