From 6d3b8b6d7d5c8199b005ae13ec596bc1e4a25eda Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Wed, 15 Jan 2020 00:25:45 -0700 Subject: [PATCH] Remove tuples from JSON RPC responses (#7806) * Remove RpcConfirmedBlock tuple * Remove getRecentBlockhash tuple * Remove getProgramAccounts tuple * Remove tuple from get_signature_confirmation_status * Collect Rpc response types * Camel-case epoch schedule for rpc response * Remove getBlockCommitment tuple * Remove getStorageTurn tuple * Update json-rpc docs --- book/src/api-reference/jsonrpc-api.md | 38 ++-- cli/src/cli.rs | 7 +- cli/src/cluster_query.rs | 2 +- client/src/lib.rs | 1 + client/src/mock_rpc_client_request.rs | 5 +- client/src/rpc_client.rs | 18 +- client/src/rpc_request.rs | 194 +------------------- client/src/rpc_response.rs | 237 +++++++++++++++++++++++++ client/src/thin_client.rs | 3 +- core/src/archiver.rs | 21 ++- core/src/banking_stage.rs | 12 +- core/src/replay_stage.rs | 21 +-- core/src/rpc.rs | 185 +++++++++++-------- core/src/rpc_pubsub.rs | 4 +- core/src/rpc_subscriptions.rs | 4 +- core/src/transaction_status_service.rs | 2 +- core/tests/rpc.rs | 2 +- ledger/src/blockstore.rs | 34 ++-- ledger/src/blockstore_db.rs | 2 +- sdk/src/account.rs | 1 + sdk/src/epoch_schedule.rs | 1 + 21 files changed, 446 insertions(+), 348 deletions(-) create mode 100644 client/src/rpc_response.rs diff --git a/book/src/api-reference/jsonrpc-api.md b/book/src/api-reference/jsonrpc-api.md index ff9f1b04f..105366df4 100644 --- a/book/src/api-reference/jsonrpc-api.md +++ b/book/src/api-reference/jsonrpc-api.md @@ -193,13 +193,13 @@ Returns commitment for particular block #### Results: -The result field will be an array with two fields: +The result field will be a JSON object containing: -* Commitment +* `commitment` - commitment, comprising either: * `null` - Unknown block * `object` - BlockCommitment * `array` - commitment, array of u64 integers logging the amount of cluster stake in lamports that has voted on the block at each depth from 0 to `MAX_LOCKOUT_HISTORY` -* 'integer' - total active stake, in lamports, of the current epoch +* `totalStake` - total active stake, in lamports, of the current epoch #### Example: @@ -287,9 +287,9 @@ The result field will be an object with the following fields: * `blockhash` - the blockhash of this block, as base-58 encoded string * `previousBlockhash` - the blockhash of this block's parent, as base-58 encoded string * `parentSlot` - the slot index of this block's parent -* `transactions` - an array of tuples containing: - * [Transaction](transaction-api.md) object, either in JSON format or base-58 encoded binary data, depending on encoding parameter - * Transaction status object, containing: +* `transactions` - an array of JSON objects containing: + * `transaction` - [Transaction](transaction-api.md) object, either in JSON format or base-58 encoded binary data, depending on encoding parameter + * `meta` - transaction status metadata object, containing `null` or: * `status` - Transaction status: * `"Ok": null` - Transaction was successful * `"Err": ` - Transaction failed with TransactionError [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L14) @@ -376,11 +376,11 @@ None The result field will be an object with the following fields: -* `slots_per_epoch`, the maximum number of slots in each epoch -* `leader_schedule_slot_offset`, the number of slots before beginning of an epoch to calculate a leader schedule for that epoch +* `slotsPerEpoch`, the maximum number of slots in each epoch +* `leaderScheduleSlotOffset`, the number of slots before beginning of an epoch to calculate a leader schedule for that epoch * `warmup`, whether epochs start short and grow -* `first_normal_epoch`, first normal-length epoch, log2(slots_per_epoch) - log2(MINIMUM_SLOTS_PER_EPOCH) -* `first_normal_slot`, MINIMUM_SLOTS_PER_EPOCH * (2.pow(first_normal_epoch) - 1) +* `firstNormalEpoch`, first normal-length epoch, log2(slotsPerEpoch) - log2(MINIMUM_SLOTS_PER_EPOCH) +* `firstNormalSlot`, MINIMUM_SLOTS_PER_EPOCH * (2.pow(firstNormalEpoch) - 1) #### Example: @@ -389,7 +389,7 @@ The result field will be an object with the following fields: curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getEpochSchedule"}' http://localhost:8899 // Result -{"jsonrpc":"2.0","result":{"first_normal_epoch":8,"first_normal_slot":8160,"leader_schedule_slot_offset":8192,"slots_per_epoch":8192,"warmup":true},"id":1} +{"jsonrpc":"2.0","result":{"firstNormalEpoch":8,"firstNormalSlot":8160,"leaderScheduleSlotOffset":8192,"slotsPerEpoch":8192,"warmup":true},"id":1} ``` ### getGenesisHash @@ -526,9 +526,9 @@ Returns a recent block hash from the ledger, and a fee schedule that can be used An RpcResponse containing an array consisting of a string blockhash and FeeCalculator JSON object. -* `RpcResponse` - RpcResponse JSON object with `value` field set to an array including: -* `string` - a Hash as base-58 encoded string -* `FeeCalculator object` - the fee schedule for this block hash +* `RpcResponse` - RpcResponse JSON object with `value` field set to a JSON object including: +* `blockhash` - a Hash as base-58 encoded string +* `feeCalculator` - FeeCalculator object, the fee schedule for this block hash #### Example: @@ -641,10 +641,10 @@ None #### Results: -An array consisting of +A JSON object consisting of -* `string` - a Hash as base-58 encoded string indicating the blockhash of the turn slot -* `u64` - the current storage turn slot +* `blockhash` - a Hash as base-58 encoded string indicating the blockhash of the turn slot +* `slot` - the current storage turn slot #### Example: @@ -652,7 +652,7 @@ An array consisting of // Request curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getStorageTurn"}' http://localhost:8899 // Result -{"jsonrpc":"2.0","result":["GH7ome3EiwEr7tu9JuTh2dpYWBJK3z69Xm1ZE3MEE6JC", "2048"],"id":1} +{"jsonrpc":"2.0","result":{"blockhash": "GH7ome3EiwEr7tu9JuTh2dpYWBJK3z69Xm1ZE3MEE6JC", "slot": "2048"},"id":1} ``` ### getStorageTurnRate @@ -673,7 +673,7 @@ None // Request curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getStorageTurnRate"}' http://localhost:8899 // Result -{"jsonrpc":"2.0","result":"1024","id":1} +{"jsonrpc":"2.0","result":1024,"id":1} ``` ### getTransactionCount diff --git a/cli/src/cli.rs b/cli/src/cli.rs index 24e61e23b..28aef01e5 100644 --- a/cli/src/cli.rs +++ b/cli/src/cli.rs @@ -1989,7 +1989,8 @@ mod tests { use serde_json::Value; use solana_client::{ mock_rpc_client_request::SIGNATURE, - rpc_request::{self, RpcRequest, RpcResponseContext}, + rpc_request::RpcRequest, + rpc_response::{Response, RpcResponseContext}, }; use solana_sdk::{ account::Account, @@ -2669,7 +2670,7 @@ mod tests { // Nonced pay let blockhash = Hash::default(); - let nonce_response = json!(rpc_request::Response { + let nonce_response = json!(Response { context: RpcResponseContext { slot: 1 }, value: json!(Account::new_data( 1, @@ -2695,7 +2696,7 @@ mod tests { let bob_keypair = Keypair::new(); let bob_pubkey = bob_keypair.pubkey(); let blockhash = Hash::default(); - let nonce_authority_response = json!(rpc_request::Response { + let nonce_authority_response = json!(Response { context: RpcResponseContext { slot: 1 }, value: json!(Account::new_data( 1, diff --git a/cli/src/cluster_query.rs b/cli/src/cluster_query.rs index bacd467fd..f25f9db81 100644 --- a/cli/src/cluster_query.rs +++ b/cli/src/cluster_query.rs @@ -9,7 +9,7 @@ use clap::{value_t, value_t_or_exit, App, Arg, ArgMatches, SubCommand}; use console::{style, Emoji}; use indicatif::{ProgressBar, ProgressStyle}; use solana_clap_utils::{input_parsers::*, input_validators::*}; -use solana_client::{rpc_client::RpcClient, rpc_request::RpcVoteAccountInfo}; +use solana_client::{rpc_client::RpcClient, rpc_response::RpcVoteAccountInfo}; use solana_sdk::{ clock::{self, Slot}, commitment_config::CommitmentConfig, diff --git a/client/src/lib.rs b/client/src/lib.rs index 004223994..0d7ba4dae 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -8,4 +8,5 @@ pub mod perf_utils; pub mod rpc_client; pub mod rpc_client_request; pub mod rpc_request; +pub mod rpc_response; pub mod thin_client; diff --git a/client/src/mock_rpc_client_request.rs b/client/src/mock_rpc_client_request.rs index 0cda46712..d80152651 100644 --- a/client/src/mock_rpc_client_request.rs +++ b/client/src/mock_rpc_client_request.rs @@ -1,7 +1,8 @@ -use crate::rpc_request::{Response, RpcResponseContext}; use crate::{ - client_error::ClientError, generic_rpc_client_request::GenericRpcClientRequest, + client_error::ClientError, + generic_rpc_client_request::GenericRpcClientRequest, rpc_request::RpcRequest, + rpc_response::{Response, RpcResponseContext}, }; use serde_json::{Number, Value}; use solana_sdk::{ diff --git a/client/src/rpc_client.rs b/client/src/rpc_client.rs index f2504c2f8..417206345 100644 --- a/client/src/rpc_client.rs +++ b/client/src/rpc_client.rs @@ -1,12 +1,12 @@ -use crate::rpc_request::{Response, RpcResponse}; use crate::{ client_error::ClientError, generic_rpc_client_request::GenericRpcClientRequest, mock_rpc_client_request::{MockRpcClientRequest, Mocks}, rpc_client_request::RpcClientRequest, - rpc_request::{ - RpcConfirmedBlock, RpcContactInfo, RpcEpochInfo, RpcLeaderSchedule, RpcRequest, - RpcVersionInfo, RpcVoteAccountStatus, + rpc_request::RpcRequest, + rpc_response::{ + Response, RpcBlockhashFeeCalculator, RpcConfirmedBlock, RpcContactInfo, RpcEpochInfo, + RpcLeaderSchedule, RpcResponse, RpcVersionInfo, RpcVoteAccountStatus, }, }; use bincode::serialize; @@ -753,8 +753,12 @@ impl RpcClient { let Response { context, - value: (blockhash_str, fee_calculator), - } = serde_json::from_value::>(response).map_err( + value: + RpcBlockhashFeeCalculator { + blockhash, + fee_calculator, + }, + } = serde_json::from_value::>(response).map_err( |err| { io::Error::new( io::ErrorKind::Other, @@ -762,7 +766,7 @@ impl RpcClient { ) }, )?; - let blockhash = blockhash_str.parse().map_err(|err| { + let blockhash = blockhash.parse().map_err(|err| { io::Error::new( io::ErrorKind::Other, format!("GetRecentBlockhash hash parse failure: {:?}", err), diff --git a/client/src/rpc_request.rs b/client/src/rpc_request.rs index 2c01661b4..e2208ad38 100644 --- a/client/src/rpc_request.rs +++ b/client/src/rpc_request.rs @@ -1,197 +1,5 @@ -use bincode::serialize; -use jsonrpc_core::Result as JsonResult; use serde_json::{json, Value}; -use solana_sdk::{ - clock::{Epoch, Slot}, - message::MessageHeader, - transaction::{Result, Transaction}, -}; -use std::{collections::HashMap, error, fmt, io, net::SocketAddr}; - -pub type RpcResponseIn = JsonResult>; -pub type RpcResponse = io::Result>; - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct RpcResponseContext { - pub slot: u64, -} - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct Response { - pub context: RpcResponseContext, - pub value: T, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RpcConfirmedBlock { - pub previous_blockhash: String, - pub blockhash: String, - pub parent_slot: Slot, - pub transactions: Vec<(RpcEncodedTransaction, Option)>, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -#[serde(rename_all = "camelCase")] -pub enum RpcTransactionEncoding { - Binary, - Json, -} - -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase", untagged)] -pub enum RpcEncodedTransaction { - Binary(String), - Json(RpcTransaction), -} - -impl RpcEncodedTransaction { - pub fn encode(transaction: Transaction, encoding: RpcTransactionEncoding) -> Self { - if encoding == RpcTransactionEncoding::Json { - RpcEncodedTransaction::Json(RpcTransaction { - signatures: transaction - .signatures - .iter() - .map(|sig| sig.to_string()) - .collect(), - message: RpcMessage { - header: transaction.message.header, - account_keys: transaction - .message - .account_keys - .iter() - .map(|pubkey| pubkey.to_string()) - .collect(), - recent_blockhash: transaction.message.recent_blockhash.to_string(), - instructions: transaction - .message - .instructions - .iter() - .map(|instruction| RpcCompiledInstruction { - program_id_index: instruction.program_id_index, - accounts: instruction.accounts.clone(), - data: bs58::encode(instruction.data.clone()).into_string(), - }) - .collect(), - }, - }) - } else { - RpcEncodedTransaction::Binary( - bs58::encode(serialize(&transaction).unwrap()).into_string(), - ) - } - } -} - -/// A duplicate representation of a Transaction for pretty JSON serialization -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RpcTransaction { - pub signatures: Vec, - pub message: RpcMessage, -} - -/// A duplicate representation of a Message for pretty JSON serialization -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RpcMessage { - pub header: MessageHeader, - pub account_keys: Vec, - pub recent_blockhash: String, - pub instructions: Vec, -} - -/// A duplicate representation of a Message for pretty JSON serialization -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RpcCompiledInstruction { - pub program_id_index: u8, - pub accounts: Vec, - pub data: String, -} - -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RpcTransactionStatus { - pub status: Result<()>, - pub fee: u64, - pub pre_balances: Vec, - pub post_balances: Vec, -} - -#[derive(Serialize, Deserialize, Clone, Debug)] -pub struct RpcContactInfo { - /// Pubkey of the node as a base-58 string - pub pubkey: String, - /// Gossip port - pub gossip: Option, - /// Tpu port - pub tpu: Option, - /// JSON RPC port - pub rpc: Option, -} - -/// Map of leader base58 identity pubkeys to the slot indices relative to the first epoch slot -pub type RpcLeaderSchedule = HashMap>; - -#[derive(Serialize, Deserialize, Clone, Debug)] -#[serde(rename_all = "camelCase")] -pub struct RpcEpochInfo { - /// The current epoch - pub epoch: Epoch, - - /// The current slot, relative to the start of the current epoch - pub slot_index: u64, - - /// The number of slots in this epoch - pub slots_in_epoch: u64, - - /// The absolute current slot - pub absolute_slot: Slot, -} - -#[derive(Serialize, Deserialize, Clone, Debug)] -#[serde(rename_all = "kebab-case")] -pub struct RpcVersionInfo { - /// The current version of solana-core - pub solana_core: String, -} - -#[derive(Serialize, Deserialize, Clone, Debug)] -#[serde(rename_all = "camelCase")] -pub struct RpcVoteAccountStatus { - pub current: Vec, - pub delinquent: Vec, -} - -#[derive(Serialize, Deserialize, Clone, Debug)] -#[serde(rename_all = "camelCase")] -pub struct RpcVoteAccountInfo { - /// Vote account pubkey as base-58 encoded string - pub vote_pubkey: String, - - /// The pubkey of the node that votes using this account - pub node_pubkey: String, - - /// The current stake, in lamports, delegated to this vote account - pub activated_stake: u64, - - /// An 8-bit integer used as a fraction (commission/MAX_U8) for rewards payout - pub commission: u8, - - /// Whether this account is staked for the current epoch - pub epoch_vote_account: bool, - - /// History of how many credits earned by the end of each epoch - /// each tuple is (Epoch, credits, prev_credits) - pub epoch_credits: Vec<(Epoch, u64, u64)>, - - /// Most recent slot voted on by this vote account (0 if no votes exist) - pub last_vote: u64, - - /// Current root slot for this vote account (0 if not root slot exists) - pub root_slot: Slot, -} +use std::{error, fmt}; #[derive(Debug, PartialEq, Eq, Hash)] pub enum RpcRequest { diff --git a/client/src/rpc_response.rs b/client/src/rpc_response.rs new file mode 100644 index 000000000..ad334c921 --- /dev/null +++ b/client/src/rpc_response.rs @@ -0,0 +1,237 @@ +use bincode::serialize; +use jsonrpc_core::Result as JsonResult; +use solana_sdk::{ + account::Account, + clock::{Epoch, Slot}, + fee_calculator::FeeCalculator, + message::MessageHeader, + transaction::{Result, Transaction}, +}; +use std::{collections::HashMap, io, net::SocketAddr}; + +pub type RpcResponseIn = JsonResult>; +pub type RpcResponse = io::Result>; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct RpcResponseContext { + pub slot: u64, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct Response { + pub context: RpcResponseContext, + pub value: T, +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RpcBlockCommitment { + pub commitment: Option, + pub total_stake: u64, +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RpcConfirmedBlock { + pub previous_blockhash: String, + pub blockhash: String, + pub parent_slot: Slot, + pub transactions: Vec, +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RpcTransactionWithStatusMeta { + pub transaction: RpcEncodedTransaction, + pub meta: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "camelCase")] +pub enum RpcTransactionEncoding { + Binary, + Json, +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase", untagged)] +pub enum RpcEncodedTransaction { + Binary(String), + Json(RpcTransaction), +} + +impl RpcEncodedTransaction { + pub fn encode(transaction: Transaction, encoding: RpcTransactionEncoding) -> Self { + if encoding == RpcTransactionEncoding::Json { + RpcEncodedTransaction::Json(RpcTransaction { + signatures: transaction + .signatures + .iter() + .map(|sig| sig.to_string()) + .collect(), + message: RpcMessage { + header: transaction.message.header, + account_keys: transaction + .message + .account_keys + .iter() + .map(|pubkey| pubkey.to_string()) + .collect(), + recent_blockhash: transaction.message.recent_blockhash.to_string(), + instructions: transaction + .message + .instructions + .iter() + .map(|instruction| RpcCompiledInstruction { + program_id_index: instruction.program_id_index, + accounts: instruction.accounts.clone(), + data: bs58::encode(instruction.data.clone()).into_string(), + }) + .collect(), + }, + }) + } else { + RpcEncodedTransaction::Binary( + bs58::encode(serialize(&transaction).unwrap()).into_string(), + ) + } + } +} + +/// A duplicate representation of a Transaction for pretty JSON serialization +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RpcTransaction { + pub signatures: Vec, + pub message: RpcMessage, +} + +/// A duplicate representation of a Message for pretty JSON serialization +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RpcMessage { + pub header: MessageHeader, + pub account_keys: Vec, + pub recent_blockhash: String, + pub instructions: Vec, +} + +/// A duplicate representation of a Message for pretty JSON serialization +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RpcCompiledInstruction { + pub program_id_index: u8, + pub accounts: Vec, + pub data: String, +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RpcTransactionStatus { + pub status: Result<()>, + pub fee: u64, + pub pre_balances: Vec, + pub post_balances: Vec, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct RpcBlockhashFeeCalculator { + pub blockhash: String, + pub fee_calculator: FeeCalculator, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct RpcKeyedAccount { + pub pubkey: String, + pub account: Account, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct RpcContactInfo { + /// Pubkey of the node as a base-58 string + pub pubkey: String, + /// Gossip port + pub gossip: Option, + /// Tpu port + pub tpu: Option, + /// JSON RPC port + pub rpc: Option, +} + +/// Map of leader base58 identity pubkeys to the slot indices relative to the first epoch slot +pub type RpcLeaderSchedule = HashMap>; + +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct RpcEpochInfo { + /// The current epoch + pub epoch: Epoch, + + /// The current slot, relative to the start of the current epoch + pub slot_index: u64, + + /// The number of slots in this epoch + pub slots_in_epoch: u64, + + /// The absolute current slot + pub absolute_slot: Slot, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(rename_all = "kebab-case")] +pub struct RpcVersionInfo { + /// The current version of solana-core + pub solana_core: String, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct RpcVoteAccountStatus { + pub current: Vec, + pub delinquent: Vec, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct RpcVoteAccountInfo { + /// Vote account pubkey as base-58 encoded string + pub vote_pubkey: String, + + /// The pubkey of the node that votes using this account + pub node_pubkey: String, + + /// The current stake, in lamports, delegated to this vote account + pub activated_stake: u64, + + /// An 8-bit integer used as a fraction (commission/MAX_U8) for rewards payout + pub commission: u8, + + /// Whether this account is staked for the current epoch + pub epoch_vote_account: bool, + + /// History of how many credits earned by the end of each epoch + /// each tuple is (Epoch, credits, prev_credits) + pub epoch_credits: Vec<(Epoch, u64, u64)>, + + /// Most recent slot voted on by this vote account (0 if no votes exist) + pub last_vote: u64, + + /// Current root slot for this vote account (0 if not root slot exists) + pub root_slot: Slot, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct RpcSignatureConfirmation { + pub confirmations: usize, + pub status: Result<()>, +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct RpcStorageTurn { + pub blockhash: String, + pub slot: Slot, +} diff --git a/client/src/thin_client.rs b/client/src/thin_client.rs index 5eb33f613..00e656c01 100644 --- a/client/src/thin_client.rs +++ b/client/src/thin_client.rs @@ -3,8 +3,7 @@ //! messages to the network directly. The binary encoding of its messages are //! unstable and may change in future releases. -use crate::rpc_client::RpcClient; -use crate::rpc_request::Response; +use crate::{rpc_client::RpcClient, rpc_response::Response}; use bincode::{serialize_into, serialized_size}; use log::*; use solana_sdk::{ diff --git a/core/src/archiver.rs b/core/src/archiver.rs index 90417f46f..2b642cb2f 100644 --- a/core/src/archiver.rs +++ b/core/src/archiver.rs @@ -17,7 +17,10 @@ use crossbeam_channel::unbounded; use ed25519_dalek; use rand::{thread_rng, Rng, SeedableRng}; use rand_chacha::ChaChaRng; -use solana_client::{rpc_client::RpcClient, rpc_request::RpcRequest, thin_client::ThinClient}; +use solana_client::{ + rpc_client::RpcClient, rpc_request::RpcRequest, rpc_response::RpcStorageTurn, + thin_client::ThinClient, +}; use solana_ledger::{ blockstore::Blockstore, leader_schedule_cache::LeaderScheduleCache, shred::Shred, }; @@ -811,13 +814,15 @@ impl Archiver { warn!("Error while making rpc request {:?}", err); Error::IO(io::Error::new(ErrorKind::Other, "rpc error")) })?; - let (storage_blockhash, turn_slot) = - serde_json::from_value::<(String, u64)>(response).map_err(|err| { - io::Error::new( - io::ErrorKind::Other, - format!("Couldn't parse response: {:?}", err), - ) - })?; + let RpcStorageTurn { + blockhash: storage_blockhash, + slot: turn_slot, + } = serde_json::from_value::(response).map_err(|err| { + io::Error::new( + io::ErrorKind::Other, + format!("Couldn't parse response: {:?}", err), + ) + })?; let turn_blockhash = storage_blockhash.parse().map_err(|err| { io::Error::new( io::ErrorKind::Other, diff --git a/core/src/banking_stage.rs b/core/src/banking_stage.rs index 01a5a6ce9..872043689 100644 --- a/core/src/banking_stage.rs +++ b/core/src/banking_stage.rs @@ -1020,7 +1020,7 @@ mod tests { }; use crossbeam_channel::unbounded; use itertools::Itertools; - use solana_client::rpc_request::RpcEncodedTransaction; + use solana_client::rpc_response::{RpcEncodedTransaction, RpcTransactionWithStatusMeta}; use solana_ledger::{ blockstore::entries_to_test_shreds, entry::{next_entry, Entry, EntrySlice}, @@ -1978,20 +1978,22 @@ mod tests { let confirmed_block = blockstore.get_confirmed_block(bank.slot(), None).unwrap(); assert_eq!(confirmed_block.transactions.len(), 3); - for (transaction, result) in confirmed_block.transactions.into_iter() { + for RpcTransactionWithStatusMeta { transaction, meta } in + confirmed_block.transactions.into_iter() + { if let RpcEncodedTransaction::Json(transaction) = transaction { if transaction.signatures[0] == success_signature.to_string() { - assert_eq!(result.unwrap().status, Ok(())); + assert_eq!(meta.unwrap().status, Ok(())); } else if transaction.signatures[0] == ix_error_signature.to_string() { assert_eq!( - result.unwrap().status, + meta.unwrap().status, Err(TransactionError::InstructionError( 0, InstructionError::CustomError(1) )) ); } else { - assert_eq!(result, None); + assert_eq!(meta, None); } } } diff --git a/core/src/replay_stage.rs b/core/src/replay_stage.rs index 82e568805..97d071cc5 100644 --- a/core/src/replay_stage.rs +++ b/core/src/replay_stage.rs @@ -997,7 +997,7 @@ pub(crate) mod tests { transaction_status_service::TransactionStatusService, }; use crossbeam_channel::unbounded; - use solana_client::rpc_request::RpcEncodedTransaction; + use solana_client::rpc_response::{RpcEncodedTransaction, RpcTransactionWithStatusMeta}; use solana_ledger::{ block_error::BlockError, blockstore::make_slot_entries, @@ -1011,22 +1011,21 @@ pub(crate) mod tests { }, }; use solana_runtime::genesis_utils::GenesisConfigInfo; - use solana_sdk::account::Account; - use solana_sdk::rent::Rent; use solana_sdk::{ + account::Account, hash::{hash, Hash}, instruction::InstructionError, packet::PACKET_DATA_SIZE, + rent::Rent, signature::{Keypair, KeypairUtil, Signature}, system_transaction, transaction::TransactionError, }; use solana_stake_program::stake_state; - use solana_vote_program::vote_state; - use solana_vote_program::vote_state::{Vote, VoteState}; - use std::iter; + use solana_vote_program::vote_state::{self, Vote, VoteState}; use std::{ fs::remove_dir_all, + iter, sync::{Arc, RwLock}, }; @@ -1803,20 +1802,22 @@ pub(crate) mod tests { let confirmed_block = blockstore.get_confirmed_block(slot, None).unwrap(); assert_eq!(confirmed_block.transactions.len(), 3); - for (transaction, result) in confirmed_block.transactions.into_iter() { + for RpcTransactionWithStatusMeta { transaction, meta } in + confirmed_block.transactions.into_iter() + { if let RpcEncodedTransaction::Json(transaction) = transaction { if transaction.signatures[0] == signatures[0].to_string() { - assert_eq!(result.unwrap().status, Ok(())); + assert_eq!(meta.unwrap().status, Ok(())); } else if transaction.signatures[0] == signatures[1].to_string() { assert_eq!( - result.unwrap().status, + meta.unwrap().status, Err(TransactionError::InstructionError( 0, InstructionError::CustomError(1) )) ); } else { - assert_eq!(result, None); + assert_eq!(meta, None); } } } diff --git a/core/src/rpc.rs b/core/src/rpc.rs index 80d1a5508..53eff156f 100644 --- a/core/src/rpc.rs +++ b/core/src/rpc.rs @@ -11,9 +11,10 @@ use crate::{ use bincode::serialize; use jsonrpc_core::{Error, Metadata, Result}; use jsonrpc_derive::rpc; -use solana_client::rpc_request::{ - Response, RpcConfirmedBlock, RpcContactInfo, RpcEpochInfo, RpcLeaderSchedule, - RpcResponseContext, RpcTransactionEncoding, RpcVersionInfo, RpcVoteAccountInfo, +use solana_client::rpc_response::{ + Response, RpcBlockCommitment, RpcBlockhashFeeCalculator, RpcConfirmedBlock, RpcContactInfo, + RpcEpochInfo, RpcKeyedAccount, RpcLeaderSchedule, RpcResponseContext, RpcSignatureConfirmation, + RpcStorageTurn, RpcTransactionEncoding, RpcVersionInfo, RpcVoteAccountInfo, RpcVoteAccountStatus, }; use solana_faucet::faucet::request_airdrop_transaction; @@ -26,7 +27,6 @@ use solana_sdk::{ clock::{Slot, UnixTimestamp}, commitment_config::{CommitmentConfig, CommitmentLevel}, epoch_schedule::EpochSchedule, - fee_calculator::FeeCalculator, hash::Hash, inflation::Inflation, pubkey::Pubkey, @@ -134,12 +134,15 @@ impl JsonRpcRequestProcessor { &self, program_id: &Pubkey, commitment: Option, - ) -> Result> { + ) -> Result> { Ok(self .bank(commitment) .get_program_accounts(&program_id) .into_iter() - .map(|(pubkey, account)| (pubkey.to_string(), account)) + .map(|(pubkey, account)| RpcKeyedAccount { + pubkey: pubkey.to_string(), + account, + }) .collect()) } @@ -168,10 +171,16 @@ impl JsonRpcRequestProcessor { fn get_recent_blockhash( &self, commitment: Option, - ) -> RpcResponse<(String, FeeCalculator)> { + ) -> RpcResponse { let bank = &*self.bank(commitment); let (blockhash, fee_calculator) = bank.confirmed_last_blockhash(); - new_response(bank, (blockhash.to_string(), fee_calculator)) + new_response( + bank, + RpcBlockhashFeeCalculator { + blockhash: blockhash.to_string(), + fee_calculator, + }, + ) } pub fn confirm_transaction( @@ -192,21 +201,25 @@ impl JsonRpcRequestProcessor { } } - fn get_block_commitment(&self, block: Slot) -> (Option, u64) { + fn get_block_commitment(&self, block: Slot) -> RpcBlockCommitment { let r_block_commitment = self.block_commitment_cache.read().unwrap(); - ( - r_block_commitment.get_block_commitment(block).cloned(), - r_block_commitment.total_stake(), - ) + RpcBlockCommitment { + commitment: r_block_commitment.get_block_commitment(block).cloned(), + total_stake: r_block_commitment.total_stake(), + } } pub fn get_signature_confirmation_status( &self, signature: Signature, commitment: Option, - ) -> Option<(usize, transaction::Result<()>)> { + ) -> Option { self.bank(commitment) .get_signature_confirmation_status(&signature) + .map(|(confirmations, status)| RpcSignatureConfirmation { + confirmations, + status, + }) } fn get_slot(&self, commitment: Option) -> Result { @@ -283,11 +296,11 @@ impl JsonRpcRequestProcessor { Ok(self.storage_state.get_storage_turn_rate()) } - fn get_storage_turn(&self) -> Result<(String, u64)> { - Ok(( - self.storage_state.get_storage_blockhash().to_string(), - self.storage_state.get_slot(), - )) + fn get_storage_turn(&self) -> Result { + Ok(RpcStorageTurn { + blockhash: self.storage_state.get_storage_blockhash().to_string(), + slot: self.storage_state.get_slot(), + }) } fn get_slots_per_segment(&self, commitment: Option) -> Result { @@ -407,7 +420,7 @@ pub trait RpcSol { meta: Self::Metadata, program_id_str: String, commitment: Option, - ) -> Result>; + ) -> Result>; #[rpc(meta, name = "getMinimumBalanceForRentExemption")] fn get_minimum_balance_for_rent_exemption( @@ -450,7 +463,7 @@ pub trait RpcSol { &self, meta: Self::Metadata, block: Slot, - ) -> Result<(Option, u64)>; + ) -> Result>; #[rpc(meta, name = "getGenesisHash")] fn get_genesis_hash(&self, meta: Self::Metadata) -> Result; @@ -468,7 +481,7 @@ pub trait RpcSol { &self, meta: Self::Metadata, commitment: Option, - ) -> RpcResponse<(String, FeeCalculator)>; + ) -> RpcResponse; #[rpc(meta, name = "getSignatureStatus")] fn get_signature_status( @@ -525,7 +538,7 @@ pub trait RpcSol { fn get_storage_turn_rate(&self, meta: Self::Metadata) -> Result; #[rpc(meta, name = "getStorageTurn")] - fn get_storage_turn(&self, meta: Self::Metadata) -> Result<(String, u64)>; + fn get_storage_turn(&self, meta: Self::Metadata) -> Result; #[rpc(meta, name = "getSlotsPerSegment")] fn get_slots_per_segment( @@ -554,7 +567,7 @@ pub trait RpcSol { meta: Self::Metadata, signature_str: String, commitment: Option, - ) -> Result)>>; + ) -> Result>; #[rpc(meta, name = "getVersion")] fn get_version(&self, meta: Self::Metadata) -> Result; @@ -635,7 +648,7 @@ impl RpcSol for RpcSolImpl { meta: Self::Metadata, program_id_str: String, commitment: Option, - ) -> Result> { + ) -> Result> { debug!( "get_program_accounts rpc request received: {:?}", program_id_str @@ -734,7 +747,7 @@ impl RpcSol for RpcSolImpl { &self, meta: Self::Metadata, block: Slot, - ) -> Result<(Option, u64)> { + ) -> Result> { Ok(meta .request_processor .read() @@ -778,7 +791,7 @@ impl RpcSol for RpcSolImpl { &self, meta: Self::Metadata, commitment: Option, - ) -> RpcResponse<(String, FeeCalculator)> { + ) -> RpcResponse { debug!("get_recent_blockhash rpc request received"); meta.request_processor .read() @@ -793,7 +806,7 @@ impl RpcSol for RpcSolImpl { commitment: Option, ) -> Result>> { self.get_signature_confirmation(meta, signature_str, commitment) - .map(|res| res.map(|x| x.1)) + .map(|res| res.map(|x| x.status)) } fn get_slot(&self, meta: Self::Metadata, commitment: Option) -> Result { @@ -807,7 +820,7 @@ impl RpcSol for RpcSolImpl { commitment: Option, ) -> Result> { self.get_signature_confirmation(meta, signature_str, commitment) - .map(|res| res.map(|x| x.0)) + .map(|res| res.map(|x| x.confirmations)) } fn get_signature_confirmation( @@ -815,7 +828,7 @@ impl RpcSol for RpcSolImpl { meta: Self::Metadata, signature_str: String, commitment: Option, - ) -> Result)>> { + ) -> Result> { debug!( "get_signature_confirmation rpc request received: {:?}", signature_str @@ -915,7 +928,7 @@ impl RpcSol for RpcSolImpl { .read() .unwrap() .get_signature_confirmation_status(signature, commitment.clone()) - .map(|x| x.1); + .map(|x| x.status); if signature_status == Some(Ok(())) { info!("airdrop signature ok"); @@ -992,7 +1005,7 @@ impl RpcSol for RpcSolImpl { .get_storage_turn_rate() } - fn get_storage_turn(&self, meta: Self::Metadata) -> Result<(String, u64)> { + fn get_storage_turn(&self, meta: Self::Metadata) -> Result { meta.request_processor.read().unwrap().get_storage_turn() } @@ -1072,7 +1085,7 @@ pub mod tests { }; use bincode::deserialize; use jsonrpc_core::{MetaIoHandler, Output, Response, Value}; - use solana_client::rpc_request::RpcEncodedTransaction; + use solana_client::rpc_response::{RpcEncodedTransaction, RpcTransactionWithStatusMeta}; use solana_ledger::{ blockstore::entries_to_test_shreds, blockstore_processor::fill_blockstore_slot_with_ticks, entry::next_entry_mut, get_tmp_ledger_path, @@ -1538,7 +1551,7 @@ pub mod tests { "lamports": 20, "data": [], "executable": false, - "rent_epoch": 0 + "rentEpoch": 0 }, }, "id": 1, @@ -1572,13 +1585,18 @@ pub mod tests { let expected = format!( r#"{{ "jsonrpc":"2.0", - "result":[["{}", {{ - "owner": {:?}, - "lamports": 20, - "data": [], - "executable": false, - "rent_epoch": 0 - }}]], + "result":[ + {{ + "pubkey": "{}", + "account": {{ + "owner": {:?}, + "lamports": 20, + "data": [], + "executable": false, + "rentEpoch": 0 + }} + }} + ], "id":1}} "#, bob.pubkey(), @@ -1709,14 +1727,17 @@ pub mod tests { "jsonrpc": "2.0", "result": { "context":{"slot":0}, - "value":[ blockhash.to_string(), { - "burnPercent": DEFAULT_BURN_PERCENT, - "lamportsPerSignature": 0, - "maxLamportsPerSignature": 0, - "minLamportsPerSignature": 0, - "targetLamportsPerSignature": 0, - "targetSignaturesPerSlot": 0 - }]}, + "value":{ + "blockhash": blockhash.to_string(), + "feeCalculator": { + "burnPercent": DEFAULT_BURN_PERCENT, + "lamportsPerSignature": 0, + "maxLamportsPerSignature": 0, + "minLamportsPerSignature": 0, + "targetLamportsPerSignature": 0, + "targetSignaturesPerSlot": 0 + } + }}, "id": 1 }); let expected: Response = @@ -1941,13 +1962,25 @@ pub mod tests { ); assert_eq!( request_processor.get_block_commitment(0), - (Some(commitment_slot0), 42) + RpcBlockCommitment { + commitment: Some(commitment_slot0), + total_stake: 42, + } ); assert_eq!( request_processor.get_block_commitment(1), - (Some(commitment_slot1), 42) + RpcBlockCommitment { + commitment: Some(commitment_slot1), + total_stake: 42, + } + ); + assert_eq!( + request_processor.get_block_commitment(2), + RpcBlockCommitment { + commitment: None, + total_stake: 42, + } ); - assert_eq!(request_processor.get_block_commitment(2), (None, 42)); } #[test] @@ -1965,16 +1998,18 @@ pub mod tests { let res = io.handle_request_sync(&req, meta.clone()); let result: Response = serde_json::from_str(&res.expect("actual response")) .expect("actual response deserialization"); - let (commitment, total_staked): (Option, u64) = - if let Response::Single(res) = result { - if let Output::Success(res) = res { - serde_json::from_value(res.result).unwrap() - } else { - panic!("Expected success"); - } + let RpcBlockCommitment { + commitment, + total_stake, + } = if let Response::Single(res) = result { + if let Output::Success(res) = res { + serde_json::from_value(res.result).unwrap() } else { - panic!("Expected single response"); - }; + panic!("Expected success"); + } + } else { + panic!("Expected single response"); + }; assert_eq!( commitment, block_commitment_cache @@ -1983,14 +2018,14 @@ pub mod tests { .get_block_commitment(0) .cloned() ); - assert_eq!(total_staked, 42); + assert_eq!(total_stake, 42); let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getBlockCommitment","params":[2]}}"#); let res = io.handle_request_sync(&req, meta); let result: Response = serde_json::from_str(&res.expect("actual response")) .expect("actual response deserialization"); - let (commitment, total_staked): (Option, u64) = + let commitment_response: RpcBlockCommitment = if let Response::Single(res) = result { if let Output::Success(res) = res { serde_json::from_value(res.result).unwrap() @@ -2000,8 +2035,8 @@ pub mod tests { } else { panic!("Expected single response"); }; - assert_eq!(commitment, None); - assert_eq!(total_staked, 42); + assert_eq!(commitment_response.commitment, None); + assert_eq!(commitment_response.total_stake, 42); } #[test] @@ -2025,21 +2060,23 @@ pub mod tests { let confirmed_block = confirmed_block.unwrap(); assert_eq!(confirmed_block.transactions.len(), 3); - for (transaction, result) in confirmed_block.transactions.into_iter() { + for RpcTransactionWithStatusMeta { transaction, meta } in + confirmed_block.transactions.into_iter() + { if let RpcEncodedTransaction::Json(transaction) = transaction { if transaction.signatures[0] == confirmed_block_signatures[0].to_string() { assert_eq!(transaction.message.recent_blockhash, blockhash.to_string()); - assert_eq!(result.unwrap().status, Ok(())); + assert_eq!(meta.unwrap().status, Ok(())); } else if transaction.signatures[0] == confirmed_block_signatures[1].to_string() { assert_eq!( - result.unwrap().status, + meta.unwrap().status, Err(TransactionError::InstructionError( 0, InstructionError::CustomError(1) )) ); } else { - assert_eq!(result, None); + assert_eq!(meta, None); } } } @@ -2055,23 +2092,25 @@ pub mod tests { let confirmed_block = confirmed_block.unwrap(); assert_eq!(confirmed_block.transactions.len(), 3); - for (transaction, result) in confirmed_block.transactions.into_iter() { + for RpcTransactionWithStatusMeta { transaction, meta } in + confirmed_block.transactions.into_iter() + { if let RpcEncodedTransaction::Binary(transaction) = transaction { let decoded_transaction: Transaction = deserialize(&bs58::decode(&transaction).into_vec().unwrap()).unwrap(); if decoded_transaction.signatures[0] == confirmed_block_signatures[0] { assert_eq!(decoded_transaction.message.recent_blockhash, blockhash); - assert_eq!(result.unwrap().status, Ok(())); + assert_eq!(meta.unwrap().status, Ok(())); } else if decoded_transaction.signatures[0] == confirmed_block_signatures[1] { assert_eq!( - result.unwrap().status, + meta.unwrap().status, Err(TransactionError::InstructionError( 0, InstructionError::CustomError(1) )) ); } else { - assert_eq!(result, None); + assert_eq!(meta, None); } } } diff --git a/core/src/rpc_pubsub.rs b/core/src/rpc_pubsub.rs index 274d648b5..6cc152f15 100644 --- a/core/src/rpc_pubsub.rs +++ b/core/src/rpc_pubsub.rs @@ -471,7 +471,7 @@ mod tests { "lamports": 51, "data": expected_data, "executable": false, - "rent_epoch": 1, + "rentEpoch": 1, }, "subscription": 0, } @@ -618,7 +618,7 @@ mod tests { "lamports": 100, "data": [], "executable": false, - "rent_epoch": 1, + "rentEpoch": 1, }, "subscription": 0, } diff --git a/core/src/rpc_subscriptions.rs b/core/src/rpc_subscriptions.rs index 5c913b1a0..d2fcf2a0a 100644 --- a/core/src/rpc_subscriptions.rs +++ b/core/src/rpc_subscriptions.rs @@ -376,7 +376,7 @@ mod tests { let string = transport_receiver.poll(); if let Async::Ready(Some(response)) = string.unwrap() { let expected = format!( - r#"{{"jsonrpc":"2.0","method":"accountNotification","params":{{"result":{{"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"executable":false,"lamports":1,"owner":[2,203,81,223,225,24,34,35,203,214,138,130,144,208,35,77,63,16,87,51,47,198,115,123,98,188,19,160,0,0,0,0],"rent_epoch":1}},"subscription":0}}}}"# + r#"{{"jsonrpc":"2.0","method":"accountNotification","params":{{"result":{{"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"executable":false,"lamports":1,"owner":[2,203,81,223,225,24,34,35,203,214,138,130,144,208,35,77,63,16,87,51,47,198,115,123,98,188,19,160,0,0,0,0],"rentEpoch":1}},"subscription":0}}}}"# ); assert_eq!(expected, response); } @@ -433,7 +433,7 @@ mod tests { let string = transport_receiver.poll(); if let Async::Ready(Some(response)) = string.unwrap() { let expected = format!( - r#"{{"jsonrpc":"2.0","method":"programNotification","params":{{"result":["{:?}",{{"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"executable":false,"lamports":1,"owner":[2,203,81,223,225,24,34,35,203,214,138,130,144,208,35,77,63,16,87,51,47,198,115,123,98,188,19,160,0,0,0,0],"rent_epoch":1}}],"subscription":0}}}}"#, + r#"{{"jsonrpc":"2.0","method":"programNotification","params":{{"result":["{:?}",{{"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"executable":false,"lamports":1,"owner":[2,203,81,223,225,24,34,35,203,214,138,130,144,208,35,77,63,16,87,51,47,198,115,123,98,188,19,160,0,0,0,0],"rentEpoch":1}}],"subscription":0}}}}"#, alice.pubkey() ); assert_eq!(expected, response); diff --git a/core/src/transaction_status_service.rs b/core/src/transaction_status_service.rs index 9386b9092..0e9e16f90 100644 --- a/core/src/transaction_status_service.rs +++ b/core/src/transaction_status_service.rs @@ -1,5 +1,5 @@ use crossbeam_channel::{Receiver, RecvTimeoutError}; -use solana_client::rpc_request::RpcTransactionStatus; +use solana_client::rpc_response::RpcTransactionStatus; use solana_ledger::{blockstore::Blockstore, blockstore_processor::TransactionStatusBatch}; use solana_runtime::bank::{Bank, HashAgeKind}; use std::{ diff --git a/core/tests/rpc.rs b/core/tests/rpc.rs index af459b431..fa4438c56 100644 --- a/core/tests/rpc.rs +++ b/core/tests/rpc.rs @@ -34,7 +34,7 @@ fn test_rpc_send_tx() { .send() .unwrap(); let json: Value = serde_json::from_str(&response.text().unwrap()).unwrap(); - let blockhash: Hash = json["result"]["value"][0] + let blockhash: Hash = json["result"]["value"]["blockhash"] .as_str() .unwrap() .parse() diff --git a/ledger/src/blockstore.rs b/ledger/src/blockstore.rs index e5cc53d38..c4298f1e6 100644 --- a/ledger/src/blockstore.rs +++ b/ledger/src/blockstore.rs @@ -21,8 +21,9 @@ use rayon::{ ThreadPool, }; use rocksdb::DBRawIterator; -use solana_client::rpc_request::{ +use solana_client::rpc_response::{ RpcConfirmedBlock, RpcEncodedTransaction, RpcTransactionEncoding, RpcTransactionStatus, + RpcTransactionWithStatusMeta, }; use solana_measure::measure::Measure; use solana_metrics::{datapoint_debug, datapoint_error}; @@ -1403,18 +1404,19 @@ impl Blockstore { slot: Slot, encoding: RpcTransactionEncoding, iterator: impl Iterator + 'a, - ) -> Vec<(RpcEncodedTransaction, Option)> { + ) -> Vec { iterator .map(|transaction| { let signature = transaction.signatures[0]; let encoded_transaction = RpcEncodedTransaction::encode(transaction, encoding.clone()); - ( - encoded_transaction, - self.transaction_status_cf + RpcTransactionWithStatusMeta { + transaction: encoded_transaction, + meta: self + .transaction_status_cf .get((slot, signature)) .expect("Expect database get to succeed"), - ) + } }) .collect() } @@ -4748,11 +4750,9 @@ pub mod tests { transactions: expected_transactions .iter() .cloned() - .map(|(tx, status)| { - ( - RpcEncodedTransaction::encode(tx, RpcTransactionEncoding::Json), - status, - ) + .map(|(tx, meta)| RpcTransactionWithStatusMeta { + transaction: RpcEncodedTransaction::encode(tx, RpcTransactionEncoding::Json), + meta, }) .collect(), parent_slot: slot - 1, @@ -4770,11 +4770,9 @@ pub mod tests { transactions: expected_transactions .iter() .cloned() - .map(|(tx, status)| { - ( - RpcEncodedTransaction::encode(tx, RpcTransactionEncoding::Json), - status, - ) + .map(|(tx, meta)| RpcTransactionWithStatusMeta { + transaction: RpcEncodedTransaction::encode(tx, RpcTransactionEncoding::Json), + meta, }) .collect(), parent_slot: slot, @@ -5007,9 +5005,9 @@ pub mod tests { ); assert_eq!(map.len(), 5); for x in 0..4 { - assert_eq!(map[x].1.as_ref().unwrap().fee, x as u64); + assert_eq!(map[x].meta.as_ref().unwrap().fee, x as u64); } - assert_eq!(map[4].1.as_ref(), None); + assert_eq!(map[4].meta, None); } Blockstore::destroy(&blockstore_path).expect("Expected successful database destruction"); } diff --git a/ledger/src/blockstore_db.rs b/ledger/src/blockstore_db.rs index e61b5fffe..acb8fff7b 100644 --- a/ledger/src/blockstore_db.rs +++ b/ledger/src/blockstore_db.rs @@ -10,7 +10,7 @@ use rocksdb::{ }; use serde::de::DeserializeOwned; use serde::Serialize; -use solana_client::rpc_request::RpcTransactionStatus; +use solana_client::rpc_response::RpcTransactionStatus; use solana_sdk::{clock::Slot, signature::Signature}; use std::{collections::HashMap, fs, marker::PhantomData, path::Path, sync::Arc}; use thiserror::Error; diff --git a/sdk/src/account.rs b/sdk/src/account.rs index 1219fcce5..7dd9b24b5 100644 --- a/sdk/src/account.rs +++ b/sdk/src/account.rs @@ -5,6 +5,7 @@ use std::{cmp, fmt, iter::FromIterator}; /// An Account with data that is stored on chain #[repr(C)] #[derive(Serialize, Deserialize, Clone, Default)] +#[serde(rename_all = "camelCase")] pub struct Account { /// lamports in the account pub lamports: u64, diff --git a/sdk/src/epoch_schedule.rs b/sdk/src/epoch_schedule.rs index 514ef19a5..b2ce557af 100644 --- a/sdk/src/epoch_schedule.rs +++ b/sdk/src/epoch_schedule.rs @@ -13,6 +13,7 @@ pub const MINIMUM_SLOTS_PER_EPOCH: u64 = 32; #[repr(C)] #[derive(Debug, Clone, Copy, PartialEq, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] pub struct EpochSchedule { /// The maximum number of slots in each epoch. pub slots_per_epoch: u64,