diff --git a/accounts-db/src/stake_rewards.rs b/accounts-db/src/stake_rewards.rs index 5376af1c973a6f..cbf7604f6d94ee 100644 --- a/accounts-db/src/stake_rewards.rs +++ b/accounts-db/src/stake_rewards.rs @@ -89,8 +89,9 @@ impl StakeReward { stake_reward_info: RewardInfo { reward_type: solana_sdk::reward_type::RewardType::Staking, lamports: reward_lamports, - post_balance: 0, /* unused atm */ - commission: None, /* unused atm */ + post_balance: 0, /* unused atm */ + commission: None, /* unused atm */ + num_partitions: None, // Not relevant }, stake_account: validator_stake_account, diff --git a/cli-output/src/display.rs b/cli-output/src/display.rs index bde22b181e4e00..26448b40e9da16 100644 --- a/cli-output/src/display.rs +++ b/cli-output/src/display.rs @@ -808,6 +808,7 @@ mod test { post_balance: 9_900, reward_type: Some(RewardType::Rent), commission: None, + num_partitions: None, }]), loaded_addresses: LoadedAddresses::default(), return_data: Some(TransactionReturnData { @@ -887,6 +888,7 @@ Rewards: post_balance: 14_900, reward_type: Some(RewardType::Rent), commission: None, + num_partitions: None, }]), loaded_addresses, return_data: Some(TransactionReturnData { diff --git a/core/src/rewards_recorder_service.rs b/core/src/rewards_recorder_service.rs index 3fc2c8dc5b5149..b90ed2c54a9e84 100644 --- a/core/src/rewards_recorder_service.rs +++ b/core/src/rewards_recorder_service.rs @@ -64,6 +64,7 @@ impl RewardsRecorderService { post_balance: reward_info.post_balance, reward_type: Some(reward_info.reward_type), commission: reward_info.commission, + num_partitions: reward_info.num_partitions, }) .collect(); diff --git a/geyser-plugin-interface/src/geyser_plugin_interface.rs b/geyser-plugin-interface/src/geyser_plugin_interface.rs index d9a3b00f8dc4c8..56285becc5887f 100644 --- a/geyser-plugin-interface/src/geyser_plugin_interface.rs +++ b/geyser-plugin-interface/src/geyser_plugin_interface.rs @@ -8,7 +8,7 @@ use { signature::Signature, transaction::SanitizedTransaction, }, - solana_transaction_status::{Reward, TransactionStatusMeta}, + solana_transaction_status::{Reward, RewardType, TransactionStatusMeta}, std::{any::Any, error, io}, thiserror::Error, }; @@ -217,7 +217,7 @@ pub enum ReplicaEntryInfoVersions<'a> { pub struct ReplicaBlockInfo<'a> { pub slot: Slot, pub blockhash: &'a str, - pub rewards: &'a [Reward], + pub rewards: &'a [DeprecatedReward], pub block_time: Option, pub block_height: Option, } @@ -230,7 +230,7 @@ pub struct ReplicaBlockInfoV2<'a> { pub parent_blockhash: &'a str, pub slot: Slot, pub blockhash: &'a str, - pub rewards: &'a [Reward], + pub rewards: &'a [DeprecatedReward], pub block_time: Option, pub block_height: Option, pub executed_transaction_count: u64, @@ -240,6 +240,31 @@ pub struct ReplicaBlockInfoV2<'a> { #[derive(Clone, Debug)] #[repr(C)] pub struct ReplicaBlockInfoV3<'a> { + pub parent_slot: Slot, + pub parent_blockhash: &'a str, + pub slot: Slot, + pub blockhash: &'a str, + pub rewards: &'a [DeprecatedReward], + pub block_time: Option, + pub block_height: Option, + pub executed_transaction_count: u64, + pub entry_count: u64, +} + +#[derive(Clone, Debug)] +#[repr(C)] +pub struct DeprecatedReward { + pub pubkey: String, + pub lamports: i64, + pub post_balance: u64, + pub reward_type: Option, + pub commission: Option, +} + +/// Adding num_partitions field to each Reward. +#[derive(Clone, Debug)] +#[repr(C)] +pub struct ReplicaBlockInfoV4<'a> { pub parent_slot: Slot, pub parent_blockhash: &'a str, pub slot: Slot, @@ -256,6 +281,7 @@ pub enum ReplicaBlockInfoVersions<'a> { V0_0_1(&'a ReplicaBlockInfo<'a>), V0_0_2(&'a ReplicaBlockInfoV2<'a>), V0_0_3(&'a ReplicaBlockInfoV3<'a>), + V0_0_4(&'a ReplicaBlockInfoV4<'a>), } /// Errors returned by plugin calls diff --git a/geyser-plugin-manager/src/block_metadata_notifier.rs b/geyser-plugin-manager/src/block_metadata_notifier.rs index 87f15f41fc0ae0..caea2ca862e689 100644 --- a/geyser-plugin-manager/src/block_metadata_notifier.rs +++ b/geyser-plugin-manager/src/block_metadata_notifier.rs @@ -4,7 +4,7 @@ use { geyser_plugin_manager::GeyserPluginManager, }, agave_geyser_plugin_interface::geyser_plugin_interface::{ - ReplicaBlockInfoV3, ReplicaBlockInfoVersions, + ReplicaBlockInfoV4, ReplicaBlockInfoVersions, }, log::*, solana_measure::measure::Measure, @@ -51,7 +51,7 @@ impl BlockMetadataNotifier for BlockMetadataNotifierImpl { executed_transaction_count, entry_count, ); - let block_info = ReplicaBlockInfoVersions::V0_0_3(&block_info); + let block_info = ReplicaBlockInfoVersions::V0_0_4(&block_info); match plugin.notify_block_metadata(block_info) { Err(err) => { error!( @@ -91,6 +91,7 @@ impl BlockMetadataNotifierImpl { post_balance: reward.post_balance, reward_type: Some(reward.reward_type), commission: reward.commission, + num_partitions: reward.num_partitions, }) .collect() } @@ -105,8 +106,8 @@ impl BlockMetadataNotifierImpl { block_height: Option, executed_transaction_count: u64, entry_count: u64, - ) -> ReplicaBlockInfoV3<'a> { - ReplicaBlockInfoV3 { + ) -> ReplicaBlockInfoV4<'a> { + ReplicaBlockInfoV4 { parent_slot, parent_blockhash, slot, diff --git a/ledger/benches/protobuf.rs b/ledger/benches/protobuf.rs index e211e85c87ff35..5a459125287178 100644 --- a/ledger/benches/protobuf.rs +++ b/ledger/benches/protobuf.rs @@ -24,6 +24,7 @@ fn create_rewards() -> Rewards { post_balance: u64::MAX, reward_type: Some(RewardType::Fee), commission: None, + num_partitions: None, }) .collect() } diff --git a/ledger/src/blockstore.rs b/ledger/src/blockstore.rs index 19173fe1feb9ff..3d9d63c689271c 100644 --- a/ledger/src/blockstore.rs +++ b/ledger/src/blockstore.rs @@ -10608,6 +10608,7 @@ pub mod tests { post_balance: u64::MAX, reward_type: Some(RewardType::Fee), commission: None, + num_partitions: None, }) .collect(); let protobuf_rewards: generated::Rewards = rewards.into(); @@ -10681,6 +10682,7 @@ pub mod tests { post_balance: 42, reward_type: Some(RewardType::Rent), commission: None, + num_partitions: None, }]), loaded_addresses: LoadedAddresses::default(), return_data: Some(TransactionReturnData { diff --git a/rpc/src/transaction_status_service.rs b/rpc/src/transaction_status_service.rs index c244827e3dd980..105cb64657c607 100644 --- a/rpc/src/transaction_status_service.rs +++ b/rpc/src/transaction_status_service.rs @@ -122,6 +122,7 @@ impl TransactionStatusService { post_balance: reward_info.post_balance, reward_type: Some(reward_info.reward_type), commission: reward_info.commission, + num_partitions: reward_info.num_partitions, }) .collect(), ); diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index e605c1ef605bef..7f349b991a53f1 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -2583,6 +2583,7 @@ impl Bank { lamports: i64::try_from(stakers_reward).unwrap(), post_balance, commission: Some(vote_state.commission), + num_partitions: None, }, stake_account, }); @@ -2659,6 +2660,7 @@ impl Bank { lamports: vote_rewards as i64, post_balance: vote_account.lamports(), commission: Some(commission), + num_partitions: None, }, )) }, @@ -2709,6 +2711,7 @@ impl Bank { lamports: vote_rewards as i64, post_balance: vote_account.lamports(), commission: Some(commission), + num_partitions: None, }, )); result diff --git a/runtime/src/bank/fee_distribution.rs b/runtime/src/bank/fee_distribution.rs index 223be2ec52ce1a..b6f08498cf107f 100644 --- a/runtime/src/bank/fee_distribution.rs +++ b/runtime/src/bank/fee_distribution.rs @@ -137,6 +137,7 @@ impl Bank { lamports: deposit as i64, post_balance, commission: None, + num_partitions: None, }, )); } @@ -296,6 +297,7 @@ impl Bank { lamports: rent_to_be_paid as i64, post_balance, commission: None, + num_partitions: None, }, )); } diff --git a/runtime/src/bank/partitioned_epoch_rewards/calculation.rs b/runtime/src/bank/partitioned_epoch_rewards/calculation.rs index 5590a4af8d2bb4..95e74e87557cd9 100644 --- a/runtime/src/bank/partitioned_epoch_rewards/calculation.rs +++ b/runtime/src/bank/partitioned_epoch_rewards/calculation.rs @@ -68,7 +68,7 @@ impl Bank { self.block_height() + REWARD_CALCULATION_NUM_BLOCKS }; - let num_partitions = stake_rewards_by_partition.len() as u64; + let num_partitions = stake_rewards_by_partition.len(); self.set_epoch_reward_status_active( distribution_starting_block_height, @@ -79,10 +79,12 @@ impl Bank { total_rewards, distributed_rewards, distribution_starting_block_height, - num_partitions, + num_partitions as u64, total_points, ); + self.record_partition_data_reward(num_partitions); + datapoint_info!( "epoch-rewards-status-update", ("start_slot", slot, i64), @@ -440,6 +442,7 @@ impl Bank { lamports: i64::try_from(stakers_reward).unwrap(), post_balance, commission: Some(vote_state.commission), + num_partitions: None, }, stake, }); @@ -759,6 +762,7 @@ mod tests { lamports: p.1.vote_rewards as i64, post_balance: p.1.vote_rewards, commission: Some(p.1.commission), + num_partitions: None, }; vote_rewards_account.rewards.push((p.0, info)); vote_rewards_account @@ -956,6 +960,7 @@ mod tests { lamports: vote_rewards as i64, post_balance: vote_account.lamports(), commission: Some(commision), + num_partitions: None, } ); assert_eq!(&rewards.0, vote_pubkey); @@ -975,6 +980,7 @@ mod tests { lamports: rewards, post_balance: original_stake_lamport + rewards as u64, commission: Some(commision), + num_partitions: None, }; assert_eq!( stake_reward_calculation.stake_rewards[0].stake_reward_info, diff --git a/runtime/src/bank/partitioned_epoch_rewards/distribution.rs b/runtime/src/bank/partitioned_epoch_rewards/distribution.rs index c627da706b1a38..c00ec916e54568 100644 --- a/runtime/src/bank/partitioned_epoch_rewards/distribution.rs +++ b/runtime/src/bank/partitioned_epoch_rewards/distribution.rs @@ -521,6 +521,7 @@ mod tests { lamports: reward_amount, post_balance: 0, commission: None, + num_partitions: None, }; let nonexistent_account = Pubkey::new_unique(); diff --git a/runtime/src/bank/partitioned_epoch_rewards/mod.rs b/runtime/src/bank/partitioned_epoch_rewards/mod.rs index b87ee5f1e797ee..bf34b1e5756a38 100644 --- a/runtime/src/bank/partitioned_epoch_rewards/mod.rs +++ b/runtime/src/bank/partitioned_epoch_rewards/mod.rs @@ -2,6 +2,7 @@ mod calculation; mod compare; mod distribution; mod epoch_rewards_hasher; +mod partition_data_reward; mod sysvar; use { diff --git a/runtime/src/bank/partitioned_epoch_rewards/partition_data_reward.rs b/runtime/src/bank/partitioned_epoch_rewards/partition_data_reward.rs new file mode 100644 index 00000000000000..3dbcc472d51fab --- /dev/null +++ b/runtime/src/bank/partitioned_epoch_rewards/partition_data_reward.rs @@ -0,0 +1,26 @@ +use { + super::Bank, + solana_sdk::{reward_info::RewardInfo, reward_type::RewardType, sysvar}, +}; + +impl Bank { + pub(in crate::bank::partitioned_epoch_rewards) fn record_partition_data_reward( + &self, + num_partitions: usize, + ) { + let mut rewards = self.rewards.write().unwrap(); + rewards.reserve(1); + rewards.push(( + // rewards must be "delivered" to some address; since this + // RewardType is for records purposes only, the address is arbitrary + sysvar::epoch_rewards::id(), + RewardInfo { + reward_type: RewardType::PartitionData, + lamports: 0, + post_balance: 0, + commission: None, + num_partitions: Some(num_partitions), + }, + )); + } +} diff --git a/runtime/src/bank/tests.rs b/runtime/src/bank/tests.rs index a4e538b128b6dc..6ea3768675388d 100644 --- a/runtime/src/bank/tests.rs +++ b/runtime/src/bank/tests.rs @@ -1984,6 +1984,7 @@ where lamports: 0, post_balance: bank1.get_balance(&vote_id), commission: Some(0), + num_partitions: None, } ), ( @@ -1993,6 +1994,7 @@ where lamports: validator_rewards as i64, post_balance: bank1.get_balance(&stake_id), commission: Some(0), + num_partitions: None, } ) ] @@ -2587,6 +2589,7 @@ fn test_bank_tx_fee() { lamports: expected_fee_collected as i64, post_balance: initial_balance + expected_fee_collected, commission: None, + num_partitions: None, } )] ); @@ -2622,6 +2625,7 @@ fn test_bank_tx_fee() { lamports: expected_fee_collected as i64, post_balance: initial_balance + 2 * expected_fee_collected, commission: None, + num_partitions: None, } )] ); @@ -2697,6 +2701,7 @@ fn test_bank_tx_compute_unit_fee() { lamports: expected_fee_collected as i64, post_balance: initial_balance + expected_fee_collected, commission: None, + num_partitions: None, } )] ); @@ -2732,6 +2737,7 @@ fn test_bank_tx_compute_unit_fee() { lamports: expected_fee_collected as i64, post_balance: initial_balance + 2 * expected_fee_collected, commission: None, + num_partitions: None, } )] ); @@ -12552,6 +12558,7 @@ fn test_calc_vote_accounts_to_store_normal() { lamports: vote_rewards as i64, post_balance: vote_account.lamports(), commission: Some(commission), + num_partitions: None, } ); assert_eq!(rewards.0, pubkey); diff --git a/sdk/src/rent_debits.rs b/sdk/src/rent_debits.rs index 588f7c67a2a929..8cacd25b4ecbf2 100644 --- a/sdk/src/rent_debits.rs +++ b/sdk/src/rent_debits.rs @@ -18,7 +18,8 @@ impl RentDebit { reward_type: RewardType::Rent, lamports: rent_debit, post_balance: self.post_balance, - commission: None, // Not applicable + commission: None, // Not applicable + num_partitions: None, // Not applicable }) } } diff --git a/sdk/src/reward_info.rs b/sdk/src/reward_info.rs index 9153d7032da39e..b1d51ae43af2fb 100644 --- a/sdk/src/reward_info.rs +++ b/sdk/src/reward_info.rs @@ -10,4 +10,7 @@ pub struct RewardInfo { pub post_balance: u64, /// Vote account commission when the reward was credited, only present for voting and staking rewards pub commission: Option, + /// Number of partitions calculated for epoch rewards, only present for + /// RewardType::PartitionData + pub num_partitions: Option, } diff --git a/sdk/src/reward_type.rs b/sdk/src/reward_type.rs index a0765e0b745f02..5b8a1feba0939f 100644 --- a/sdk/src/reward_type.rs +++ b/sdk/src/reward_type.rs @@ -9,6 +9,7 @@ pub enum RewardType { Rent, Staking, Voting, + PartitionData, } impl fmt::Display for RewardType { @@ -21,6 +22,7 @@ impl fmt::Display for RewardType { RewardType::Rent => "rent", RewardType::Staking => "staking", RewardType::Voting => "voting", + RewardType::PartitionData => "partition", } ) } diff --git a/storage-bigtable/src/lib.rs b/storage-bigtable/src/lib.rs index 240ae44c3d07fe..d73f0c51dd196d 100644 --- a/storage-bigtable/src/lib.rs +++ b/storage-bigtable/src/lib.rs @@ -295,6 +295,7 @@ impl From for Reward { post_balance: 0, reward_type: None, commission: None, + num_partitions: None, } } } diff --git a/storage-proto/proto/confirmed_block.proto b/storage-proto/proto/confirmed_block.proto index 47548ea13bc6a4..d7e494e59d07b4 100644 --- a/storage-proto/proto/confirmed_block.proto +++ b/storage-proto/proto/confirmed_block.proto @@ -118,6 +118,7 @@ enum RewardType { Rent = 2; Staking = 3; Voting = 4; + PartitionData = 5; } message Reward { @@ -126,6 +127,7 @@ message Reward { uint64 post_balance = 3; RewardType reward_type = 4; string commission = 5; + optional uint32 num_partitions = 6; } message Rewards { diff --git a/storage-proto/src/convert.rs b/storage-proto/src/convert.rs index 8d6669e44b43f1..4859608008c396 100644 --- a/storage-proto/src/convert.rs +++ b/storage-proto/src/convert.rs @@ -96,8 +96,10 @@ impl From for generated::Reward { Some(RewardType::Rent) => generated::RewardType::Rent, Some(RewardType::Staking) => generated::RewardType::Staking, Some(RewardType::Voting) => generated::RewardType::Voting, + Some(RewardType::PartitionData) => generated::RewardType::PartitionData, } as i32, commission: reward.commission.map(|c| c.to_string()).unwrap_or_default(), + num_partitions: reward.num_partitions.map(|num| num as u32), } } } @@ -114,9 +116,11 @@ impl From for Reward { 2 => Some(RewardType::Rent), 3 => Some(RewardType::Staking), 4 => Some(RewardType::Voting), + 5 => Some(RewardType::PartitionData), _ => None, }, commission: reward.commission.parse::().ok(), + num_partitions: reward.num_partitions.map(|num| num as usize), } } } @@ -1230,6 +1234,7 @@ mod test { post_balance: 321, reward_type: None, commission: None, + num_partitions: None, }; let gen_reward: generated::Reward = reward.clone().into(); assert_eq!(reward, gen_reward.into()); diff --git a/storage-proto/src/lib.rs b/storage-proto/src/lib.rs index 0832690f1e2b88..08717dfb9688e1 100644 --- a/storage-proto/src/lib.rs +++ b/storage-proto/src/lib.rs @@ -28,6 +28,8 @@ pub struct StoredExtendedReward { reward_type: Option, #[serde(deserialize_with = "default_on_eof")] commission: Option, + #[serde(deserialize_with = "default_on_eof")] + num_partitions: Option, } impl From for Reward { @@ -38,6 +40,7 @@ impl From for Reward { post_balance, reward_type, commission, + num_partitions, } = value; Self { pubkey, @@ -45,6 +48,7 @@ impl From for Reward { post_balance, reward_type, commission, + num_partitions, } } } @@ -57,6 +61,7 @@ impl From for StoredExtendedReward { post_balance, reward_type, commission, + num_partitions, } = value; Self { pubkey, @@ -64,6 +69,7 @@ impl From for StoredExtendedReward { post_balance, reward_type, commission, + num_partitions, } } } diff --git a/transaction-status/src/lib.rs b/transaction-status/src/lib.rs index 4028ff14bb62bb..c665a3e0370f99 100644 --- a/transaction-status/src/lib.rs +++ b/transaction-status/src/lib.rs @@ -624,6 +624,7 @@ pub struct Reward { pub post_balance: u64, // Account balance in lamports after `lamports` was applied pub reward_type: Option, pub commission: Option, // Vote account commission when the reward was credited, only present for voting and staking rewards + pub num_partitions: Option, // Number of partitions calculated for partitioned epoch rewards, only present for RewardType::PartitionData } pub type Rewards = Vec;