Update getSignatureStatus: support multiple signatures, include slot in each response item (#9022)

* Rename enable-rpc-get-confirmed-block

* Rename RpcTransactionStatus -> RpcTransactionStatusMeta

* Return simplified RpcTransactionStatus; Add support for multiple transactions

* Update docs

* typo
This commit is contained in:
Tyera Eulberg
2020-03-23 11:25:39 -06:00
committed by GitHub
parent 1a5b01676d
commit 1b8f9e75dd
16 changed files with 136 additions and 120 deletions

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}, rpc_response::{Response, RpcResponseContext, RpcTransactionStatus},
}; };
use serde_json::{Number, Value}; use serde_json::{Number, Value};
use solana_sdk::{ use solana_sdk::{
@ -87,19 +87,22 @@ impl GenericRpcClientRequest for MockRpcClientRequest {
value: serde_json::to_value(FeeRateGovernor::default()).unwrap(), value: serde_json::to_value(FeeRateGovernor::default()).unwrap(),
})?, })?,
RpcRequest::GetSignatureStatus => { RpcRequest::GetSignatureStatus => {
let response: Option<transaction::Result<()>> = if self.url == "account_in_use" { let status: transaction::Result<()> = if self.url == "account_in_use" {
Some(Err(TransactionError::AccountInUse)) Err(TransactionError::AccountInUse)
} else if self.url == "instruction_error" { } else if self.url == "instruction_error" {
Some(Err(TransactionError::InstructionError( Err(TransactionError::InstructionError(
0, 0,
InstructionError::UninitializedAccount, InstructionError::UninitializedAccount,
))) ))
} else if self.url == "sig_not_found" { } else {
Ok(())
};
let status = if self.url == "sig_not_found" {
None None
} else { } else {
Some(Ok(())) Some(RpcTransactionStatus { status, slot: 1 })
}; };
serde_json::to_value(response).unwrap() serde_json::to_value(vec![status])?
} }
RpcRequest::GetTransactionCount => Value::Number(Number::from(1234)), RpcRequest::GetTransactionCount => Value::Number(Number::from(1234)),
RpcRequest::GetSlot => Value::Number(Number::from(0)), RpcRequest::GetSlot => Value::Number(Number::from(0)),

View File

@ -7,7 +7,7 @@ use crate::{
rpc_response::{ rpc_response::{
Response, RpcAccount, RpcBlockhashFeeCalculator, RpcConfirmedBlock, RpcContactInfo, Response, RpcAccount, RpcBlockhashFeeCalculator, RpcConfirmedBlock, RpcContactInfo,
RpcEpochInfo, RpcFeeCalculator, RpcFeeRateGovernor, RpcIdentity, RpcKeyedAccount, RpcEpochInfo, RpcFeeCalculator, RpcFeeRateGovernor, RpcIdentity, RpcKeyedAccount,
RpcLeaderSchedule, RpcResult, RpcVersionInfo, RpcVoteAccountStatus, RpcLeaderSchedule, RpcResult, RpcTransactionStatus, RpcVersionInfo, RpcVoteAccountStatus,
}, },
}; };
use bincode::serialize; use bincode::serialize;
@ -120,12 +120,12 @@ impl RpcClient {
) -> ClientResult<Option<transaction::Result<()>>> { ) -> ClientResult<Option<transaction::Result<()>>> {
let signature_status = self.client.send( let signature_status = self.client.send(
&RpcRequest::GetSignatureStatus, &RpcRequest::GetSignatureStatus,
json!([signature.to_string(), commitment_config]), json!([[signature.to_string()], commitment_config]),
5, 5,
)?; )?;
let result: Option<transaction::Result<()>> = let result: Vec<Option<RpcTransactionStatus>> =
serde_json::from_value(signature_status).unwrap(); serde_json::from_value(signature_status).unwrap();
Ok(result) Ok(result[0].clone().map(|status_meta| status_meta.status))
} }
pub fn get_slot(&self) -> ClientResult<Slot> { pub fn get_slot(&self) -> ClientResult<Slot> {

View File

@ -97,7 +97,7 @@ impl RpcRequest {
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum RpcError { pub enum RpcError {
#[error("rpc reques error: {0}")] #[error("rpc request error: {0}")]
RpcRequestError(String), RpcRequestError(String),
#[error("parse error: expected {0}")] #[error("parse error: expected {0}")]
ParseError(String), /* "expected" */ ParseError(String), /* "expected" */

View File

@ -52,7 +52,7 @@ pub struct RpcConfirmedBlock {
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RpcTransactionWithStatusMeta { pub struct RpcTransactionWithStatusMeta {
pub transaction: RpcEncodedTransaction, pub transaction: RpcEncodedTransaction,
pub meta: Option<RpcTransactionStatus>, pub meta: Option<RpcTransactionStatusMeta>,
} }
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
@ -136,13 +136,20 @@ pub struct RpcCompiledInstruction {
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RpcTransactionStatus { pub struct RpcTransactionStatusMeta {
pub status: Result<()>, pub status: Result<()>,
pub fee: u64, pub fee: u64,
pub pre_balances: Vec<u64>, pub pre_balances: Vec<u64>,
pub post_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

@ -7,13 +7,7 @@ use crate::{
use bincode::serialize; use bincode::serialize;
use jsonrpc_core::{Error, Metadata, Result}; use jsonrpc_core::{Error, Metadata, Result};
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use solana_client::rpc_response::{ use solana_client::rpc_response::*;
Response, RpcAccount, RpcBlockCommitment, RpcBlockhashFeeCalculator, RpcConfirmedBlock,
RpcContactInfo, RpcEpochInfo, RpcFeeCalculator, RpcFeeRateGovernor, RpcIdentity,
RpcKeyedAccount, RpcLeaderSchedule, RpcResponseContext, RpcSignatureConfirmation,
RpcStorageTurn, RpcTransactionEncoding, RpcVersionInfo, RpcVoteAccountInfo,
RpcVoteAccountStatus,
};
use solana_faucet::faucet::request_airdrop_transaction; use solana_faucet::faucet::request_airdrop_transaction;
use solana_ledger::{ use solana_ledger::{
bank_forks::BankForks, blockstore::Blockstore, rooted_slot_iterator::RootedSlotIterator, bank_forks::BankForks, blockstore::Blockstore, rooted_slot_iterator::RootedSlotIterator,
@ -29,7 +23,7 @@ use solana_sdk::{
pubkey::Pubkey, pubkey::Pubkey,
signature::Signature, signature::Signature,
timing::slot_duration_from_slots_per_year, timing::slot_duration_from_slots_per_year,
transaction::{self, Transaction}, transaction::Transaction,
}; };
use solana_vote_program::vote_state::{VoteState, MAX_LOCKOUT_HISTORY}; use solana_vote_program::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
use std::{ use std::{
@ -52,7 +46,7 @@ fn new_response<T>(bank: &Bank, value: T) -> RpcResponse<T> {
pub struct JsonRpcConfig { pub struct JsonRpcConfig {
pub enable_validator_exit: bool, pub enable_validator_exit: bool,
pub enable_set_log_filter: bool, pub enable_set_log_filter: bool,
pub enable_get_confirmed_block: bool, pub enable_rpc_transaction_history: bool,
pub identity_pubkey: Pubkey, pub identity_pubkey: Pubkey,
pub faucet_addr: Option<SocketAddr>, pub faucet_addr: Option<SocketAddr>,
} }
@ -374,7 +368,7 @@ impl JsonRpcRequestProcessor {
slot: Slot, slot: Slot,
encoding: Option<RpcTransactionEncoding>, encoding: Option<RpcTransactionEncoding>,
) -> Result<Option<RpcConfirmedBlock>> { ) -> Result<Option<RpcConfirmedBlock>> {
if self.config.enable_get_confirmed_block { 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 {
Ok(None) Ok(None)
@ -422,6 +416,27 @@ impl JsonRpcRequestProcessor {
.ok() .ok()
.unwrap_or(None)) .unwrap_or(None))
} }
pub fn get_signature_status(
&self,
signatures: Vec<Signature>,
commitment: Option<CommitmentConfig>,
) -> Result<Vec<Option<RpcTransactionStatus>>> {
let mut statuses: Vec<Option<RpcTransactionStatus>> = vec![];
let bank = self.bank(commitment);
for signature in signatures {
let status = bank.get_signature_confirmation_status(&signature).map(
|SignatureConfirmationStatus { slot, status, .. }| RpcTransactionStatus {
slot,
status,
},
);
statuses.push(status);
}
Ok(statuses)
}
} }
fn get_tpu_addr(cluster_info: &Arc<RwLock<ClusterInfo>>) -> Result<SocketAddr> { fn get_tpu_addr(cluster_info: &Arc<RwLock<ClusterInfo>>) -> Result<SocketAddr> {
@ -548,9 +563,9 @@ pub trait RpcSol {
fn get_signature_status( fn get_signature_status(
&self, &self,
meta: Self::Metadata, meta: Self::Metadata,
signature_str: String, signature_strs: Vec<String>,
commitment: Option<CommitmentConfig>, commitment: Option<CommitmentConfig>,
) -> Result<Option<transaction::Result<()>>>; ) -> Result<Vec<Option<RpcTransactionStatus>>>;
#[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>;
@ -894,11 +909,17 @@ impl RpcSol for RpcSolImpl {
fn get_signature_status( fn get_signature_status(
&self, &self,
meta: Self::Metadata, meta: Self::Metadata,
signature_str: String, signature_strs: Vec<String>,
commitment: Option<CommitmentConfig>, commitment: Option<CommitmentConfig>,
) -> Result<Option<transaction::Result<()>>> { ) -> Result<Vec<Option<RpcTransactionStatus>>> {
self.get_signature_confirmation(meta, signature_str, commitment) let mut signatures: Vec<Signature> = vec![];
.map(|res| res.map(|x| x.status)) for signature_str in signature_strs {
signatures.push(verify_signature(&signature_str)?);
}
meta.request_processor
.read()
.unwrap()
.get_signature_status(signatures, commitment)
} }
fn get_slot(&self, meta: Self::Metadata, commitment: Option<CommitmentConfig>) -> Result<u64> { fn get_slot(&self, meta: Self::Metadata, commitment: Option<CommitmentConfig>) -> Result<u64> {
@ -1210,7 +1231,7 @@ pub mod tests {
rpc_port, rpc_port,
signature::{Keypair, Signer}, signature::{Keypair, Signer},
system_transaction, system_transaction,
transaction::TransactionError, transaction::{self, TransactionError},
}; };
use solana_vote_program::{ use solana_vote_program::{
vote_instruction, vote_instruction,
@ -1339,7 +1360,7 @@ pub mod tests {
let request_processor = Arc::new(RwLock::new(JsonRpcRequestProcessor::new( let request_processor = Arc::new(RwLock::new(JsonRpcRequestProcessor::new(
JsonRpcConfig { JsonRpcConfig {
enable_get_confirmed_block: true, enable_rpc_transaction_history: true,
identity_pubkey: *pubkey, identity_pubkey: *pubkey,
..JsonRpcConfig::default() ..JsonRpcConfig::default()
}, },
@ -1783,66 +1804,50 @@ pub mod tests {
meta, meta,
blockhash, blockhash,
alice, alice,
confirmed_block_signatures,
.. ..
} = start_rpc_handler_with_tx(&bob_pubkey); } = start_rpc_handler_with_tx(&bob_pubkey);
let tx = system_transaction::transfer(&alice, &bob_pubkey, 20, blockhash);
let req = format!( let req = format!(
r#"{{"jsonrpc":"2.0","id":1,"method":"getSignatureStatus","params":["{}"]}}"#, r#"{{"jsonrpc":"2.0","id":1,"method":"getSignatureStatus","params":[["{}"]]}}"#,
tx.signatures[0] confirmed_block_signatures[0]
); );
let res = io.handle_request_sync(&req, meta.clone()); let res = io.handle_request_sync(&req, meta.clone());
let expected_res: Option<transaction::Result<()>> = Some(Ok(())); let expected_res: transaction::Result<()> = Ok(());
let expected = json!({ let json: Value = serde_json::from_str(&res.unwrap()).unwrap();
"jsonrpc": "2.0", let result: Vec<Option<RpcTransactionStatus>> =
"result": expected_res, serde_json::from_value(json["result"].clone())
"id": 1 .expect("actual response deserialization");
}); assert_eq!(expected_res, result[0].as_ref().unwrap().status);
let expected: Response =
serde_json::from_value(expected).expect("expected response deserialization");
let result: Response = serde_json::from_str(&res.expect("actual response"))
.expect("actual response deserialization");
assert_eq!(expected, result);
// Test getSignatureStatus request on unprocessed tx // Test getSignatureStatus request on unprocessed tx
let tx = system_transaction::transfer(&alice, &bob_pubkey, 10, blockhash); let tx = system_transaction::transfer(&alice, &bob_pubkey, 10, blockhash);
let req = format!( let req = format!(
r#"{{"jsonrpc":"2.0","id":1,"method":"getSignatureStatus","params":["{}"]}}"#, r#"{{"jsonrpc":"2.0","id":1,"method":"getSignatureStatus","params":[["{}"]]}}"#,
tx.signatures[0] tx.signatures[0]
); );
let res = io.handle_request_sync(&req, meta.clone()); let res = io.handle_request_sync(&req, meta.clone());
let expected_res: Option<String> = None; let json: Value = serde_json::from_str(&res.unwrap()).unwrap();
let expected = json!({ let result: Vec<Option<RpcTransactionStatus>> =
"jsonrpc": "2.0", serde_json::from_value(json["result"].clone())
"result": expected_res, .expect("actual response deserialization");
"id": 1 assert!(result[0].is_none());
});
let expected: Response =
serde_json::from_value(expected).expect("expected response deserialization");
let result: Response = serde_json::from_str(&res.expect("actual response"))
.expect("actual response deserialization");
assert_eq!(expected, result);
// Test getSignatureStatus request on a TransactionError // Test getSignatureStatus request on a TransactionError
let tx = system_transaction::transfer(&alice, &bob_pubkey, std::u64::MAX, blockhash);
let req = format!( let req = format!(
r#"{{"jsonrpc":"2.0","id":1,"method":"getSignatureStatus","params":["{}"]}}"#, r#"{{"jsonrpc":"2.0","id":1,"method":"getSignatureStatus","params":[["{}"]]}}"#,
tx.signatures[0] confirmed_block_signatures[1]
); );
let res = io.handle_request_sync(&req, meta); let res = io.handle_request_sync(&req, meta.clone());
let expected_res: Option<transaction::Result<()>> = Some(Err( let expected_res: transaction::Result<()> = Err(TransactionError::InstructionError(
TransactionError::InstructionError(0, InstructionError::CustomError(1)), 0,
InstructionError::CustomError(1),
)); ));
let expected = json!({ let json: Value = serde_json::from_str(&res.unwrap()).unwrap();
"jsonrpc": "2.0", let result: Vec<Option<RpcTransactionStatus>> =
"result": expected_res, serde_json::from_value(json["result"].clone())
"id": 1 .expect("actual response deserialization");
}); assert_eq!(expected_res, result[0].as_ref().unwrap().status);
let expected: Response =
serde_json::from_value(expected).expect("expected response deserialization");
let result: Response = serde_json::from_str(&res.expect("actual response"))
.expect("actual response deserialization");
assert_eq!(expected, result);
} }
#[test] #[test]

View File

@ -1,5 +1,5 @@
use crossbeam_channel::{Receiver, RecvTimeoutError}; use crossbeam_channel::{Receiver, RecvTimeoutError};
use solana_client::rpc_response::RpcTransactionStatus; 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},
@ -73,7 +73,7 @@ impl TransactionStatusService {
blockstore blockstore
.write_transaction_status( .write_transaction_status(
(slot, transaction.signatures[0]), (slot, transaction.signatures[0]),
&RpcTransactionStatus { &RpcTransactionStatusMeta {
status, status,
fee, fee,
pre_balances, pre_balances,

View File

@ -266,7 +266,7 @@ impl Validator {
}); });
let (transaction_status_sender, transaction_status_service) = let (transaction_status_sender, transaction_status_service) =
if rpc_service.is_some() && config.rpc_config.enable_get_confirmed_block { if rpc_service.is_some() && config.rpc_config.enable_rpc_transaction_history {
let (transaction_status_sender, transaction_status_receiver) = unbounded(); let (transaction_status_sender, transaction_status_receiver) = unbounded();
( (
Some(transaction_status_sender), Some(transaction_status_sender),
@ -281,7 +281,7 @@ impl Validator {
}; };
let (rewards_recorder_sender, rewards_recorder_service) = let (rewards_recorder_sender, rewards_recorder_service) =
if rpc_service.is_some() && config.rpc_config.enable_get_confirmed_block { if rpc_service.is_some() && config.rpc_config.enable_rpc_transaction_history {
let (rewards_recorder_sender, rewards_receiver) = unbounded(); let (rewards_recorder_sender, rewards_receiver) = unbounded();
( (
Some(rewards_recorder_sender), Some(rewards_recorder_sender),

View File

@ -693,24 +693,30 @@ Returns the status of a given signature. This method is similar to [confirmTrans
#### Parameters: #### Parameters:
* `<string>` - Signature of Transaction to confirm, as base-58 encoded string * `<array>` - An array of transaction signatures to confirm, as base-58 encoded strings
* `<object>` - (optional) [Commitment](jsonrpc-api.md#configuring-state-commitment) * `<object>` - (optional) Extended Rpc configuration, containing the following optional fields:
* `commitment: <string>` - [Commitment](jsonrpc-api.md#configuring-state-commitment)
* `searchTransactionHistory: <bool>` - whether to search the ledger transaction status cache, which may be expensive
#### Results: #### Results:
An array of:
* `<null>` - Unknown transaction * `<null>` - Unknown transaction
* `<object>` - Transaction status: * `<object>`
* `"Ok": <null>` - Transaction was successful * `slot: <u64>` - The slot the transaction was processed
* `"Err": <ERR>` - Transaction failed with TransactionError [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L14) * `status: <object>` - Transaction status
* `"Ok": <null>` - Transaction was successful
* `"Err": <ERR>` - Transaction failed with TransactionError [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L14)
#### Example: #### Example:
```bash ```bash
// Request // Request
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getSignatureStatus", "params":["5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW"]}' http://localhost:8899 curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"getSignatureStatus", "params":[["5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW", "5j7s6NiJS3JAkvgkoc18WVAsiSaci2pxB2A6ueCJP4tprA2TFg9wSyTLeYouxPBJEMzJinENTkpA52YStRW5Dia7"]]]}' http://localhost:8899
// Result // Result
{"jsonrpc":"2.0","result":{"Ok": null},"id":1} {"jsonrpc":"2.0","result":[{"slot": 72, "status": {"Ok": null}}, null],"id":1}
``` ```
### getSlot ### getSlot

View File

@ -24,7 +24,7 @@ use rayon::{
use rocksdb::DBRawIterator; use rocksdb::DBRawIterator;
use solana_client::rpc_response::{ use solana_client::rpc_response::{
RpcConfirmedBlock, RpcEncodedTransaction, RpcRewards, RpcTransactionEncoding, RpcConfirmedBlock, RpcEncodedTransaction, RpcRewards, RpcTransactionEncoding,
RpcTransactionStatus, RpcTransactionWithStatusMeta, 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};
@ -1501,7 +1501,7 @@ impl Blockstore {
pub fn write_transaction_status( pub fn write_transaction_status(
&self, &self,
index: (Slot, Signature), index: (Slot, Signature),
status: &RpcTransactionStatus, status: &RpcTransactionStatusMeta,
) -> Result<()> { ) -> Result<()> {
self.transaction_status_cf.put(index, status) self.transaction_status_cf.put(index, status)
} }
@ -4829,7 +4829,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<RpcTransactionStatus>)> = entries let expected_transactions: Vec<(Transaction, Option<RpcTransactionStatusMeta>)> = entries
.iter() .iter()
.cloned() .cloned()
.filter(|entry| !entry.is_tick()) .filter(|entry| !entry.is_tick())
@ -4846,7 +4846,7 @@ pub mod tests {
.transaction_status_cf .transaction_status_cf
.put( .put(
(slot, signature), (slot, signature),
&RpcTransactionStatus { &RpcTransactionStatusMeta {
status: Ok(()), status: Ok(()),
fee: 42, fee: 42,
pre_balances: pre_balances.clone(), pre_balances: pre_balances.clone(),
@ -4858,7 +4858,7 @@ pub mod tests {
.transaction_status_cf .transaction_status_cf
.put( .put(
(slot + 1, signature), (slot + 1, signature),
&RpcTransactionStatus { &RpcTransactionStatusMeta {
status: Ok(()), status: Ok(()),
fee: 42, fee: 42,
pre_balances: pre_balances.clone(), pre_balances: pre_balances.clone(),
@ -4868,7 +4868,7 @@ pub mod tests {
.unwrap(); .unwrap();
( (
transaction, transaction,
Some(RpcTransactionStatus { Some(RpcTransactionStatusMeta {
status: Ok(()), status: Ok(()),
fee: 42, fee: 42,
pre_balances, pre_balances,
@ -5131,7 +5131,7 @@ pub mod tests {
assert!(transaction_status_cf assert!(transaction_status_cf
.put( .put(
(0, Signature::default()), (0, Signature::default()),
&RpcTransactionStatus { &RpcTransactionStatusMeta {
status: solana_sdk::transaction::Result::<()>::Err( status: solana_sdk::transaction::Result::<()>::Err(
TransactionError::AccountNotFound TransactionError::AccountNotFound
), ),
@ -5143,7 +5143,7 @@ pub mod tests {
.is_ok()); .is_ok());
// result found // result found
let RpcTransactionStatus { let RpcTransactionStatusMeta {
status, status,
fee, fee,
pre_balances, pre_balances,
@ -5161,7 +5161,7 @@ pub mod tests {
assert!(transaction_status_cf assert!(transaction_status_cf
.put( .put(
(9, Signature::default()), (9, Signature::default()),
&RpcTransactionStatus { &RpcTransactionStatusMeta {
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(),
@ -5171,7 +5171,7 @@ pub mod tests {
.is_ok()); .is_ok());
// result found // result found
let RpcTransactionStatus { let RpcTransactionStatusMeta {
status, status,
fee, fee,
pre_balances, pre_balances,
@ -5226,7 +5226,7 @@ pub mod tests {
transaction_status_cf transaction_status_cf
.put( .put(
(slot, transaction.signatures[0]), (slot, transaction.signatures[0]),
&RpcTransactionStatus { &RpcTransactionStatusMeta {
status: solana_sdk::transaction::Result::<()>::Err( status: solana_sdk::transaction::Result::<()>::Err(
TransactionError::AccountNotFound, TransactionError::AccountNotFound,
), ),

View File

@ -10,7 +10,7 @@ use rocksdb::{
}; };
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use serde::Serialize; use serde::Serialize;
use solana_client::rpc_response::{RpcRewards, RpcTransactionStatus}; use solana_client::rpc_response::{RpcRewards, RpcTransactionStatusMeta};
use solana_sdk::{clock::Slot, signature::Signature}; use solana_sdk::{clock::Slot, signature::Signature};
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 = RpcTransactionStatus; type Type = RpcTransactionStatusMeta;
} }
pub trait SlotColumn<Index = u64> {} pub trait SlotColumn<Index = u64> {}

View File

@ -42,7 +42,7 @@ while [[ -n $1 ]]; do
elif [[ $1 = --no-rocksdb-compaction ]]; then elif [[ $1 = --no-rocksdb-compaction ]]; then
args+=("$1") args+=("$1")
shift shift
elif [[ $1 = --enable-rpc-get-confirmed-block ]]; then elif [[ $1 = --enable-rpc-transaction-history ]]; then
args+=("$1") args+=("$1")
shift shift
elif [[ $1 = --skip-poh-verify ]]; then elif [[ $1 = --skip-poh-verify ]]; then

View File

@ -132,7 +132,7 @@ while [[ -n $1 ]]; do
elif [[ $1 = --no-rocksdb-compaction ]]; then elif [[ $1 = --no-rocksdb-compaction ]]; then
args+=("$1") args+=("$1")
shift shift
elif [[ $1 = --enable-rpc-get-confirmed-block ]]; then elif [[ $1 = --enable-rpc-transaction-history ]]; then
args+=("$1") args+=("$1")
shift shift
elif [[ $1 = --skip-poh-verify ]]; then elif [[ $1 = --skip-poh-verify ]]; then

View File

@ -290,7 +290,7 @@ EOF
--blockstream /tmp/solana-blockstream.sock --blockstream /tmp/solana-blockstream.sock
--no-voting --no-voting
--dev-no-sigverify --dev-no-sigverify
--enable-rpc-get-confirmed-block --enable-rpc-transaction-history
) )
else else
if [[ -n $internalNodesLamports ]]; then if [[ -n $internalNodesLamports ]]; then

2
run.sh
View File

@ -94,7 +94,7 @@ args=(
--rpc-faucet-address 127.0.0.1:9900 --rpc-faucet-address 127.0.0.1:9900
--log - --log -
--enable-rpc-exit --enable-rpc-exit
--enable-rpc-get-confirmed-block --enable-rpc-transaction-history
--init-complete-file "$dataDir"/init-completed --init-complete-file "$dataDir"/init-completed
) )
solana-validator "${args[@]}" & solana-validator "${args[@]}" &

View File

@ -117,20 +117,15 @@ impl<T: Serialize + Clone> StatusCache<T> {
trace!("get_signature_status_slow: trying {}", blockhash); trace!("get_signature_status_slow: trying {}", blockhash);
if let Some((forkid, res)) = self.get_signature_status(sig, blockhash, ancestors) { if let Some((forkid, res)) = self.get_signature_status(sig, blockhash, ancestors) {
trace!("get_signature_status_slow: got {}", forkid); trace!("get_signature_status_slow: got {}", forkid);
return ancestors let confirmations = ancestors
.get(&forkid) .get(&forkid)
.map(|id| SignatureConfirmationStatus { .copied()
slot: forkid, .unwrap_or_else(|| ancestors.len());
confirmations: *id, return Some(SignatureConfirmationStatus {
status: res.clone(), slot: forkid,
}) confirmations,
.or_else(|| { status: res,
Some(SignatureConfirmationStatus { });
slot: forkid,
confirmations: ancestors.len(),
status: res,
})
});
} }
} }
None None

View File

@ -502,10 +502,10 @@ pub fn main() {
.help("Enable the JSON RPC 'setLogFilter' API. Only enable in a debug environment"), .help("Enable the JSON RPC 'setLogFilter' API. Only enable in a debug environment"),
) )
.arg( .arg(
Arg::with_name("enable_rpc_get_confirmed_block") Arg::with_name("enable_rpc_transaction_history")
.long("enable-rpc-get-confirmed-block") .long("enable-rpc-transaction-history")
.takes_value(false) .takes_value(false)
.help("Enable the JSON RPC 'getConfirmedBlock' API. This will cause an increase in disk usage and IOPS"), .help("Enable historical transaction info over JSON RPC, including the 'getConfirmedBlock' API. This will cause an increase in disk usage and IOPS"),
) )
.arg( .arg(
Arg::with_name("rpc_faucet_addr") Arg::with_name("rpc_faucet_addr")
@ -742,7 +742,7 @@ pub fn main() {
rpc_config: JsonRpcConfig { rpc_config: JsonRpcConfig {
enable_validator_exit: matches.is_present("enable_rpc_exit"), enable_validator_exit: matches.is_present("enable_rpc_exit"),
enable_set_log_filter: matches.is_present("enable_rpc_set_log_filter"), enable_set_log_filter: matches.is_present("enable_rpc_set_log_filter"),
enable_get_confirmed_block: matches.is_present("enable_rpc_get_confirmed_block"), enable_rpc_transaction_history: matches.is_present("enable_rpc_transaction_history"),
identity_pubkey: identity_keypair.pubkey(), identity_pubkey: identity_keypair.pubkey(),
faucet_addr: matches.value_of("rpc_faucet_addr").map(|address| { faucet_addr: matches.value_of("rpc_faucet_addr").map(|address| {
solana_net_utils::parse_host_port(address).expect("failed to parse faucet address") solana_net_utils::parse_host_port(address).expect("failed to parse faucet address")