diff --git a/applications/minotari_app_grpc/proto/base_node.proto b/applications/minotari_app_grpc/proto/base_node.proto index 1ea4428757..3e75dad936 100644 --- a/applications/minotari_app_grpc/proto/base_node.proto +++ b/applications/minotari_app_grpc/proto/base_node.proto @@ -217,6 +217,8 @@ message NetworkDifficultyResponse { uint64 pow_algo = 5; uint64 sha3x_estimated_hash_rate = 6; uint64 randomx_estimated_hash_rate = 7; + uint64 num_coinbases = 8; + repeated bytes coinbase_extras = 9; } // A generic single value response for a specific height 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 8738da2433..d6245767f6 100644 --- a/applications/minotari_node/src/grpc/base_node_grpc_server.rs +++ b/applications/minotari_node/src/grpc/base_node_grpc_server.rs @@ -313,6 +313,27 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { let randomx_estimated_hash_rate = randomx_hash_rate_moving_average.average(); let estimated_hash_rate = sha3x_estimated_hash_rate.saturating_add(randomx_estimated_hash_rate); + let block = match handler.get_block(current_height, true).await { + Ok(block) => block, + Err(err) => { + warn!(target: LOG_TARGET, "Base node service error: {:?}", err,); + let _network_difficulty_response = tx.send(Err(obscure_error_if_true( + report_error_flag, + Status::internal(format!("Error fetching block at height {}", current_height)), + ))); + return; + }, + }; + if block.is_none() { + let _network_difficulty_response = tx.send(Err(obscure_error_if_true( + report_error_flag, + Status::internal(format!("Block not found at height {}", current_height)), + ))); + return; + } + let block = block.unwrap(); + let coinbases = block.block().body.get_coinbase_outputs(); + let difficulty = tari_rpc::NetworkDifficultyResponse { difficulty: current_difficulty.as_u64(), estimated_hash_rate, @@ -321,6 +342,8 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { height: current_height, timestamp: current_timestamp.as_u64(), pow_algo: pow_algo.as_u64(), + num_coinbases: coinbases.len() as u64, + coinbase_extras: coinbases.iter().map(|c| c.features.coinbase_extra.to_vec()).collect(), }; if let Err(err) = tx.send(Ok(difficulty)).await { diff --git a/base_layer/core/src/transactions/aggregated_body.rs b/base_layer/core/src/transactions/aggregated_body.rs index 9d4f798285..ecdafcde2c 100644 --- a/base_layer/core/src/transactions/aggregated_body.rs +++ b/base_layer/core/src/transactions/aggregated_body.rs @@ -265,6 +265,16 @@ impl AggregateBody { Ok(fee) } + pub fn get_coinbase_outputs(&self) -> Vec<&TransactionOutput> { + let mut outputs = vec![]; + for utxo in self.outputs() { + if utxo.features.output_type == OutputType::Coinbase { + outputs.push(utxo); + } + } + outputs + } + /// Run through the outputs of the block and check that /// 1. There is exactly ONE coinbase output /// 1. The coinbase output's maturity is correctly set