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 4b2e044644..4ad1e1a1b3 100644 --- a/applications/minotari_node/src/grpc/base_node_grpc_server.rs +++ b/applications/minotari_node/src/grpc/base_node_grpc_server.rs @@ -788,27 +788,41 @@ impl tari_rpc::base_node_server::BaseNode for BaseNodeGrpcServer { let mut coinbases: Vec = request.coinbases; // let validate the coinbase amounts; - let reward = self - .consensus_rules - .calculate_coinbase_and_fees(new_template.header.height, new_template.body.kernels()) + let reward = u128::from( + self.consensus_rules + .calculate_coinbase_and_fees(new_template.header.height, new_template.body.kernels()) + .map_err(|_| { + obscure_error_if_true( + report_error_flag, + Status::internal("Could not calculate the amount of fees in the block".to_string()), + ) + })? + .as_u64(), + ); + let mut total_shares = 0u128; + for coinbase in &coinbases { + total_shares += u128::from(coinbase.value); + } + let mut cur_share_sum = 0u128; + let mut prev_coinbase_value = 0u128; + for coinbase in &mut coinbases { + cur_share_sum += u128::from(coinbase.value); + coinbase.value = u64::try_from( + (cur_share_sum.saturating_mul(reward)) + .checked_div(total_shares) + .ok_or(obscure_error_if_true( + report_error_flag, + Status::internal("total shares are zero".to_string()), + ))? - + prev_coinbase_value, + ) .map_err(|_| { obscure_error_if_true( report_error_flag, - Status::internal("Could not calculate the amount of fees in the block".to_string()), + Status::internal("Single coinbase fees exceeded u64".to_string()), ) - })? - .as_u64(); - let mut total_shares = 0u64; - for coinbase in &coinbases { - total_shares += coinbase.value; - } - let mut remainder = reward - ((reward / total_shares) * total_shares); - for coinbase in &mut coinbases { - coinbase.value *= reward / total_shares; - if remainder > 0 { - coinbase.value += 1; - remainder -= 1; - } + })?; + prev_coinbase_value = u128::from(coinbase.value); } let key_manager = create_memory_db_key_manager(); diff --git a/base_layer/common_types/src/emoji.rs b/base_layer/common_types/src/emoji.rs index 8c84882ea7..32b9e3ff5a 100644 --- a/base_layer/common_types/src/emoji.rs +++ b/base_layer/common_types/src/emoji.rs @@ -50,25 +50,26 @@ use crate::{ /// # Example /// /// ``` +/// use std::str::FromStr; /// use tari_common_types::emoji::EmojiId; /// /// // Construct an emoji ID from an emoji string (this can fail) /// let emoji_string = "πŸŒ΄πŸ¦€πŸ”ŒπŸ“ŒπŸš‘πŸŒ°πŸŽ“πŸŒ΄πŸŠπŸŒπŸ”’πŸ’‘πŸœπŸ“œπŸ‘›πŸ΅πŸ‘›πŸ½πŸŽ‚πŸ»πŸ¦‹πŸ“πŸ‘ΆπŸ­πŸΌπŸ€πŸŽͺπŸ’”πŸ’΅πŸ₯‘πŸ”‹πŸŽ’πŸ₯Š"; -/// let emoji_id_from_emoji_string = EmojiId::from_emoji_string(emoji_string); +/// let emoji_id_from_emoji_string = EmojiId::from_str(emoji_string); /// assert!(emoji_id_from_emoji_string.is_ok()); /// /// // Get the public key -/// let public_key = emoji_id_from_emoji_string.unwrap().to_public_key(); +/// let public_key = emoji_id_from_emoji_string.unwrap().as_public_key().clone(); /// /// // Reconstruct the emoji ID from the public key (this cannot fail) -/// let emoji_id_from_public_key = EmojiId::from_public_key(&public_key); +/// let emoji_id_from_public_key = EmojiId::from(&public_key); /// /// // An emoji ID is deterministic -/// assert_eq!(emoji_id_from_public_key.to_emoji_string(), emoji_string); +/// assert_eq!(emoji_id_from_public_key.to_string(), emoji_string); /// /// // Oh no! We swapped the first two emoji characters by mistake, so this should fail /// let invalid_emoji_string = "πŸ¦€πŸŒ΄πŸ”ŒπŸ“ŒπŸš‘πŸŒ°πŸŽ“πŸŒ΄πŸŠπŸŒπŸ”’πŸ’‘πŸœπŸ“œπŸ‘›πŸ΅πŸ‘›πŸ½πŸŽ‚πŸ»πŸ¦‹πŸ“πŸ‘ΆπŸ­πŸΌπŸ€πŸŽͺπŸ’”πŸ’΅πŸ₯‘πŸ”‹πŸŽ’πŸ₯Š"; -/// assert!(EmojiId::from_emoji_string(invalid_emoji_string).is_err()); +/// assert!(EmojiId::from_str(invalid_emoji_string).is_err()); /// ``` #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] pub struct EmojiId(PublicKey); diff --git a/base_layer/core/src/transactions/transaction_components/transaction_output.rs b/base_layer/core/src/transactions/transaction_components/transaction_output.rs index 49fd8fa53d..51d856cd1e 100644 --- a/base_layer/core/src/transactions/transaction_components/transaction_output.rs +++ b/base_layer/core/src/transactions/transaction_components/transaction_output.rs @@ -196,7 +196,7 @@ impl TransactionOutput { } } } else { - "None".to_string() + format!("None({})", self.minimum_value_promise) } } diff --git a/integration_tests/tests/steps/node_steps.rs b/integration_tests/tests/steps/node_steps.rs index f6c1049ab6..fe9c5f62fc 100644 --- a/integration_tests/tests/steps/node_steps.rs +++ b/integration_tests/tests/steps/node_steps.rs @@ -851,18 +851,19 @@ async fn generate_block_with_2_as_single_request_coinbases(world: &mut TariWorld } assert_eq!(coinbase_kernel_count, 1); assert_eq!(coinbase_utxo_count, 2); - let mut num_6154266700 = 0; - let mut num_12308533398 = 0; + let mut num_6154272109 = 0; + let mut num_12308544218 = 0; for output in body.outputs() { - if output.minimum_value_promise.as_u64() == 6154266700 { - num_6154266700 += 1; + if output.minimum_value_promise.as_u64() == 6154272109 { + num_6154272109 += 1; } - if output.minimum_value_promise.as_u64() == 12308533398 { - num_12308533398 += 1; + if output.minimum_value_promise.as_u64() == 12308544218 { + num_12308544218 += 1; } } - assert_eq!(num_6154266700, 1); - assert_eq!(num_12308533398, 1); + + assert_eq!(num_6154272109, 1); + assert_eq!(num_12308544218, 1); match client.submit_block(new_block).await { Ok(_) => (),