Convert Blockstore Rewards cf to protobuf (#12860)

* Add Blockstore protobuf cf type

* Add Rewards message to proto and make generated pub

* Convert Rewards cf to ProtobufColumn

* Add bench

* Adjust tags

* Move solana proto definitions and conversion methods to new crate
This commit is contained in:
Tyera Eulberg 2020-10-15 18:04:10 -06:00 committed by GitHub
parent b510474dcb
commit 359707c85e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 734 additions and 32 deletions

15
Cargo.lock generated
View File

@ -4016,6 +4016,7 @@ dependencies = [
"log 0.4.8",
"matches",
"num_cpus",
"prost",
"rand 0.7.3",
"rand_chacha 0.2.2",
"rayon",
@ -4036,6 +4037,7 @@ dependencies = [
"solana-sdk 1.5.0",
"solana-stake-program",
"solana-storage-bigtable",
"solana-storage-proto",
"solana-transaction-status",
"solana-vote-program",
"tempfile",
@ -4618,12 +4620,25 @@ dependencies = [
"serde_derive",
"smpl_jwt",
"solana-sdk 1.5.0",
"solana-storage-proto",
"solana-transaction-status",
"thiserror",
"tonic",
"zstd",
]
[[package]]
name = "solana-storage-proto"
version = "1.5.0"
dependencies = [
"bincode",
"prost",
"serde",
"serde_derive",
"solana-sdk 1.5.0",
"solana-transaction-status",
]
[[package]]
name = "solana-streamer"
version = "1.5.0"

View File

@ -30,6 +30,7 @@ members = [
"merkle-tree",
"stake-o-matic",
"storage-bigtable",
"storage-proto",
"streamer",
"measure",
"metrics",

View File

@ -24,6 +24,7 @@ lazy_static = "1.4.0"
libc = "0.2.72"
log = { version = "0.4.8" }
num_cpus = "1.13.0"
prost = "0.6.1"
rand = "0.7.0"
rand_chacha = "0.2.2"
rayon = "1.4.1"
@ -43,6 +44,7 @@ solana-runtime = { path = "../runtime", version = "1.5.0" }
solana-sdk = { path = "../sdk", version = "1.5.0" }
solana-stake-program = { path = "../programs/stake", version = "1.5.0" }
solana-storage-bigtable = { path = "../storage-bigtable", version = "1.5.0" }
solana-storage-proto = { path = "../storage-proto", version = "1.5.0" }
solana-vote-program = { path = "../programs/vote", version = "1.5.0" }
tempfile = "3.1.0"
thiserror = "1.0"

115
ledger/benches/protobuf.rs Normal file
View File

@ -0,0 +1,115 @@
#![feature(test)]
extern crate test;
use bincode::{deserialize, serialize};
use solana_ledger::{
blockstore::Blockstore,
blockstore_db::{columns as cf, LedgerColumn},
get_tmp_ledger_path,
};
use solana_runtime::bank::RewardType;
use solana_sdk::{clock::Slot, pubkey::Pubkey};
use solana_transaction_status::{Reward, Rewards};
use std::path::Path;
use test::Bencher;
fn create_rewards() -> Rewards {
(0..100)
.map(|i| Reward {
pubkey: Pubkey::new_rand().to_string(),
lamports: 42 + i,
post_balance: std::u64::MAX,
reward_type: Some(RewardType::Fee),
})
.collect()
}
fn write_bincode_rewards(rewards_cf: &LedgerColumn<cf::Rewards>, slot: Slot, rewards: Rewards) {
let data = serialize(&rewards).unwrap();
rewards_cf.put_bytes(slot, &data).unwrap();
}
fn write_protobuf_rewards(rewards_cf: &LedgerColumn<cf::Rewards>, slot: Slot, rewards: Rewards) {
let rewards = rewards.into();
rewards_cf.put_protobuf(slot, &rewards).unwrap();
}
fn read_bincode_rewards(rewards_cf: &LedgerColumn<cf::Rewards>, slot: Slot) -> Option<Rewards> {
rewards_cf
.get_bytes(slot)
.unwrap()
.map(|data| deserialize::<Rewards>(&data).unwrap())
}
fn read_protobuf_rewards(rewards_cf: &LedgerColumn<cf::Rewards>, slot: Slot) -> Option<Rewards> {
rewards_cf.get_protobuf(slot).unwrap().map(|r| r.into())
}
fn bench_write_rewards<F>(bench: &mut Bencher, ledger_path: &Path, write_method: F)
where
F: Fn(&LedgerColumn<cf::Rewards>, Slot, Rewards),
{
let blockstore =
Blockstore::open(ledger_path).expect("Expected to be able to open database ledger");
let rewards = create_rewards();
let mut slot = 0;
let rewards_cf = blockstore.db().column::<cf::Rewards>();
bench.iter(move || {
write_method(&rewards_cf, slot, rewards.clone());
slot += 1;
});
Blockstore::destroy(ledger_path).expect("Expected successful database destruction");
}
fn bench_read_rewards<F, G>(
bench: &mut Bencher,
ledger_path: &Path,
write_method: F,
read_method: G,
) where
F: Fn(&LedgerColumn<cf::Rewards>, Slot, Rewards),
G: Fn(&LedgerColumn<cf::Rewards>, Slot) -> Option<Rewards>,
{
let blockstore =
Blockstore::open(ledger_path).expect("Expected to be able to open database ledger");
let rewards = create_rewards();
let slot = 1;
let rewards_cf = blockstore.db().column::<cf::Rewards>();
write_method(&rewards_cf, slot, rewards);
bench.iter(move || read_method(&rewards_cf, slot));
Blockstore::destroy(ledger_path).expect("Expected successful database destruction");
}
#[bench]
fn bench_serialize_write_bincode(bencher: &mut Bencher) {
let ledger_path = get_tmp_ledger_path!();
bench_write_rewards(bencher, &ledger_path, write_bincode_rewards);
}
#[bench]
fn bench_serialize_write_protobuf(bencher: &mut Bencher) {
let ledger_path = get_tmp_ledger_path!();
bench_write_rewards(bencher, &ledger_path, write_protobuf_rewards);
}
#[bench]
fn bench_read_bincode(bencher: &mut Bencher) {
let ledger_path = get_tmp_ledger_path!();
bench_read_rewards(
bencher,
&ledger_path,
write_bincode_rewards,
read_bincode_rewards,
);
}
#[bench]
fn bench_read_protobuf(bencher: &mut Bencher) {
let ledger_path = get_tmp_ledger_path!();
bench_read_rewards(
bencher,
&ledger_path,
write_protobuf_rewards,
read_protobuf_rewards,
);
}

View File

@ -37,6 +37,7 @@ use solana_sdk::{
timing::timestamp,
transaction::Transaction,
};
use solana_storage_proto::StoredExtendedRewards;
use solana_transaction_status::{
ConfirmedBlock, ConfirmedTransaction, ConfirmedTransactionStatusWithSignature, Rewards,
TransactionStatusMeta, TransactionWithStatusMeta,
@ -1694,7 +1695,11 @@ 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)?.unwrap_or_else(Vec::new);
let rewards = self
.rewards_cf
.get_protobuf_or_bincode::<StoredExtendedRewards>(slot)?
.unwrap_or_default()
.into();
let block_time = self.blocktime_cf.get(slot)?;
let block = ConfirmedBlock {
@ -2256,11 +2261,14 @@ impl Blockstore {
}
pub fn read_rewards(&self, index: Slot) -> Result<Option<Rewards>> {
self.rewards_cf.get(index)
self.rewards_cf
.get_protobuf_or_bincode::<Rewards>(index)
.map(|result| result.map(|option| option.into()))
}
pub fn write_rewards(&self, index: Slot, rewards: Rewards) -> Result<()> {
self.rewards_cf.put(index, &rewards)
let rewards = rewards.into();
self.rewards_cf.put_protobuf(index, &rewards)
}
fn get_block_timestamps(&self, slot: Slot) -> Result<Vec<(Pubkey, (Slot, UnixTimestamp))>> {
@ -3446,7 +3454,7 @@ pub mod tests {
use bincode::serialize;
use itertools::Itertools;
use rand::{seq::SliceRandom, thread_rng};
use solana_runtime::bank::Bank;
use solana_runtime::bank::{Bank, RewardType};
use solana_sdk::{
hash::{self, hash, Hash},
instruction::CompiledInstruction,
@ -3456,7 +3464,8 @@ pub mod tests {
signature::Signature,
transaction::TransactionError,
};
use solana_transaction_status::InnerInstructions;
use solana_storage_proto::convert::generated;
use solana_transaction_status::{InnerInstructions, Reward, Rewards};
use solana_vote_program::{vote_instruction, vote_state::Vote};
use std::{iter::FromIterator, time::Duration};
@ -7239,4 +7248,44 @@ pub mod tests {
);
assert_eq!(completed_data_indexes, vec![0, 1, 3]);
}
#[test]
fn test_rewards_protobuf_backward_compatability() {
let blockstore_path = get_tmp_ledger_path!();
{
let blockstore = Blockstore::open(&blockstore_path).unwrap();
let rewards: Rewards = (0..100)
.map(|i| Reward {
pubkey: Pubkey::new_rand().to_string(),
lamports: 42 + i,
post_balance: std::u64::MAX,
reward_type: Some(RewardType::Fee),
})
.collect();
let protobuf_rewards: generated::Rewards = rewards.into();
let deprecated_rewards: StoredExtendedRewards = protobuf_rewards.clone().into();
for slot in 0..2 {
let data = serialize(&deprecated_rewards).unwrap();
blockstore.rewards_cf.put_bytes(slot, &data).unwrap();
}
for slot in 2..4 {
blockstore
.rewards_cf
.put_protobuf(slot, &protobuf_rewards)
.unwrap();
}
for slot in 0..4 {
assert_eq!(
blockstore
.rewards_cf
.get_protobuf_or_bincode::<StoredExtendedRewards>(slot)
.unwrap()
.unwrap(),
protobuf_rewards
);
}
}
Blockstore::destroy(&blockstore_path).expect("Expected successful database destruction");
}
}

View File

@ -2,6 +2,7 @@ use crate::blockstore_meta;
use bincode::{deserialize, serialize};
use byteorder::{BigEndian, ByteOrder};
use log::*;
use prost::Message;
pub use rocksdb::Direction as IteratorDirection;
use rocksdb::{
self, ColumnFamily, ColumnFamilyDescriptor, DBIterator, DBRawIterator, DBRecoveryMode,
@ -15,7 +16,8 @@ use solana_sdk::{
pubkey::Pubkey,
signature::Signature,
};
use solana_transaction_status::{Rewards, TransactionStatusMeta};
use solana_storage_proto::convert::generated;
use solana_transaction_status::TransactionStatusMeta;
use std::{collections::HashMap, fs, marker::PhantomData, path::Path, sync::Arc};
use thiserror::Error;
@ -71,6 +73,8 @@ pub enum BlockstoreError {
TransactionStatusSlotMismatch,
EmptyEpochStakes,
NoVoteTimestampsInRange,
ProtobufEncodeError(#[from] prost::EncodeError),
ProtobufDecodeError(#[from] prost::DecodeError),
}
pub type Result<T> = std::result::Result<T, BlockstoreError>;
@ -421,6 +425,10 @@ impl TypedColumn for columns::TransactionStatusIndex {
type Type = blockstore_meta::TransactionStatusIndexMeta;
}
pub trait ProtobufColumn: Column {
type Type: prost::Message + Default;
}
pub trait SlotColumn<Index = u64> {}
impl<T: SlotColumn> Column for T {
@ -543,8 +551,8 @@ impl SlotColumn for columns::Rewards {}
impl ColumnName for columns::Rewards {
const NAME: &'static str = REWARDS_CF;
}
impl TypedColumn for columns::Rewards {
type Type = Rewards;
impl ProtobufColumn for columns::Rewards {
type Type = generated::Rewards;
}
impl SlotColumn for columns::Blocktime {}
@ -921,6 +929,40 @@ where
}
}
impl<C> LedgerColumn<C>
where
C: ProtobufColumn + ColumnName,
{
pub fn get_protobuf_or_bincode<T: DeserializeOwned + Into<C::Type>>(
&self,
key: C::Index,
) -> Result<Option<C::Type>> {
if let Some(serialized_value) = self.backend.get_cf(self.handle(), &C::key(key))? {
let value = match C::Type::decode(&serialized_value[..]) {
Ok(value) => value,
Err(_) => deserialize::<T>(&serialized_value)?.into(),
};
Ok(Some(value))
} else {
Ok(None)
}
}
pub fn get_protobuf(&self, key: C::Index) -> Result<Option<C::Type>> {
if let Some(serialized_value) = self.backend.get_cf(self.handle(), &C::key(key))? {
Ok(Some(C::Type::decode(&serialized_value[..])?))
} else {
Ok(None)
}
}
pub fn put_protobuf(&self, key: C::Index, value: &C::Type) -> Result<()> {
let mut buf = Vec::with_capacity(value.encoded_len());
value.encode(&mut buf)?;
self.backend.put_cf(self.handle(), &C::key(key), &buf)
}
}
impl<'a> WriteBatch<'a> {
pub fn put_bytes<C: Column + ColumnName>(&mut self, key: C::Index, bytes: &[u8]) -> Result<()> {
self.write_batch

View File

@ -22,6 +22,7 @@ serde = "1.0.112"
serde_derive = "1.0.103"
smpl_jwt = "0.5.0"
solana-sdk = { path = "../sdk", version = "1.5.0" }
solana-storage-proto = { path = "../storage-proto", version = "1.5.0" }
solana-transaction-status = { path = "../transaction-status", version = "1.5.0" }
thiserror = "1.0"
futures = "0.3.5"

View File

@ -15,21 +15,5 @@ fn main() -> Result<(), std::io::Error> {
.compile(
&[googleapis.join("google/bigtable/v2/bigtable.proto")],
&[googleapis],
)?;
let out_dir = manifest_dir.join("../proto");
let proto_files = manifest_dir.join("../src");
println!("Protobuf directory: {}", proto_files.display());
println!("output directory: {}", out_dir.display());
tonic_build::configure()
.build_client(true)
.build_server(false)
.format(true)
.out_dir(&out_dir)
.compile(
&[proto_files.join("confirmed_block.proto")],
&[proto_files],
)
}

View File

@ -633,9 +633,10 @@ where
#[cfg(test)]
mod tests {
use super::*;
use crate::{convert::generated, StoredConfirmedBlock};
use crate::StoredConfirmedBlock;
use prost::Message;
use solana_sdk::{hash::Hash, pubkey::Pubkey, signature::Keypair, system_transaction};
use solana_storage_proto::convert::generated;
use solana_transaction_status::{
ConfirmedBlock, TransactionStatusMeta, TransactionWithStatusMeta,
};

View File

@ -7,6 +7,7 @@ use solana_sdk::{
sysvar::is_sysvar_id,
transaction::{Transaction, TransactionError},
};
use solana_storage_proto::convert::generated;
use solana_transaction_status::{
ConfirmedBlock, ConfirmedTransaction, ConfirmedTransactionStatusWithSignature, Reward,
TransactionStatus, TransactionStatusMeta, TransactionWithStatusMeta,
@ -20,11 +21,8 @@ extern crate serde_derive;
mod access_token;
mod bigtable;
mod compression;
mod convert;
mod root_ca_certificate;
use convert::generated;
#[derive(Debug, Error)]
pub enum Error {
#[error("BigTable: {0}")]

24
storage-proto/Cargo.toml Normal file
View File

@ -0,0 +1,24 @@
[package]
name = "solana-storage-proto"
version = "1.5.0"
description = "Solana Storage Protobuf Definitions"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
edition = "2018"
[dependencies]
bincode = "1.2.1"
prost = "0.6.1"
serde = "1.0.112"
serde_derive = "1.0.103"
solana-sdk = { path = "../sdk", version = "1.5.0" }
solana-transaction-status = { path = "../transaction-status", version = "1.5.0" }
[lib]
crate-type = ["lib"]
name = "solana_storage_proto"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

1
storage-proto/build-proto/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
target/

337
storage-proto/build-proto/Cargo.lock generated Normal file
View File

@ -0,0 +1,337 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "anyhow"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1fd36ffbb1fb7c834eac128ea8d0e310c5aeb635548f9d58861e1308d46e71c"
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bytes"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "fixedbitset"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
[[package]]
name = "getrandom"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hashbrown"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
[[package]]
name = "heck"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "indexmap"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "itertools"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
dependencies = [
"either",
]
[[package]]
name = "libc"
version = "0.2.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743"
[[package]]
name = "log"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
dependencies = [
"cfg-if",
]
[[package]]
name = "multimap"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1255076139a83bb467426e7f8d0134968a8118844faa755985e077cf31850333"
[[package]]
name = "petgraph"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
dependencies = [
"fixedbitset",
"indexmap",
]
[[package]]
name = "ppv-lite86"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20"
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "prost"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212"
dependencies = [
"bytes",
"prost-derive",
]
[[package]]
name = "prost-build"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b10678c913ecbd69350e8535c3aef91a8676c0773fc1d7b95cdd196d7f2f26"
dependencies = [
"bytes",
"heck",
"itertools",
"log",
"multimap",
"petgraph",
"prost",
"prost-types",
"tempfile",
"which",
]
[[package]]
name = "prost-derive"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72"
dependencies = [
"anyhow",
"itertools",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "prost-types"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa"
dependencies = [
"bytes",
"prost",
]
[[package]]
name = "proto"
version = "1.5.0"
dependencies = [
"tonic-build",
]
[[package]]
name = "quote"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom",
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core",
]
[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "remove_dir_all"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
"winapi",
]
[[package]]
name = "syn"
version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e03e57e4fcbfe7749842d53e24ccb9aa12b7252dbe5e91d2acad31834c8b8fdd"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "tempfile"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
dependencies = [
"cfg-if",
"libc",
"rand",
"redox_syscall",
"remove_dir_all",
"winapi",
]
[[package]]
name = "tonic-build"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d8d21cb568e802d77055ab7fcd43f0992206de5028de95c8d3a41118d32e8e"
dependencies = [
"proc-macro2",
"prost-build",
"quote",
"syn",
]
[[package]]
name = "unicode-segmentation"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "which"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
dependencies = [
"libc",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View File

@ -0,0 +1,15 @@
[package]
authors = ["Solana Maintainers <maintainers@solana.com>"]
description = "Blockchain, Rebuilt for Scale"
edition = "2018"
homepage = "https://solana.com/"
license = "Apache-2.0"
name = "proto"
publish = false
repository = "https://github.com/solana-labs/solana"
version = "1.5.0"
[workspace]
[dependencies]
tonic-build = "0.2.0"

View File

@ -0,0 +1,16 @@
fn main() -> Result<(), std::io::Error> {
let manifest_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let out_dir = manifest_dir.join("../proto");
let proto_files = manifest_dir.join("../src");
println!("Protobuf directory: {}", proto_files.display());
println!("output directory: {}", out_dir.display());
tonic_build::configure()
.build_client(true)
.build_server(false)
.format(true)
.out_dir(&out_dir)
.compile(&[proto_files.join("confirmed_block.proto")], &[proto_files])
}

View File

@ -95,6 +95,11 @@ pub struct Reward {
pub reward_type: i32,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Rewards {
#[prost(message, repeated, tag = "1")]
pub rewards: ::std::vec::Vec<Reward>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct UnixTimestamp {
#[prost(int64, tag = "1")]
pub timestamp: i64,

View File

@ -1,6 +1,6 @@
syntax = "proto3";
package solana.bigtable.ConfirmedBlock;
package solana.storage.ConfirmedBlock;
message ConfirmedBlock {
string previous_blockhash = 1;
@ -73,6 +73,10 @@ message Reward {
RewardType reward_type = 4;
}
message Rewards {
repeated Reward rewards = 1;
}
message UnixTimestamp {
int64 timestamp = 1;
}

View File

@ -1,3 +1,4 @@
use crate::StoredExtendedRewards;
use solana_sdk::{
hash::Hash,
instruction::CompiledInstruction,
@ -15,10 +16,51 @@ use std::convert::{TryFrom, TryInto};
pub mod generated {
include!(concat!(
env!("CARGO_MANIFEST_DIR"),
concat!("/proto/solana.bigtable.confirmed_block.rs")
concat!("/proto/solana.storage.confirmed_block.rs")
));
}
impl From<Vec<Reward>> for generated::Rewards {
fn from(rewards: Vec<Reward>) -> Self {
Self {
rewards: rewards.into_iter().map(|r| r.into()).collect(),
}
}
}
impl From<generated::Rewards> for Vec<Reward> {
fn from(rewards: generated::Rewards) -> Self {
rewards.rewards.into_iter().map(|r| r.into()).collect()
}
}
impl From<StoredExtendedRewards> for generated::Rewards {
fn from(rewards: StoredExtendedRewards) -> Self {
Self {
rewards: rewards
.into_iter()
.map(|r| {
let r: Reward = r.into();
r.into()
})
.collect(),
}
}
}
impl From<generated::Rewards> for StoredExtendedRewards {
fn from(rewards: generated::Rewards) -> Self {
rewards
.rewards
.into_iter()
.map(|r| {
let r: Reward = r.into();
r.into()
})
.collect()
}
}
impl From<Reward> for generated::Reward {
fn from(reward: Reward) -> Self {
Self {

52
storage-proto/src/lib.rs Normal file
View File

@ -0,0 +1,52 @@
use serde::{Deserialize, Serialize};
use solana_sdk::deserialize_utils::default_on_eof;
use solana_transaction_status::{Reward, RewardType};
pub mod convert;
pub type StoredExtendedRewards = Vec<StoredExtendedReward>;
#[derive(Serialize, Deserialize)]
pub struct StoredExtendedReward {
pubkey: String,
lamports: i64,
#[serde(deserialize_with = "default_on_eof")]
post_balance: u64,
#[serde(deserialize_with = "default_on_eof")]
reward_type: Option<RewardType>,
}
impl From<StoredExtendedReward> for Reward {
fn from(value: StoredExtendedReward) -> Self {
let StoredExtendedReward {
pubkey,
lamports,
post_balance,
reward_type,
} = value;
Self {
pubkey,
lamports,
post_balance,
reward_type,
}
}
}
impl From<Reward> for StoredExtendedReward {
fn from(value: Reward) -> Self {
let Reward {
pubkey,
lamports,
post_balance,
reward_type,
..
} = value;
Self {
pubkey,
lamports,
post_balance,
reward_type,
}
}
}

View File

@ -240,9 +240,7 @@ pub struct ConfirmedTransactionStatusWithSignature {
pub struct Reward {
pub pubkey: String,
pub lamports: i64,
#[serde(deserialize_with = "default_on_eof")]
pub post_balance: u64, // Account balance in lamports after `lamports` was applied
#[serde(default, deserialize_with = "default_on_eof")]
pub reward_type: Option<RewardType>,
}