Report validator rewards in getConfirmedBlock JSON RPC
This commit is contained in:
@ -22,8 +22,8 @@ use rayon::{
|
||||
};
|
||||
use rocksdb::DBRawIterator;
|
||||
use solana_client::rpc_response::{
|
||||
RpcConfirmedBlock, RpcEncodedTransaction, RpcTransactionEncoding, RpcTransactionStatus,
|
||||
RpcTransactionWithStatusMeta,
|
||||
RpcConfirmedBlock, RpcEncodedTransaction, RpcRewards, RpcTransactionEncoding,
|
||||
RpcTransactionStatus, RpcTransactionWithStatusMeta,
|
||||
};
|
||||
use solana_measure::measure::Measure;
|
||||
use solana_metrics::{datapoint_debug, datapoint_error};
|
||||
@ -86,6 +86,7 @@ pub struct Blockstore {
|
||||
data_shred_cf: LedgerColumn<cf::ShredData>,
|
||||
code_shred_cf: LedgerColumn<cf::ShredCode>,
|
||||
transaction_status_cf: LedgerColumn<cf::TransactionStatus>,
|
||||
rewards_cf: LedgerColumn<cf::Rewards>,
|
||||
last_root: Arc<RwLock<Slot>>,
|
||||
insert_shreds_lock: Arc<Mutex<()>>,
|
||||
pub new_shreds_signals: Vec<SyncSender<bool>>,
|
||||
@ -195,6 +196,7 @@ impl Blockstore {
|
||||
let data_shred_cf = db.column();
|
||||
let code_shred_cf = db.column();
|
||||
let transaction_status_cf = db.column();
|
||||
let rewards_cf = db.column();
|
||||
|
||||
let db = Arc::new(db);
|
||||
|
||||
@ -219,6 +221,7 @@ impl Blockstore {
|
||||
data_shred_cf,
|
||||
code_shred_cf,
|
||||
transaction_status_cf,
|
||||
rewards_cf,
|
||||
new_shreds_signals: vec![],
|
||||
completed_slots_senders: vec![],
|
||||
insert_shreds_lock: Arc::new(Mutex::new(())),
|
||||
@ -346,6 +349,10 @@ impl Blockstore {
|
||||
& self
|
||||
.db
|
||||
.delete_range_cf::<cf::TransactionStatus>(&mut write_batch, from_slot, to_slot)
|
||||
.unwrap_or(false)
|
||||
& self
|
||||
.db
|
||||
.delete_range_cf::<cf::Rewards>(&mut write_batch, from_slot, to_slot)
|
||||
.unwrap_or(false);
|
||||
if let Err(e) = self.db.write(write_batch) {
|
||||
error!(
|
||||
@ -398,6 +405,10 @@ impl Blockstore {
|
||||
&& self
|
||||
.transaction_status_cf
|
||||
.compact_range(from_slot, to_slot)
|
||||
.unwrap_or(false)
|
||||
&& self
|
||||
.rewards_cf
|
||||
.compact_range(from_slot, to_slot)
|
||||
.unwrap_or(false);
|
||||
Ok(result)
|
||||
}
|
||||
@ -1396,6 +1407,12 @@ impl Blockstore {
|
||||
let blockhash = get_last_hash(slot_entries.iter())
|
||||
.unwrap_or_else(|| panic!("Rooted slot {:?} must have blockhash", slot));
|
||||
|
||||
let rewards = self
|
||||
.rewards_cf
|
||||
.get(slot)
|
||||
.expect("Expect rewards get to succeed")
|
||||
.unwrap_or_else(|| vec![]);
|
||||
|
||||
let block = RpcConfirmedBlock {
|
||||
previous_blockhash: previous_blockhash.to_string(),
|
||||
blockhash: blockhash.to_string(),
|
||||
@ -1405,6 +1422,7 @@ impl Blockstore {
|
||||
encoding,
|
||||
slot_transaction_iterator,
|
||||
),
|
||||
rewards,
|
||||
};
|
||||
return Ok(block);
|
||||
}
|
||||
@ -1442,6 +1460,10 @@ impl Blockstore {
|
||||
self.transaction_status_cf.put(index, status)
|
||||
}
|
||||
|
||||
pub fn write_rewards(&self, index: Slot, rewards: RpcRewards) -> Result<()> {
|
||||
self.rewards_cf.put(index, &rewards)
|
||||
}
|
||||
|
||||
fn get_block_timestamps(&self, slot: Slot) -> Result<Vec<(Pubkey, (Slot, UnixTimestamp))>> {
|
||||
let slot_entries = self.get_slot_entries(slot, 0, None)?;
|
||||
Ok(slot_entries
|
||||
@ -2574,6 +2596,13 @@ pub mod tests {
|
||||
.unwrap()
|
||||
.next()
|
||||
.map(|((slot, _), _)| slot >= min_slot)
|
||||
.unwrap_or(true)
|
||||
& blockstore
|
||||
.db
|
||||
.iter::<cf::Rewards>(IteratorMode::Start)
|
||||
.unwrap()
|
||||
.next()
|
||||
.map(|(slot, _)| slot >= min_slot)
|
||||
.unwrap_or(true);
|
||||
assert!(condition_met);
|
||||
}
|
||||
@ -4826,6 +4855,7 @@ pub mod tests {
|
||||
parent_slot: slot - 1,
|
||||
blockhash: blockhash.to_string(),
|
||||
previous_blockhash: Hash::default().to_string(),
|
||||
rewards: vec![],
|
||||
};
|
||||
// The previous_blockhash of `expected_block` is default because its parent slot is a
|
||||
// root, but empty of entries. This is special handling for snapshot root slots.
|
||||
@ -4846,6 +4876,7 @@ pub mod tests {
|
||||
parent_slot: slot,
|
||||
blockhash: blockhash.to_string(),
|
||||
previous_blockhash: blockhash.to_string(),
|
||||
rewards: vec![],
|
||||
};
|
||||
assert_eq!(confirmed_block, expected_block);
|
||||
|
||||
|
@ -10,7 +10,7 @@ use rocksdb::{
|
||||
};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
use solana_client::rpc_response::RpcTransactionStatus;
|
||||
use solana_client::rpc_response::{RpcRewards, RpcTransactionStatus};
|
||||
use solana_sdk::{clock::Slot, signature::Signature};
|
||||
use std::{collections::HashMap, fs, marker::PhantomData, path::Path, sync::Arc};
|
||||
use thiserror::Error;
|
||||
@ -38,6 +38,8 @@ const DATA_SHRED_CF: &str = "data_shred";
|
||||
const CODE_SHRED_CF: &str = "code_shred";
|
||||
/// Column family for Transaction Status
|
||||
const TRANSACTION_STATUS_CF: &str = "transaction_status";
|
||||
/// Column family for Rewards
|
||||
const REWARDS_CF: &str = "rewards";
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum BlockstoreError {
|
||||
@ -105,6 +107,10 @@ pub mod columns {
|
||||
#[derive(Debug)]
|
||||
/// The transaction status column
|
||||
pub struct TransactionStatus;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// The rewards column
|
||||
pub struct Rewards;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -113,8 +119,8 @@ struct Rocks(rocksdb::DB);
|
||||
impl Rocks {
|
||||
fn open(path: &Path) -> Result<Rocks> {
|
||||
use columns::{
|
||||
DeadSlots, DuplicateSlots, ErasureMeta, Index, Orphans, Root, ShredCode, ShredData,
|
||||
SlotMeta, TransactionStatus,
|
||||
DeadSlots, DuplicateSlots, ErasureMeta, Index, Orphans, Rewards, Root, ShredCode,
|
||||
ShredData, SlotMeta, TransactionStatus,
|
||||
};
|
||||
|
||||
fs::create_dir_all(&path)?;
|
||||
@ -139,6 +145,7 @@ impl Rocks {
|
||||
ColumnFamilyDescriptor::new(ShredCode::NAME, get_cf_options());
|
||||
let transaction_status_cf_descriptor =
|
||||
ColumnFamilyDescriptor::new(TransactionStatus::NAME, get_cf_options());
|
||||
let rewards_cf_descriptor = ColumnFamilyDescriptor::new(Rewards::NAME, get_cf_options());
|
||||
|
||||
let cfs = vec![
|
||||
meta_cf_descriptor,
|
||||
@ -151,6 +158,7 @@ impl Rocks {
|
||||
shred_data_cf_descriptor,
|
||||
shred_code_cf_descriptor,
|
||||
transaction_status_cf_descriptor,
|
||||
rewards_cf_descriptor,
|
||||
];
|
||||
|
||||
// Open the database
|
||||
@ -161,8 +169,8 @@ impl Rocks {
|
||||
|
||||
fn columns(&self) -> Vec<&'static str> {
|
||||
use columns::{
|
||||
DeadSlots, DuplicateSlots, ErasureMeta, Index, Orphans, Root, ShredCode, ShredData,
|
||||
SlotMeta, TransactionStatus,
|
||||
DeadSlots, DuplicateSlots, ErasureMeta, Index, Orphans, Rewards, Root, ShredCode,
|
||||
ShredData, SlotMeta, TransactionStatus,
|
||||
};
|
||||
|
||||
vec![
|
||||
@ -176,6 +184,7 @@ impl Rocks {
|
||||
ShredData::NAME,
|
||||
ShredCode::NAME,
|
||||
TransactionStatus::NAME,
|
||||
Rewards::NAME,
|
||||
]
|
||||
}
|
||||
|
||||
@ -316,6 +325,14 @@ impl ColumnName for columns::TransactionStatus {
|
||||
const NAME: &'static str = TRANSACTION_STATUS_CF;
|
||||
}
|
||||
|
||||
impl SlotColumn for columns::Rewards {}
|
||||
impl ColumnName for columns::Rewards {
|
||||
const NAME: &'static str = REWARDS_CF;
|
||||
}
|
||||
impl TypedColumn for columns::Rewards {
|
||||
type Type = RpcRewards;
|
||||
}
|
||||
|
||||
impl Column for columns::ShredCode {
|
||||
type Index = (u64, u64);
|
||||
|
||||
|
Reference in New Issue
Block a user