move rpc types from client to client-types crate (#9039)

* Separate client types into own crate, so ledger does not need it

Removes about 50 crates of dependency from ledger

* Drop Rpc name from transaction-status types
This commit is contained in:
sakridge
2020-03-26 13:29:30 -07:00
committed by GitHub
parent ed036b978d
commit b7b4aa5d4d
17 changed files with 241 additions and 205 deletions

15
Cargo.lock generated
View File

@ -3898,6 +3898,7 @@ dependencies = [
"solana-logger 1.1.0", "solana-logger 1.1.0",
"solana-net-utils 1.1.0", "solana-net-utils 1.1.0",
"solana-sdk 1.1.0", "solana-sdk 1.1.0",
"solana-transaction-status 1.1.0",
"solana-vote-program 1.1.0", "solana-vote-program 1.1.0",
"thiserror 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
"tungstenite 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "tungstenite 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3972,6 +3973,7 @@ dependencies = [
"solana-storage-program 1.1.0", "solana-storage-program 1.1.0",
"solana-streamer 1.1.0", "solana-streamer 1.1.0",
"solana-sys-tuner 1.1.0", "solana-sys-tuner 1.1.0",
"solana-transaction-status 1.1.0",
"solana-vote-program 1.1.0", "solana-vote-program 1.1.0",
"solana-vote-signer 1.1.0", "solana-vote-signer 1.1.0",
"systemstat 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "systemstat 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -4205,7 +4207,6 @@ dependencies = [
"serde_bytes 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-budget-program 1.1.0", "solana-budget-program 1.1.0",
"solana-client 1.1.0",
"solana-genesis-programs 1.1.0", "solana-genesis-programs 1.1.0",
"solana-logger 1.1.0", "solana-logger 1.1.0",
"solana-measure 1.1.0", "solana-measure 1.1.0",
@ -4217,6 +4218,7 @@ dependencies = [
"solana-runtime 1.1.0", "solana-runtime 1.1.0",
"solana-sdk 1.1.0", "solana-sdk 1.1.0",
"solana-stake-program 1.1.0", "solana-stake-program 1.1.0",
"solana-transaction-status 1.1.0",
"solana-vote-program 1.1.0", "solana-vote-program 1.1.0",
"symlink 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "symlink 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)",
@ -4645,6 +4647,17 @@ dependencies = [
"users 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "users 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "solana-transaction-status"
version = "1.1.0"
dependencies = [
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
"solana-sdk 1.1.0",
]
[[package]] [[package]]
name = "solana-upload-perf" name = "solana-upload-perf"
version = "1.1.0" version = "1.1.0"

View File

@ -53,6 +53,7 @@ members = [
"sdk-c", "sdk-c",
"scripts", "scripts",
"sys-tuner", "sys-tuner",
"transaction-status",
"upload-perf", "upload-perf",
"net-utils", "net-utils",
"vote-signer", "vote-signer",

View File

@ -19,6 +19,7 @@ reqwest = { version = "0.10.4", default-features = false, features = ["blocking"
serde = "1.0.105" serde = "1.0.105"
serde_derive = "1.0.103" serde_derive = "1.0.103"
serde_json = "1.0.48" serde_json = "1.0.48"
solana-transaction-status = { path = "../transaction-status", version = "1.1.0" }
solana-net-utils = { path = "../net-utils", version = "1.1.0" } solana-net-utils = { path = "../net-utils", version = "1.1.0" }
solana-sdk = { path = "../sdk", version = "1.1.0" } solana-sdk = { path = "../sdk", version = "1.1.0" }
solana-vote-program = { path = "../programs/vote", version = "1.1.0" } solana-vote-program = { path = "../programs/vote", version = "1.1.0" }

View File

@ -2,7 +2,7 @@ use crate::{
client_error::Result, client_error::Result,
generic_rpc_client_request::GenericRpcClientRequest, generic_rpc_client_request::GenericRpcClientRequest,
rpc_request::RpcRequest, rpc_request::RpcRequest,
rpc_response::{Response, RpcResponseContext, RpcTransactionStatus}, rpc_response::{Response, RpcResponseContext},
}; };
use serde_json::{Number, Value}; use serde_json::{Number, Value};
use solana_sdk::{ use solana_sdk::{
@ -10,6 +10,7 @@ use solana_sdk::{
instruction::InstructionError, instruction::InstructionError,
transaction::{self, TransactionError}, transaction::{self, TransactionError},
}; };
use solana_transaction_status::TransactionStatus;
use std::{collections::HashMap, sync::RwLock}; use std::{collections::HashMap, sync::RwLock};
pub const PUBKEY: &str = "7RoSF9fUmdphVCpabEoefH81WwrW7orsWonXWqTXkKV8"; pub const PUBKEY: &str = "7RoSF9fUmdphVCpabEoefH81WwrW7orsWonXWqTXkKV8";
@ -100,7 +101,7 @@ impl GenericRpcClientRequest for MockRpcClientRequest {
let status = if self.url == "sig_not_found" { let status = if self.url == "sig_not_found" {
None None
} else { } else {
Some(RpcTransactionStatus { status, slot: 1 }) Some(TransactionStatus { status, slot: 1 })
}; };
serde_json::to_value(vec![status])? serde_json::to_value(vec![status])?
} }

View File

@ -23,6 +23,7 @@ use solana_sdk::{
signers::Signers, signers::Signers,
transaction::{self, Transaction, TransactionError}, transaction::{self, Transaction, TransactionError},
}; };
use solana_transaction_status::{ConfirmedBlock, TransactionEncoding, TransactionStatus};
use solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY; use solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY;
use std::{ use std::{
error, error,
@ -119,7 +120,7 @@ impl RpcClient {
json!([[signature.to_string()], commitment_config]), json!([[signature.to_string()], commitment_config]),
5, 5,
)?; )?;
let result: Vec<Option<RpcTransactionStatus>> = let result: Vec<Option<TransactionStatus>> =
serde_json::from_value(signature_status).unwrap(); serde_json::from_value(signature_status).unwrap();
Ok(result[0].clone().map(|status_meta| status_meta.status)) Ok(result[0].clone().map(|status_meta| status_meta.status))
} }
@ -185,15 +186,15 @@ impl RpcClient {
.map_err(|err| ClientError::new_with_command(err.into(), "GetClusterNodes")) .map_err(|err| ClientError::new_with_command(err.into(), "GetClusterNodes"))
} }
pub fn get_confirmed_block(&self, slot: Slot) -> ClientResult<RpcConfirmedBlock> { pub fn get_confirmed_block(&self, slot: Slot) -> ClientResult<ConfirmedBlock> {
self.get_confirmed_block_with_encoding(slot, RpcTransactionEncoding::Json) self.get_confirmed_block_with_encoding(slot, TransactionEncoding::Json)
} }
pub fn get_confirmed_block_with_encoding( pub fn get_confirmed_block_with_encoding(
&self, &self,
slot: Slot, slot: Slot,
encoding: RpcTransactionEncoding, encoding: TransactionEncoding,
) -> ClientResult<RpcConfirmedBlock> { ) -> ClientResult<ConfirmedBlock> {
let response = self let response = self
.client .client
.send(&RpcRequest::GetConfirmedBlock, json!([slot, encoding]), 0) .send(&RpcRequest::GetConfirmedBlock, json!([slot, encoding]), 0)

View File

@ -1,12 +1,10 @@
use crate::{client_error, rpc_request::RpcError}; use crate::{client_error, rpc_request::RpcError};
use bincode::serialize;
use solana_sdk::{ use solana_sdk::{
account::Account, account::Account,
clock::{Epoch, Slot}, clock::{Epoch, Slot},
fee_calculator::{FeeCalculator, FeeRateGovernor}, fee_calculator::{FeeCalculator, FeeRateGovernor},
message::MessageHeader,
pubkey::Pubkey, pubkey::Pubkey,
transaction::{Result, Transaction}, transaction::Result,
}; };
use std::{collections::HashMap, net::SocketAddr, str::FromStr}; use std::{collections::HashMap, net::SocketAddr, str::FromStr};
@ -30,126 +28,6 @@ pub struct RpcBlockCommitment<T> {
pub total_stake: u64, pub total_stake: u64,
} }
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct RpcReward {
pub pubkey: String,
pub lamports: i64,
}
pub type RpcRewards = Vec<RpcReward>;
#[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<RpcTransactionWithStatusMeta>,
pub rewards: RpcRewards,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcTransactionWithStatusMeta {
pub transaction: RpcEncodedTransaction,
pub meta: Option<RpcTransactionStatusMeta>,
}
#[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<String>,
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<String>,
pub recent_blockhash: String,
pub instructions: Vec<RpcCompiledInstruction>,
}
/// 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<u8>,
pub data: String,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcTransactionStatusMeta {
pub status: Result<()>,
pub fee: u64,
pub pre_balances: Vec<u64>,
pub post_balances: Vec<u64>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RpcTransactionStatus {
pub slot: Slot,
pub status: Result<()>,
}
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RpcBlockhashFeeCalculator { pub struct RpcBlockhashFeeCalculator {

View File

@ -44,6 +44,7 @@ serde_json = "1.0.48"
solana-budget-program = { path = "../programs/budget", version = "1.1.0" } solana-budget-program = { path = "../programs/budget", version = "1.1.0" }
solana-clap-utils = { path = "../clap-utils", version = "1.1.0" } solana-clap-utils = { path = "../clap-utils", version = "1.1.0" }
solana-client = { path = "../client", version = "1.1.0" } solana-client = { path = "../client", version = "1.1.0" }
solana-transaction-status = { path = "../transaction-status", version = "1.1.0" }
solana-faucet = { path = "../faucet", version = "1.1.0" } solana-faucet = { path = "../faucet", version = "1.1.0" }
ed25519-dalek = "=1.0.0-pre.1" ed25519-dalek = "=1.0.0-pre.1"
solana-ledger = { path = "../ledger", version = "1.1.0" } solana-ledger = { path = "../ledger", version = "1.1.0" }

View File

@ -1017,7 +1017,6 @@ mod tests {
}; };
use crossbeam_channel::unbounded; use crossbeam_channel::unbounded;
use itertools::Itertools; use itertools::Itertools;
use solana_client::rpc_response::{RpcEncodedTransaction, RpcTransactionWithStatusMeta};
use solana_ledger::{ use solana_ledger::{
blockstore::entries_to_test_shreds, blockstore::entries_to_test_shreds,
entry::{next_entry, Entry, EntrySlice}, entry::{next_entry, Entry, EntrySlice},
@ -1032,6 +1031,7 @@ mod tests {
system_transaction, system_transaction,
transaction::TransactionError, transaction::TransactionError,
}; };
use solana_transaction_status::{EncodedTransaction, TransactionWithStatusMeta};
use std::{sync::atomic::Ordering, thread::sleep}; use std::{sync::atomic::Ordering, thread::sleep};
#[test] #[test]
@ -1977,10 +1977,10 @@ mod tests {
let confirmed_block = blockstore.get_confirmed_block(bank.slot(), None).unwrap(); let confirmed_block = blockstore.get_confirmed_block(bank.slot(), None).unwrap();
assert_eq!(confirmed_block.transactions.len(), 3); assert_eq!(confirmed_block.transactions.len(), 3);
for RpcTransactionWithStatusMeta { transaction, meta } in for TransactionWithStatusMeta { transaction, meta } in
confirmed_block.transactions.into_iter() confirmed_block.transactions.into_iter()
{ {
if let RpcEncodedTransaction::Json(transaction) = transaction { if let EncodedTransaction::Json(transaction) = transaction {
if transaction.signatures[0] == success_signature.to_string() { if transaction.signatures[0] == success_signature.to_string() {
assert_eq!(meta.unwrap().status, Ok(())); assert_eq!(meta.unwrap().status, Ok(()));
} else if transaction.signatures[0] == ix_error_signature.to_string() { } else if transaction.signatures[0] == ix_error_signature.to_string() {

View File

@ -1281,7 +1281,6 @@ pub(crate) mod tests {
transaction_status_service::TransactionStatusService, transaction_status_service::TransactionStatusService,
}; };
use crossbeam_channel::unbounded; use crossbeam_channel::unbounded;
use solana_client::rpc_response::{RpcEncodedTransaction, RpcTransactionWithStatusMeta};
use solana_ledger::{ use solana_ledger::{
blockstore::make_slot_entries, blockstore::make_slot_entries,
blockstore::{entries_to_test_shreds, BlockstoreError}, blockstore::{entries_to_test_shreds, BlockstoreError},
@ -1306,6 +1305,7 @@ pub(crate) mod tests {
transaction::TransactionError, transaction::TransactionError,
}; };
use solana_stake_program::stake_state; use solana_stake_program::stake_state;
use solana_transaction_status::{EncodedTransaction, TransactionWithStatusMeta};
use solana_vote_program::{ use solana_vote_program::{
vote_state::{self, Vote, VoteState, VoteStateVersions}, vote_state::{self, Vote, VoteState, VoteStateVersions},
vote_transaction, vote_transaction,
@ -2137,10 +2137,10 @@ pub(crate) mod tests {
let confirmed_block = blockstore.get_confirmed_block(slot, None).unwrap(); let confirmed_block = blockstore.get_confirmed_block(slot, None).unwrap();
assert_eq!(confirmed_block.transactions.len(), 3); assert_eq!(confirmed_block.transactions.len(), 3);
for RpcTransactionWithStatusMeta { transaction, meta } in for TransactionWithStatusMeta { transaction, meta } in
confirmed_block.transactions.into_iter() confirmed_block.transactions.into_iter()
{ {
if let RpcEncodedTransaction::Json(transaction) = transaction { if let EncodedTransaction::Json(transaction) = transaction {
if transaction.signatures[0] == signatures[0].to_string() { if transaction.signatures[0] == signatures[0].to_string() {
assert_eq!(meta.unwrap().status, Ok(())); assert_eq!(meta.unwrap().status, Ok(()));
} else if transaction.signatures[0] == signatures[1].to_string() { } else if transaction.signatures[0] == signatures[1].to_string() {

View File

@ -1,7 +1,7 @@
use crossbeam_channel::{Receiver, RecvTimeoutError, Sender}; use crossbeam_channel::{Receiver, RecvTimeoutError, Sender};
use solana_client::rpc_response::RpcReward;
use solana_ledger::blockstore::Blockstore; use solana_ledger::blockstore::Blockstore;
use solana_sdk::{clock::Slot, pubkey::Pubkey}; use solana_sdk::{clock::Slot, pubkey::Pubkey};
use solana_transaction_status::Reward;
use std::{ use std::{
sync::{ sync::{
atomic::{AtomicBool, Ordering}, atomic::{AtomicBool, Ordering},
@ -49,7 +49,7 @@ impl RewardsRecorderService {
let (slot, rewards) = rewards_receiver.recv_timeout(Duration::from_secs(1))?; let (slot, rewards) = rewards_receiver.recv_timeout(Duration::from_secs(1))?;
let rpc_rewards = rewards let rpc_rewards = rewards
.into_iter() .into_iter()
.map(|(pubkey, lamports)| RpcReward { .map(|(pubkey, lamports)| Reward {
pubkey: pubkey.to_string(), pubkey: pubkey.to_string(),
lamports, lamports,
}) })

View File

@ -25,6 +25,7 @@ use solana_sdk::{
timing::slot_duration_from_slots_per_year, timing::slot_duration_from_slots_per_year,
transaction::Transaction, transaction::Transaction,
}; };
use solana_transaction_status::{ConfirmedBlock, TransactionEncoding, TransactionStatus};
use solana_vote_program::vote_state::{VoteState, MAX_LOCKOUT_HISTORY}; use solana_vote_program::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
use std::{ use std::{
collections::HashMap, collections::HashMap,
@ -366,8 +367,8 @@ impl JsonRpcRequestProcessor {
pub fn get_confirmed_block( pub fn get_confirmed_block(
&self, &self,
slot: Slot, slot: Slot,
encoding: Option<RpcTransactionEncoding>, encoding: Option<TransactionEncoding>,
) -> Result<Option<RpcConfirmedBlock>> { ) -> Result<Option<ConfirmedBlock>> {
if self.config.enable_rpc_transaction_history { if self.config.enable_rpc_transaction_history {
Ok(self.blockstore.get_confirmed_block(slot, encoding).ok()) Ok(self.blockstore.get_confirmed_block(slot, encoding).ok())
} else { } else {
@ -421,14 +422,14 @@ impl JsonRpcRequestProcessor {
&self, &self,
signatures: Vec<Signature>, signatures: Vec<Signature>,
commitment: Option<CommitmentConfig>, commitment: Option<CommitmentConfig>,
) -> Result<Vec<Option<RpcTransactionStatus>>> { ) -> Result<Vec<Option<TransactionStatus>>> {
let mut statuses: Vec<Option<RpcTransactionStatus>> = vec![]; let mut statuses: Vec<Option<TransactionStatus>> = vec![];
let bank = self.bank(commitment); let bank = self.bank(commitment);
for signature in signatures { for signature in signatures {
let status = bank.get_signature_confirmation_status(&signature).map( let status = bank.get_signature_confirmation_status(&signature).map(
|SignatureConfirmationStatus { slot, status, .. }| RpcTransactionStatus { |SignatureConfirmationStatus { slot, status, .. }| TransactionStatus {
slot, slot,
status, status,
}, },
@ -565,7 +566,7 @@ pub trait RpcSol {
meta: Self::Metadata, meta: Self::Metadata,
signature_strs: Vec<String>, signature_strs: Vec<String>,
commitment: Option<CommitmentConfig>, commitment: Option<CommitmentConfig>,
) -> Result<Vec<Option<RpcTransactionStatus>>>; ) -> Result<Vec<Option<TransactionStatus>>>;
#[rpc(meta, name = "getSlot")] #[rpc(meta, name = "getSlot")]
fn get_slot(&self, meta: Self::Metadata, commitment: Option<CommitmentConfig>) -> Result<u64>; fn get_slot(&self, meta: Self::Metadata, commitment: Option<CommitmentConfig>) -> Result<u64>;
@ -662,8 +663,8 @@ pub trait RpcSol {
&self, &self,
meta: Self::Metadata, meta: Self::Metadata,
slot: Slot, slot: Slot,
encoding: Option<RpcTransactionEncoding>, encoding: Option<TransactionEncoding>,
) -> Result<Option<RpcConfirmedBlock>>; ) -> Result<Option<ConfirmedBlock>>;
#[rpc(meta, name = "getBlockTime")] #[rpc(meta, name = "getBlockTime")]
fn get_block_time(&self, meta: Self::Metadata, slot: Slot) -> Result<Option<UnixTimestamp>>; fn get_block_time(&self, meta: Self::Metadata, slot: Slot) -> Result<Option<UnixTimestamp>>;
@ -911,7 +912,7 @@ impl RpcSol for RpcSolImpl {
meta: Self::Metadata, meta: Self::Metadata,
signature_strs: Vec<String>, signature_strs: Vec<String>,
commitment: Option<CommitmentConfig>, commitment: Option<CommitmentConfig>,
) -> Result<Vec<Option<RpcTransactionStatus>>> { ) -> Result<Vec<Option<TransactionStatus>>> {
let mut signatures: Vec<Signature> = vec![]; let mut signatures: Vec<Signature> = vec![];
for signature_str in signature_strs { for signature_str in signature_strs {
signatures.push(verify_signature(&signature_str)?); signatures.push(verify_signature(&signature_str)?);
@ -1182,8 +1183,8 @@ impl RpcSol for RpcSolImpl {
&self, &self,
meta: Self::Metadata, meta: Self::Metadata,
slot: Slot, slot: Slot,
encoding: Option<RpcTransactionEncoding>, encoding: Option<TransactionEncoding>,
) -> Result<Option<RpcConfirmedBlock>> { ) -> Result<Option<ConfirmedBlock>> {
meta.request_processor meta.request_processor
.read() .read()
.unwrap() .unwrap()
@ -1216,7 +1217,6 @@ pub mod tests {
}; };
use bincode::deserialize; use bincode::deserialize;
use jsonrpc_core::{MetaIoHandler, Output, Response, Value}; use jsonrpc_core::{MetaIoHandler, Output, Response, Value};
use solana_client::rpc_response::{RpcEncodedTransaction, RpcTransactionWithStatusMeta};
use solana_ledger::{ use solana_ledger::{
blockstore::entries_to_test_shreds, blockstore::entries_to_test_shreds,
blockstore_processor::fill_blockstore_slot_with_ticks, blockstore_processor::fill_blockstore_slot_with_ticks,
@ -1233,6 +1233,7 @@ pub mod tests {
system_transaction, system_transaction,
transaction::{self, TransactionError}, transaction::{self, TransactionError},
}; };
use solana_transaction_status::{EncodedTransaction, TransactionWithStatusMeta};
use solana_vote_program::{ use solana_vote_program::{
vote_instruction, vote_instruction,
vote_state::{Vote, VoteInit, MAX_LOCKOUT_HISTORY}, vote_state::{Vote, VoteInit, MAX_LOCKOUT_HISTORY},
@ -1815,8 +1816,7 @@ pub mod tests {
let res = io.handle_request_sync(&req, meta.clone()); let res = io.handle_request_sync(&req, meta.clone());
let expected_res: transaction::Result<()> = Ok(()); let expected_res: transaction::Result<()> = Ok(());
let json: Value = serde_json::from_str(&res.unwrap()).unwrap(); let json: Value = serde_json::from_str(&res.unwrap()).unwrap();
let result: Vec<Option<RpcTransactionStatus>> = let result: Vec<Option<TransactionStatus>> = serde_json::from_value(json["result"].clone())
serde_json::from_value(json["result"].clone())
.expect("actual response deserialization"); .expect("actual response deserialization");
assert_eq!(expected_res, result[0].as_ref().unwrap().status); assert_eq!(expected_res, result[0].as_ref().unwrap().status);
@ -1828,8 +1828,7 @@ pub mod tests {
); );
let res = io.handle_request_sync(&req, meta.clone()); let res = io.handle_request_sync(&req, meta.clone());
let json: Value = serde_json::from_str(&res.unwrap()).unwrap(); let json: Value = serde_json::from_str(&res.unwrap()).unwrap();
let result: Vec<Option<RpcTransactionStatus>> = let result: Vec<Option<TransactionStatus>> = serde_json::from_value(json["result"].clone())
serde_json::from_value(json["result"].clone())
.expect("actual response deserialization"); .expect("actual response deserialization");
assert!(result[0].is_none()); assert!(result[0].is_none());
@ -1844,8 +1843,7 @@ pub mod tests {
InstructionError::CustomError(1), InstructionError::CustomError(1),
)); ));
let json: Value = serde_json::from_str(&res.unwrap()).unwrap(); let json: Value = serde_json::from_str(&res.unwrap()).unwrap();
let result: Vec<Option<RpcTransactionStatus>> = let result: Vec<Option<TransactionStatus>> = serde_json::from_value(json["result"].clone())
serde_json::from_value(json["result"].clone())
.expect("actual response deserialization"); .expect("actual response deserialization");
assert_eq!(expected_res, result[0].as_ref().unwrap().status); assert_eq!(expected_res, result[0].as_ref().unwrap().status);
} }
@ -2286,15 +2284,15 @@ pub mod tests {
let res = io.handle_request_sync(&req, meta.clone()); let res = io.handle_request_sync(&req, meta.clone());
let result: Value = serde_json::from_str(&res.expect("actual response")) let result: Value = serde_json::from_str(&res.expect("actual response"))
.expect("actual response deserialization"); .expect("actual response deserialization");
let confirmed_block: Option<RpcConfirmedBlock> = let confirmed_block: Option<ConfirmedBlock> =
serde_json::from_value(result["result"].clone()).unwrap(); serde_json::from_value(result["result"].clone()).unwrap();
let confirmed_block = confirmed_block.unwrap(); let confirmed_block = confirmed_block.unwrap();
assert_eq!(confirmed_block.transactions.len(), 3); assert_eq!(confirmed_block.transactions.len(), 3);
for RpcTransactionWithStatusMeta { transaction, meta } in for TransactionWithStatusMeta { transaction, meta } in
confirmed_block.transactions.into_iter() confirmed_block.transactions.into_iter()
{ {
if let RpcEncodedTransaction::Json(transaction) = transaction { if let EncodedTransaction::Json(transaction) = transaction {
if transaction.signatures[0] == confirmed_block_signatures[0].to_string() { if transaction.signatures[0] == confirmed_block_signatures[0].to_string() {
assert_eq!(transaction.message.recent_blockhash, blockhash.to_string()); assert_eq!(transaction.message.recent_blockhash, blockhash.to_string());
assert_eq!(meta.unwrap().status, Ok(())); assert_eq!(meta.unwrap().status, Ok(()));
@ -2318,15 +2316,15 @@ pub mod tests {
let res = io.handle_request_sync(&req, meta); let res = io.handle_request_sync(&req, meta);
let result: Value = serde_json::from_str(&res.expect("actual response")) let result: Value = serde_json::from_str(&res.expect("actual response"))
.expect("actual response deserialization"); .expect("actual response deserialization");
let confirmed_block: Option<RpcConfirmedBlock> = let confirmed_block: Option<ConfirmedBlock> =
serde_json::from_value(result["result"].clone()).unwrap(); serde_json::from_value(result["result"].clone()).unwrap();
let confirmed_block = confirmed_block.unwrap(); let confirmed_block = confirmed_block.unwrap();
assert_eq!(confirmed_block.transactions.len(), 3); assert_eq!(confirmed_block.transactions.len(), 3);
for RpcTransactionWithStatusMeta { transaction, meta } in for TransactionWithStatusMeta { transaction, meta } in
confirmed_block.transactions.into_iter() confirmed_block.transactions.into_iter()
{ {
if let RpcEncodedTransaction::Binary(transaction) = transaction { if let EncodedTransaction::Binary(transaction) = transaction {
let decoded_transaction: Transaction = let decoded_transaction: Transaction =
deserialize(&bs58::decode(&transaction).into_vec().unwrap()).unwrap(); deserialize(&bs58::decode(&transaction).into_vec().unwrap()).unwrap();
if decoded_transaction.signatures[0] == confirmed_block_signatures[0] { if decoded_transaction.signatures[0] == confirmed_block_signatures[0] {

View File

@ -1,10 +1,10 @@
use crossbeam_channel::{Receiver, RecvTimeoutError}; use crossbeam_channel::{Receiver, RecvTimeoutError};
use solana_client::rpc_response::RpcTransactionStatusMeta;
use solana_ledger::{blockstore::Blockstore, blockstore_processor::TransactionStatusBatch}; use solana_ledger::{blockstore::Blockstore, blockstore_processor::TransactionStatusBatch};
use solana_runtime::{ use solana_runtime::{
bank::{Bank, HashAgeKind}, bank::{Bank, HashAgeKind},
nonce_utils, nonce_utils,
}; };
use solana_transaction_status::TransactionStatusMeta;
use std::{ use std::{
sync::{ sync::{
atomic::{AtomicBool, Ordering}, atomic::{AtomicBool, Ordering},
@ -73,7 +73,7 @@ impl TransactionStatusService {
blockstore blockstore
.write_transaction_status( .write_transaction_status(
(slot, transaction.signatures[0]), (slot, transaction.signatures[0]),
&RpcTransactionStatusMeta { &TransactionStatusMeta {
status, status,
fee, fee,
pre_balances, pre_balances,

View File

@ -28,7 +28,7 @@ reed-solomon-erasure = { package = "solana-reed-solomon-erasure", version = "4.0
regex = "1.3.6" regex = "1.3.6"
serde = "1.0.105" serde = "1.0.105"
serde_bytes = "0.11.3" serde_bytes = "0.11.3"
solana-client = { path = "../client", version = "1.1.0" } solana-transaction-status = { path = "../transaction-status", version = "1.1.0" }
solana-genesis-programs = { path = "../genesis-programs", version = "1.1.0" } solana-genesis-programs = { path = "../genesis-programs", version = "1.1.0" }
solana-logger = { path = "../logger", version = "1.1.0" } solana-logger = { path = "../logger", version = "1.1.0" }
solana-measure = { path = "../measure", version = "1.1.0" } solana-measure = { path = "../measure", version = "1.1.0" }

View File

@ -22,10 +22,6 @@ use rayon::{
ThreadPool, ThreadPool,
}; };
use rocksdb::DBRawIterator; use rocksdb::DBRawIterator;
use solana_client::rpc_response::{
RpcConfirmedBlock, RpcEncodedTransaction, RpcRewards, RpcTransactionEncoding,
RpcTransactionStatusMeta, RpcTransactionWithStatusMeta,
};
use solana_measure::measure::Measure; use solana_measure::measure::Measure;
use solana_metrics::{datapoint_debug, datapoint_error}; use solana_metrics::{datapoint_debug, datapoint_error};
use solana_rayon_threadlimit::get_thread_count; use solana_rayon_threadlimit::get_thread_count;
@ -40,6 +36,10 @@ use solana_sdk::{
timing::timestamp, timing::timestamp,
transaction::Transaction, transaction::Transaction,
}; };
use solana_transaction_status::{
ConfirmedBlock, EncodedTransaction, Rewards, TransactionEncoding, TransactionStatusMeta,
TransactionWithStatusMeta,
};
use solana_vote_program::{vote_instruction::VoteInstruction, vote_state::TIMESTAMP_SLOT_INTERVAL}; use solana_vote_program::{vote_instruction::VoteInstruction, vote_state::TIMESTAMP_SLOT_INTERVAL};
use std::{ use std::{
cell::RefCell, cell::RefCell,
@ -1430,15 +1430,15 @@ impl Blockstore {
pub fn get_confirmed_block( pub fn get_confirmed_block(
&self, &self,
slot: Slot, slot: Slot,
encoding: Option<RpcTransactionEncoding>, encoding: Option<TransactionEncoding>,
) -> Result<RpcConfirmedBlock> { ) -> Result<ConfirmedBlock> {
let lowest_cleanup_slot = self.lowest_cleanup_slot.read().unwrap(); let lowest_cleanup_slot = self.lowest_cleanup_slot.read().unwrap();
// lowest_cleanup_slot is the last slot that was not cleaned up by // lowest_cleanup_slot is the last slot that was not cleaned up by
// LedgerCleanupService // LedgerCleanupService
if *lowest_cleanup_slot > slot { if *lowest_cleanup_slot > slot {
return Err(BlockstoreError::SlotCleanedUp); return Err(BlockstoreError::SlotCleanedUp);
} }
let encoding = encoding.unwrap_or(RpcTransactionEncoding::Json); let encoding = encoding.unwrap_or(TransactionEncoding::Json);
if self.is_root(slot) { if self.is_root(slot) {
let slot_meta_cf = self.db.column::<cf::SlotMeta>(); let slot_meta_cf = self.db.column::<cf::SlotMeta>();
let slot_meta = match slot_meta_cf.get(slot)? { let slot_meta = match slot_meta_cf.get(slot)? {
@ -1467,7 +1467,7 @@ impl Blockstore {
let rewards = self.rewards_cf.get(slot)?.unwrap_or_else(|| vec![]); let rewards = self.rewards_cf.get(slot)?.unwrap_or_else(|| vec![]);
let block = RpcConfirmedBlock { let block = ConfirmedBlock {
previous_blockhash: previous_blockhash.to_string(), previous_blockhash: previous_blockhash.to_string(),
blockhash: blockhash.to_string(), blockhash: blockhash.to_string(),
parent_slot: slot_meta.parent_slot, parent_slot: slot_meta.parent_slot,
@ -1487,15 +1487,14 @@ impl Blockstore {
fn map_transactions_to_statuses<'a>( fn map_transactions_to_statuses<'a>(
&self, &self,
slot: Slot, slot: Slot,
encoding: RpcTransactionEncoding, encoding: TransactionEncoding,
iterator: impl Iterator<Item = Transaction> + 'a, iterator: impl Iterator<Item = Transaction> + 'a,
) -> Vec<RpcTransactionWithStatusMeta> { ) -> Vec<TransactionWithStatusMeta> {
iterator iterator
.map(|transaction| { .map(|transaction| {
let signature = transaction.signatures[0]; let signature = transaction.signatures[0];
let encoded_transaction = let encoded_transaction = EncodedTransaction::encode(transaction, encoding.clone());
RpcEncodedTransaction::encode(transaction, encoding.clone()); TransactionWithStatusMeta {
RpcTransactionWithStatusMeta {
transaction: encoded_transaction, transaction: encoded_transaction,
meta: self meta: self
.transaction_status_cf .transaction_status_cf
@ -1509,23 +1508,23 @@ impl Blockstore {
pub fn read_transaction_status( pub fn read_transaction_status(
&self, &self,
index: (Slot, Signature), index: (Slot, Signature),
) -> Result<Option<RpcTransactionStatusMeta>> { ) -> Result<Option<TransactionStatusMeta>> {
self.transaction_status_cf.get(index) self.transaction_status_cf.get(index)
} }
pub fn write_transaction_status( pub fn write_transaction_status(
&self, &self,
index: (Slot, Signature), index: (Slot, Signature),
status: &RpcTransactionStatusMeta, status: &TransactionStatusMeta,
) -> Result<()> { ) -> Result<()> {
self.transaction_status_cf.put(index, status) self.transaction_status_cf.put(index, status)
} }
pub fn read_rewards(&self, index: Slot) -> Result<Option<RpcRewards>> { pub fn read_rewards(&self, index: Slot) -> Result<Option<Rewards>> {
self.rewards_cf.get(index) self.rewards_cf.get(index)
} }
pub fn write_rewards(&self, index: Slot, rewards: RpcRewards) -> Result<()> { pub fn write_rewards(&self, index: Slot, rewards: Rewards) -> Result<()> {
self.rewards_cf.put(index, &rewards) self.rewards_cf.put(index, &rewards)
} }
@ -4848,7 +4847,7 @@ pub mod tests {
.put_meta_bytes(slot - 1, &serialize(&parent_meta).unwrap()) .put_meta_bytes(slot - 1, &serialize(&parent_meta).unwrap())
.unwrap(); .unwrap();
let expected_transactions: Vec<(Transaction, Option<RpcTransactionStatusMeta>)> = entries let expected_transactions: Vec<(Transaction, Option<TransactionStatusMeta>)> = entries
.iter() .iter()
.cloned() .cloned()
.filter(|entry| !entry.is_tick()) .filter(|entry| !entry.is_tick())
@ -4865,7 +4864,7 @@ pub mod tests {
.transaction_status_cf .transaction_status_cf
.put( .put(
(slot, signature), (slot, signature),
&RpcTransactionStatusMeta { &TransactionStatusMeta {
status: Ok(()), status: Ok(()),
fee: 42, fee: 42,
pre_balances: pre_balances.clone(), pre_balances: pre_balances.clone(),
@ -4877,7 +4876,7 @@ pub mod tests {
.transaction_status_cf .transaction_status_cf
.put( .put(
(slot + 1, signature), (slot + 1, signature),
&RpcTransactionStatusMeta { &TransactionStatusMeta {
status: Ok(()), status: Ok(()),
fee: 42, fee: 42,
pre_balances: pre_balances.clone(), pre_balances: pre_balances.clone(),
@ -4887,7 +4886,7 @@ pub mod tests {
.unwrap(); .unwrap();
( (
transaction, transaction,
Some(RpcTransactionStatusMeta { Some(TransactionStatusMeta {
status: Ok(()), status: Ok(()),
fee: 42, fee: 42,
pre_balances, pre_balances,
@ -4904,12 +4903,12 @@ pub mod tests {
let confirmed_block = ledger.get_confirmed_block(slot, None).unwrap(); let confirmed_block = ledger.get_confirmed_block(slot, None).unwrap();
assert_eq!(confirmed_block.transactions.len(), 100); assert_eq!(confirmed_block.transactions.len(), 100);
let expected_block = RpcConfirmedBlock { let expected_block = ConfirmedBlock {
transactions: expected_transactions transactions: expected_transactions
.iter() .iter()
.cloned() .cloned()
.map(|(tx, meta)| RpcTransactionWithStatusMeta { .map(|(tx, meta)| TransactionWithStatusMeta {
transaction: RpcEncodedTransaction::encode(tx, RpcTransactionEncoding::Json), transaction: EncodedTransaction::encode(tx, TransactionEncoding::Json),
meta, meta,
}) })
.collect(), .collect(),
@ -4925,12 +4924,12 @@ pub mod tests {
let confirmed_block = ledger.get_confirmed_block(slot + 1, None).unwrap(); let confirmed_block = ledger.get_confirmed_block(slot + 1, None).unwrap();
assert_eq!(confirmed_block.transactions.len(), 100); assert_eq!(confirmed_block.transactions.len(), 100);
let expected_block = RpcConfirmedBlock { let expected_block = ConfirmedBlock {
transactions: expected_transactions transactions: expected_transactions
.iter() .iter()
.cloned() .cloned()
.map(|(tx, meta)| RpcTransactionWithStatusMeta { .map(|(tx, meta)| TransactionWithStatusMeta {
transaction: RpcEncodedTransaction::encode(tx, RpcTransactionEncoding::Json), transaction: EncodedTransaction::encode(tx, TransactionEncoding::Json),
meta, meta,
}) })
.collect(), .collect(),
@ -5150,7 +5149,7 @@ pub mod tests {
assert!(transaction_status_cf assert!(transaction_status_cf
.put( .put(
(0, Signature::default()), (0, Signature::default()),
&RpcTransactionStatusMeta { &TransactionStatusMeta {
status: solana_sdk::transaction::Result::<()>::Err( status: solana_sdk::transaction::Result::<()>::Err(
TransactionError::AccountNotFound TransactionError::AccountNotFound
), ),
@ -5162,7 +5161,7 @@ pub mod tests {
.is_ok()); .is_ok());
// result found // result found
let RpcTransactionStatusMeta { let TransactionStatusMeta {
status, status,
fee, fee,
pre_balances, pre_balances,
@ -5180,7 +5179,7 @@ pub mod tests {
assert!(transaction_status_cf assert!(transaction_status_cf
.put( .put(
(9, Signature::default()), (9, Signature::default()),
&RpcTransactionStatusMeta { &TransactionStatusMeta {
status: solana_sdk::transaction::Result::<()>::Ok(()), status: solana_sdk::transaction::Result::<()>::Ok(()),
fee: 9u64, fee: 9u64,
pre_balances: pre_balances_vec.clone(), pre_balances: pre_balances_vec.clone(),
@ -5190,7 +5189,7 @@ pub mod tests {
.is_ok()); .is_ok());
// result found // result found
let RpcTransactionStatusMeta { let TransactionStatusMeta {
status, status,
fee, fee,
pre_balances, pre_balances,
@ -5245,7 +5244,7 @@ pub mod tests {
transaction_status_cf transaction_status_cf
.put( .put(
(slot, transaction.signatures[0]), (slot, transaction.signatures[0]),
&RpcTransactionStatusMeta { &TransactionStatusMeta {
status: solana_sdk::transaction::Result::<()>::Err( status: solana_sdk::transaction::Result::<()>::Err(
TransactionError::AccountNotFound, TransactionError::AccountNotFound,
), ),
@ -5268,7 +5267,7 @@ pub mod tests {
let map = blockstore.map_transactions_to_statuses( let map = blockstore.map_transactions_to_statuses(
slot, slot,
RpcTransactionEncoding::Json, TransactionEncoding::Json,
transactions.into_iter(), transactions.into_iter(),
); );
assert_eq!(map.len(), 5); assert_eq!(map.len(), 5);

View File

@ -10,8 +10,8 @@ use rocksdb::{
}; };
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use serde::Serialize; use serde::Serialize;
use solana_client::rpc_response::{RpcRewards, RpcTransactionStatusMeta};
use solana_sdk::{clock::Slot, signature::Signature}; use solana_sdk::{clock::Slot, signature::Signature};
use solana_transaction_status::{Rewards, TransactionStatusMeta};
use std::{collections::HashMap, fs, marker::PhantomData, path::Path, sync::Arc}; use std::{collections::HashMap, fs, marker::PhantomData, path::Path, sync::Arc};
use thiserror::Error; use thiserror::Error;
@ -269,7 +269,7 @@ pub trait TypedColumn: Column {
} }
impl TypedColumn for columns::TransactionStatus { impl TypedColumn for columns::TransactionStatus {
type Type = RpcTransactionStatusMeta; type Type = TransactionStatusMeta;
} }
pub trait SlotColumn<Index = u64> {} pub trait SlotColumn<Index = u64> {}
@ -330,7 +330,7 @@ impl ColumnName for columns::Rewards {
const NAME: &'static str = REWARDS_CF; const NAME: &'static str = REWARDS_CF;
} }
impl TypedColumn for columns::Rewards { impl TypedColumn for columns::Rewards {
type Type = RpcRewards; type Type = Rewards;
} }
impl Column for columns::ShredCode { impl Column for columns::ShredCode {

View File

@ -0,0 +1,16 @@
[package]
name = "solana-transaction-status"
version = "1.1.0"
description = "Solana transaction status types"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
homepage = "https://solana.com/"
license = "Apache-2.0"
edition = "2018"
[dependencies]
bincode = "1.2.1"
bs58 = "0.3.0"
solana-sdk = { path = "../sdk", version = "1.1.0" }
serde = "1.0.105"
serde_derive = "1.0.103"

View File

@ -0,0 +1,127 @@
#[macro_use]
extern crate serde_derive;
use bincode::serialize;
use solana_sdk::{
clock::Slot,
message::MessageHeader,
transaction::{Result, Transaction},
};
/// 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<u8>,
pub data: String,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TransactionStatusMeta {
pub status: Result<()>,
pub fee: u64,
pub pre_balances: Vec<u64>,
pub post_balances: Vec<u64>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TransactionStatus {
pub slot: Slot,
pub status: Result<()>,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Reward {
pub pubkey: String,
pub lamports: i64,
}
pub type Rewards = Vec<Reward>;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ConfirmedBlock {
pub previous_blockhash: String,
pub blockhash: String,
pub parent_slot: Slot,
pub transactions: Vec<TransactionWithStatusMeta>,
pub rewards: Rewards,
}
/// 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<String>,
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<String>,
pub recent_blockhash: String,
pub instructions: Vec<RpcCompiledInstruction>,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TransactionWithStatusMeta {
pub transaction: EncodedTransaction,
pub meta: Option<TransactionStatusMeta>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(rename_all = "camelCase")]
pub enum TransactionEncoding {
Binary,
Json,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", untagged)]
pub enum EncodedTransaction {
Binary(String),
Json(RpcTransaction),
}
impl EncodedTransaction {
pub fn encode(transaction: Transaction, encoding: TransactionEncoding) -> Self {
if encoding == TransactionEncoding::Json {
EncodedTransaction::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 {
EncodedTransaction::Binary(bs58::encode(serialize(&transaction).unwrap()).into_string())
}
}
}