diff --git a/applications/minotari_app_grpc/proto/base_node.proto b/applications/minotari_app_grpc/proto/base_node.proto index df0ef382ee..eda1acf63f 100644 --- a/applications/minotari_app_grpc/proto/base_node.proto +++ b/applications/minotari_app_grpc/proto/base_node.proto @@ -347,6 +347,7 @@ message GetNewBlockResult{ // This is the completed block Block block = 2; bytes merge_mining_hash =3; + bytes tari_unique_id =4; } // This is the message that is returned for a miner after it asks for a new block. @@ -359,6 +360,7 @@ message GetNewBlockBlobResult{ bytes block_body = 3; bytes merge_mining_hash =4; bytes utxo_mr = 5; + bytes tari_unique_id =6; } // This is mining data for the miner asking for a new block diff --git a/applications/minotari_node/src/grpc/base_node_grpc_server.rs b/applications/minotari_node/src/grpc/base_node_grpc_server.rs index f331237a31..c6eebed83d 100644 --- a/applications/minotari_node/src/grpc/base_node_grpc_server.rs +++ b/applications/minotari_node/src/grpc/base_node_grpc_server.rs @@ -635,6 +635,23 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { )) }, }; + let gen_hash = handler + .get_header(0) + .await + .map_err(|_| { + obscure_error_if_true( + report_error_flag, + Status::invalid_argument("Tari genesis block not found".to_string()), + ) + })? + .ok_or_else(|| { + obscure_error_if_true( + report_error_flag, + Status::not_found("Tari genesis block not found".to_string()), + ) + })? + .hash() + .to_vec(); // construct response let block_hash = new_block.hash().to_vec(); let mining_hash = match new_block.header.pow.pow_algo { @@ -651,6 +668,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { block_hash, block, merge_mining_hash: mining_hash, + tari_unique_id: gen_hash, }; debug!(target: LOG_TARGET, "Sending GetNewBlock response to client"); Ok(Response::new(response)) @@ -704,6 +722,23 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { PowAlgorithm::Sha3x => new_block.header.mining_hash().to_vec(), PowAlgorithm::RandomX => new_block.header.merge_mining_hash().to_vec(), }; + let gen_hash = handler + .get_header(0) + .await + .map_err(|_| { + obscure_error_if_true( + report_error_flag, + Status::invalid_argument("Tari genesis block not found".to_string()), + ) + })? + .ok_or_else(|| { + obscure_error_if_true( + report_error_flag, + Status::not_found("Tari genesis block not found".to_string()), + ) + })? + .hash() + .to_vec(); let (header, block_body) = new_block.into_header_body(); let mut header_bytes = Vec::new(); @@ -718,6 +753,7 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { block_body: block_body_bytes, merge_mining_hash: mining_hash, utxo_mr: header.output_mr.to_vec(), + tari_unique_id: gen_hash, }; debug!(target: LOG_TARGET, "Sending GetNewBlockBlob response to client"); Ok(Response::new(response)) diff --git a/base_layer/wallet_ffi/src/lib.rs b/base_layer/wallet_ffi/src/lib.rs index 47f0b01845..bbcd7e5dfb 100644 --- a/base_layer/wallet_ffi/src/lib.rs +++ b/base_layer/wallet_ffi/src/lib.rs @@ -1237,6 +1237,38 @@ pub unsafe extern "C" fn tari_address_to_emoji_id( CString::into_raw(result) } +/// Creates a char array from a TariWalletAddress's network +/// +/// ## Arguments +/// `address` - The pointer to a TariWalletAddress +/// `error_out` - Pointer to an int which will be modified to an error code should one occur, may not be null. Functions +/// as an out parameter. +/// +/// ## Returns +/// `*mut c_char` - Returns a pointer to a char array. Note that it returns empty +/// if there was an error from TariWalletAddress +/// +/// # Safety +/// The ```string_destroy``` method must be called when finished with a string from rust to prevent a memory leak +#[no_mangle] +pub unsafe extern "C" fn tari_address_network(address: *mut TariWalletAddress, error_out: *mut c_int) -> *mut c_char { + let mut error = 0; + let mut result = CString::new("").expect("Blank CString will not fail."); + ptr::swap(error_out, &mut error as *mut c_int); + if address.is_null() { + error = LibWalletError::from(InterfaceError::NullError("address".to_string())).code; + ptr::swap(error_out, &mut error as *mut c_int); + return CString::into_raw(result); + } + let network_string = address + .as_ref() + .expect("Address should not be empty") + .network() + .to_string(); + result = CString::new(network_string).expect("string will not fail."); + CString::into_raw(result) +} + /// Creates a TariWalletAddress from a char array in emoji format /// /// ## Arguments diff --git a/base_layer/wallet_ffi/wallet.h b/base_layer/wallet_ffi/wallet.h index 329e4fa086..af72907883 100644 --- a/base_layer/wallet_ffi/wallet.h +++ b/base_layer/wallet_ffi/wallet.h @@ -768,6 +768,24 @@ TariWalletAddress *tari_address_from_hex(const char *address, char *tari_address_to_emoji_id(TariWalletAddress *address, int *error_out); +/** + * Creates a char array from a TariWalletAddress's network + * + * ## Arguments + * `address` - The pointer to a TariWalletAddress + * `error_out` - Pointer to an int which will be modified to an error code should one occur, may not be null. Functions + * as an out parameter. + * + * ## Returns + * `*mut c_char` - Returns a pointer to a char array. Note that it returns empty + * if there was an error from TariWalletAddress + * + * # Safety + * The ```string_destroy``` method must be called when finished with a string from rust to prevent a memory leak + */ +char *tari_address_network(TariWalletAddress *address, + int *error_out); + /** * Creates a TariWalletAddress from a char array in emoji format *