rpc: Add config options limiting getConfirmedBlock response data (#15970)
* Add new confirmed block struct * Add RpcConfirmedBlockConfig options * Configure block response based on new options * Add client api, use in cli fetch_epoch_rewards * Update docs * Apply review suggestions
This commit is contained in:
parent
9760fded2d
commit
aa54c468ea
@ -27,6 +27,7 @@ use solana_client::{
|
|||||||
client_error::{ClientError, ClientErrorKind},
|
client_error::{ClientError, ClientErrorKind},
|
||||||
nonce_utils,
|
nonce_utils,
|
||||||
rpc_client::RpcClient,
|
rpc_client::RpcClient,
|
||||||
|
rpc_config::RpcConfirmedBlockConfig,
|
||||||
rpc_custom_error,
|
rpc_custom_error,
|
||||||
rpc_request::{self, DELINQUENT_VALIDATOR_SLOT_DISTANCE},
|
rpc_request::{self, DELINQUENT_VALIDATOR_SLOT_DISTANCE},
|
||||||
};
|
};
|
||||||
@ -1674,9 +1675,9 @@ pub(crate) fn fetch_epoch_rewards(
|
|||||||
.get(0)
|
.get(0)
|
||||||
.ok_or_else(|| format!("Unable to fetch first confirmed block for epoch {}", epoch))?;
|
.ok_or_else(|| format!("Unable to fetch first confirmed block for epoch {}", epoch))?;
|
||||||
|
|
||||||
let first_confirmed_block = match rpc_client.get_confirmed_block_with_encoding(
|
let first_confirmed_block = match rpc_client.get_configured_confirmed_block(
|
||||||
first_confirmed_block_in_epoch,
|
first_confirmed_block_in_epoch,
|
||||||
solana_transaction_status::UiTransactionEncoding::Base64,
|
RpcConfirmedBlockConfig::rewards_only(),
|
||||||
) {
|
) {
|
||||||
Ok(first_confirmed_block) => first_confirmed_block,
|
Ok(first_confirmed_block) => first_confirmed_block,
|
||||||
Err(ClientError {
|
Err(ClientError {
|
||||||
@ -1702,7 +1703,7 @@ pub(crate) fn fetch_epoch_rewards(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Rewards for the previous epoch are found in the first confirmed block of the current epoch
|
// Rewards for the previous epoch are found in the first confirmed block of the current epoch
|
||||||
let previous_epoch_rewards = first_confirmed_block.rewards;
|
let previous_epoch_rewards = first_confirmed_block.rewards.unwrap_or_default();
|
||||||
|
|
||||||
if let Some((effective_slot, epoch_end_time, epoch_rewards)) = epoch_info {
|
if let Some((effective_slot, epoch_end_time, epoch_rewards)) = epoch_info {
|
||||||
let wallclock_epoch_duration = if epoch_end_time > epoch_start_time {
|
let wallclock_epoch_duration = if epoch_end_time > epoch_start_time {
|
||||||
|
@ -4,9 +4,9 @@ use crate::{
|
|||||||
mock_sender::{MockSender, Mocks},
|
mock_sender::{MockSender, Mocks},
|
||||||
rpc_config::RpcAccountInfoConfig,
|
rpc_config::RpcAccountInfoConfig,
|
||||||
rpc_config::{
|
rpc_config::{
|
||||||
RpcGetConfirmedSignaturesForAddress2Config, RpcLargestAccountsConfig,
|
RpcConfirmedBlockConfig, RpcGetConfirmedSignaturesForAddress2Config,
|
||||||
RpcProgramAccountsConfig, RpcSendTransactionConfig, RpcSimulateTransactionConfig,
|
RpcLargestAccountsConfig, RpcProgramAccountsConfig, RpcSendTransactionConfig,
|
||||||
RpcTokenAccountsFilter,
|
RpcSimulateTransactionConfig, RpcTokenAccountsFilter,
|
||||||
},
|
},
|
||||||
rpc_request::{RpcError, RpcRequest, RpcResponseErrorData, TokenAccountsFilter},
|
rpc_request::{RpcError, RpcRequest, RpcResponseErrorData, TokenAccountsFilter},
|
||||||
rpc_response::*,
|
rpc_response::*,
|
||||||
@ -33,7 +33,8 @@ use solana_sdk::{
|
|||||||
transaction::{self, uses_durable_nonce, Transaction},
|
transaction::{self, uses_durable_nonce, Transaction},
|
||||||
};
|
};
|
||||||
use solana_transaction_status::{
|
use solana_transaction_status::{
|
||||||
EncodedConfirmedBlock, EncodedConfirmedTransaction, TransactionStatus, UiTransactionEncoding,
|
EncodedConfirmedBlock, EncodedConfirmedTransaction, TransactionStatus, UiConfirmedBlock,
|
||||||
|
UiTransactionEncoding,
|
||||||
};
|
};
|
||||||
use solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY;
|
use solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY;
|
||||||
use std::{
|
use std::{
|
||||||
@ -507,6 +508,14 @@ impl RpcClient {
|
|||||||
self.send(RpcRequest::GetConfirmedBlock, json!([slot, encoding]))
|
self.send(RpcRequest::GetConfirmedBlock, json!([slot, encoding]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_configured_confirmed_block(
|
||||||
|
&self,
|
||||||
|
slot: Slot,
|
||||||
|
config: RpcConfirmedBlockConfig,
|
||||||
|
) -> ClientResult<UiConfirmedBlock> {
|
||||||
|
self.send(RpcRequest::GetConfirmedBlock, json!([slot, config]))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_confirmed_blocks(
|
pub fn get_confirmed_blocks(
|
||||||
&self,
|
&self,
|
||||||
start_slot: Slot,
|
start_slot: Slot,
|
||||||
|
@ -4,7 +4,7 @@ use solana_sdk::{
|
|||||||
clock::Epoch,
|
clock::Epoch,
|
||||||
commitment_config::{CommitmentConfig, CommitmentLevel},
|
commitment_config::{CommitmentConfig, CommitmentLevel},
|
||||||
};
|
};
|
||||||
use solana_transaction_status::UiTransactionEncoding;
|
use solana_transaction_status::{TransactionDetails, UiTransactionEncoding};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
@ -133,12 +133,24 @@ pub trait EncodingConfig {
|
|||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct RpcConfirmedBlockConfig {
|
pub struct RpcConfirmedBlockConfig {
|
||||||
pub encoding: Option<UiTransactionEncoding>,
|
pub encoding: Option<UiTransactionEncoding>,
|
||||||
|
pub transaction_details: Option<TransactionDetails>,
|
||||||
|
pub rewards: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EncodingConfig for RpcConfirmedBlockConfig {
|
impl EncodingConfig for RpcConfirmedBlockConfig {
|
||||||
fn new_with_encoding(encoding: &Option<UiTransactionEncoding>) -> Self {
|
fn new_with_encoding(encoding: &Option<UiTransactionEncoding>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
encoding: *encoding,
|
encoding: *encoding,
|
||||||
|
..Self::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RpcConfirmedBlockConfig {
|
||||||
|
pub fn rewards_only() -> Self {
|
||||||
|
Self {
|
||||||
|
transaction_details: Some(TransactionDetails::None),
|
||||||
|
..Self::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,8 +66,8 @@ use solana_sdk::{
|
|||||||
};
|
};
|
||||||
use solana_stake_program::stake_state::StakeState;
|
use solana_stake_program::stake_state::StakeState;
|
||||||
use solana_transaction_status::{
|
use solana_transaction_status::{
|
||||||
EncodedConfirmedBlock, EncodedConfirmedTransaction, TransactionConfirmationStatus,
|
EncodedConfirmedTransaction, TransactionConfirmationStatus, TransactionStatus,
|
||||||
TransactionStatus, UiTransactionEncoding,
|
UiConfirmedBlock, UiTransactionEncoding,
|
||||||
};
|
};
|
||||||
use solana_vote_program::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
|
use solana_vote_program::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
|
||||||
use spl_token_v2_0::{
|
use spl_token_v2_0::{
|
||||||
@ -720,11 +720,13 @@ impl JsonRpcRequestProcessor {
|
|||||||
&self,
|
&self,
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
config: Option<RpcEncodingConfigWrapper<RpcConfirmedBlockConfig>>,
|
config: Option<RpcEncodingConfigWrapper<RpcConfirmedBlockConfig>>,
|
||||||
) -> Result<Option<EncodedConfirmedBlock>> {
|
) -> Result<Option<UiConfirmedBlock>> {
|
||||||
let config = config
|
let config = config
|
||||||
.map(|config| config.convert_to_current())
|
.map(|config| config.convert_to_current())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let encoding = config.encoding.unwrap_or(UiTransactionEncoding::Json);
|
let encoding = config.encoding.unwrap_or(UiTransactionEncoding::Json);
|
||||||
|
let transaction_details = config.transaction_details.unwrap_or_default();
|
||||||
|
let show_rewards = config.rewards.unwrap_or(true);
|
||||||
if self.config.enable_rpc_transaction_history
|
if self.config.enable_rpc_transaction_history
|
||||||
&& slot
|
&& slot
|
||||||
<= self
|
<= self
|
||||||
@ -741,15 +743,15 @@ impl JsonRpcRequestProcessor {
|
|||||||
.runtime
|
.runtime
|
||||||
.block_on(bigtable_ledger_storage.get_confirmed_block(slot));
|
.block_on(bigtable_ledger_storage.get_confirmed_block(slot));
|
||||||
self.check_bigtable_result(&bigtable_result)?;
|
self.check_bigtable_result(&bigtable_result)?;
|
||||||
return Ok(bigtable_result
|
return Ok(bigtable_result.ok().map(|confirmed_block| {
|
||||||
.ok()
|
confirmed_block.configure(encoding, transaction_details, show_rewards)
|
||||||
.map(|confirmed_block| confirmed_block.encode(encoding)));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.check_slot_cleaned_up(&result, slot)?;
|
self.check_slot_cleaned_up(&result, slot)?;
|
||||||
Ok(result
|
Ok(result.ok().map(|confirmed_block| {
|
||||||
.ok()
|
confirmed_block.configure(encoding, transaction_details, show_rewards)
|
||||||
.map(|confirmed_block| confirmed_block.encode(encoding)))
|
}))
|
||||||
} else {
|
} else {
|
||||||
Err(RpcCustomError::BlockNotAvailable { slot }.into())
|
Err(RpcCustomError::BlockNotAvailable { slot }.into())
|
||||||
}
|
}
|
||||||
@ -2185,7 +2187,7 @@ pub mod rpc_full {
|
|||||||
meta: Self::Metadata,
|
meta: Self::Metadata,
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
config: Option<RpcEncodingConfigWrapper<RpcConfirmedBlockConfig>>,
|
config: Option<RpcEncodingConfigWrapper<RpcConfirmedBlockConfig>>,
|
||||||
) -> Result<Option<EncodedConfirmedBlock>>;
|
) -> Result<Option<UiConfirmedBlock>>;
|
||||||
|
|
||||||
#[rpc(meta, name = "getBlockTime")]
|
#[rpc(meta, name = "getBlockTime")]
|
||||||
fn get_block_time(&self, meta: Self::Metadata, slot: Slot)
|
fn get_block_time(&self, meta: Self::Metadata, slot: Slot)
|
||||||
@ -2793,7 +2795,7 @@ pub mod rpc_full {
|
|||||||
meta: Self::Metadata,
|
meta: Self::Metadata,
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
config: Option<RpcEncodingConfigWrapper<RpcConfirmedBlockConfig>>,
|
config: Option<RpcEncodingConfigWrapper<RpcConfirmedBlockConfig>>,
|
||||||
) -> Result<Option<EncodedConfirmedBlock>> {
|
) -> Result<Option<UiConfirmedBlock>> {
|
||||||
debug!("get_confirmed_block rpc request received: {:?}", slot);
|
debug!("get_confirmed_block rpc request received: {:?}", slot);
|
||||||
meta.get_confirmed_block(slot, config)
|
meta.get_confirmed_block(slot, config)
|
||||||
}
|
}
|
||||||
@ -3119,7 +3121,8 @@ pub mod tests {
|
|||||||
transaction::{self, TransactionError},
|
transaction::{self, TransactionError},
|
||||||
};
|
};
|
||||||
use solana_transaction_status::{
|
use solana_transaction_status::{
|
||||||
EncodedTransaction, EncodedTransactionWithStatusMeta, UiMessage,
|
EncodedConfirmedBlock, EncodedTransaction, EncodedTransactionWithStatusMeta,
|
||||||
|
TransactionDetails, UiMessage,
|
||||||
};
|
};
|
||||||
use solana_vote_program::{
|
use solana_vote_program::{
|
||||||
vote_instruction,
|
vote_instruction,
|
||||||
@ -5077,6 +5080,7 @@ pub mod tests {
|
|||||||
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);
|
||||||
|
assert_eq!(confirmed_block.rewards, vec![]);
|
||||||
|
|
||||||
for EncodedTransactionWithStatusMeta { transaction, meta } in
|
for EncodedTransactionWithStatusMeta { transaction, meta } in
|
||||||
confirmed_block.transactions.into_iter()
|
confirmed_block.transactions.into_iter()
|
||||||
@ -5121,6 +5125,7 @@ pub mod tests {
|
|||||||
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);
|
||||||
|
assert_eq!(confirmed_block.rewards, vec![]);
|
||||||
|
|
||||||
for EncodedTransactionWithStatusMeta { transaction, meta } in
|
for EncodedTransactionWithStatusMeta { transaction, meta } in
|
||||||
confirmed_block.transactions.into_iter()
|
confirmed_block.transactions.into_iter()
|
||||||
@ -5156,6 +5161,55 @@ pub mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_confirmed_block_config() {
|
||||||
|
let bob_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
|
let RpcHandler {
|
||||||
|
io,
|
||||||
|
meta,
|
||||||
|
confirmed_block_signatures,
|
||||||
|
..
|
||||||
|
} = start_rpc_handler_with_tx(&bob_pubkey);
|
||||||
|
|
||||||
|
let req = format!(
|
||||||
|
r#"{{"jsonrpc":"2.0","id":1,"method":"getConfirmedBlock","params":[0,{}]}}"#,
|
||||||
|
json!(RpcConfirmedBlockConfig {
|
||||||
|
encoding: None,
|
||||||
|
transaction_details: Some(TransactionDetails::Signatures),
|
||||||
|
rewards: Some(false),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
let res = io.handle_request_sync(&req, meta.clone());
|
||||||
|
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
||||||
|
.expect("actual response deserialization");
|
||||||
|
let confirmed_block: Option<UiConfirmedBlock> =
|
||||||
|
serde_json::from_value(result["result"].clone()).unwrap();
|
||||||
|
let confirmed_block = confirmed_block.unwrap();
|
||||||
|
assert!(confirmed_block.transactions.is_none());
|
||||||
|
assert!(confirmed_block.rewards.is_none());
|
||||||
|
for (i, signature) in confirmed_block.signatures.unwrap()[..2].iter().enumerate() {
|
||||||
|
assert_eq!(*signature, confirmed_block_signatures[i].to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let req = format!(
|
||||||
|
r#"{{"jsonrpc":"2.0","id":1,"method":"getConfirmedBlock","params":[0,{}]}}"#,
|
||||||
|
json!(RpcConfirmedBlockConfig {
|
||||||
|
encoding: None,
|
||||||
|
transaction_details: Some(TransactionDetails::None),
|
||||||
|
rewards: Some(true),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
let res = io.handle_request_sync(&req, meta);
|
||||||
|
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
||||||
|
.expect("actual response deserialization");
|
||||||
|
let confirmed_block: Option<UiConfirmedBlock> =
|
||||||
|
serde_json::from_value(result["result"].clone()).unwrap();
|
||||||
|
let confirmed_block = confirmed_block.unwrap();
|
||||||
|
assert!(confirmed_block.transactions.is_none());
|
||||||
|
assert!(confirmed_block.signatures.is_none());
|
||||||
|
assert_eq!(confirmed_block.rewards.unwrap(), vec![]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_confirmed_blocks() {
|
fn test_get_confirmed_blocks() {
|
||||||
let bob_pubkey = solana_sdk::pubkey::new_rand();
|
let bob_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
|
@ -460,6 +460,8 @@ Returns identity and transaction information about a confirmed block in the ledg
|
|||||||
- `<object>` - (optional) Configuration object containing the following optional fields:
|
- `<object>` - (optional) Configuration object containing the following optional fields:
|
||||||
- (optional) `encoding: <string>` - encoding for each returned Transaction, either "json", "jsonParsed", "base58" (*slow*), "base64". If parameter not provided, the default encoding is "json".
|
- (optional) `encoding: <string>` - encoding for each returned Transaction, either "json", "jsonParsed", "base58" (*slow*), "base64". If parameter not provided, the default encoding is "json".
|
||||||
"jsonParsed" encoding attempts to use program-specific instruction parsers to return more human-readable and explicit data in the `transaction.message.instructions` list. If "jsonParsed" is requested but a parser cannot be found, the instruction falls back to regular JSON encoding (`accounts`, `data`, and `programIdIndex` fields).
|
"jsonParsed" encoding attempts to use program-specific instruction parsers to return more human-readable and explicit data in the `transaction.message.instructions` list. If "jsonParsed" is requested but a parser cannot be found, the instruction falls back to regular JSON encoding (`accounts`, `data`, and `programIdIndex` fields).
|
||||||
|
- (optional) `transactionDetails: <string>` - level of transaction detail to return, either "full", "signatures", or "none". If parameter not provided, the default detail level is "full".
|
||||||
|
- (optional) `rewards: bool` - whether to populate the `rewards` array. If parameter not provided, the default includes rewards.
|
||||||
|
|
||||||
#### Results:
|
#### Results:
|
||||||
|
|
||||||
@ -470,7 +472,7 @@ The result field will be an object with the following fields:
|
|||||||
- `blockhash: <string>` - the blockhash of this block, as base-58 encoded string
|
- `blockhash: <string>` - the blockhash of this block, as base-58 encoded string
|
||||||
- `previousBlockhash: <string>` - the blockhash of this block's parent, as base-58 encoded string; if the parent block is not available due to ledger cleanup, this field will return "11111111111111111111111111111111"
|
- `previousBlockhash: <string>` - the blockhash of this block's parent, as base-58 encoded string; if the parent block is not available due to ledger cleanup, this field will return "11111111111111111111111111111111"
|
||||||
- `parentSlot: <u64>` - the slot index of this block's parent
|
- `parentSlot: <u64>` - the slot index of this block's parent
|
||||||
- `transactions: <array>` - an array of JSON objects containing:
|
- `transactions: <array>` - present if "full" transaction details are requested; an array of JSON objects containing:
|
||||||
- `transaction: <object|[string,encoding]>` - [Transaction](#transaction-structure) object, either in JSON format or encoded binary data, depending on encoding parameter
|
- `transaction: <object|[string,encoding]>` - [Transaction](#transaction-structure) object, either in JSON format or encoded binary data, depending on encoding parameter
|
||||||
- `meta: <object>` - transaction status metadata object, containing `null` or:
|
- `meta: <object>` - transaction status metadata object, containing `null` or:
|
||||||
- `err: <object | null>` - Error if transaction failed, null if transaction succeeded. [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L24)
|
- `err: <object | null>` - Error if transaction failed, null if transaction succeeded. [TransactionError definitions](https://github.com/solana-labs/solana/blob/master/sdk/src/transaction.rs#L24)
|
||||||
@ -484,7 +486,8 @@ The result field will be an object with the following fields:
|
|||||||
- DEPRECATED: `status: <object>` - Transaction status
|
- DEPRECATED: `status: <object>` - Transaction status
|
||||||
- `"Ok": <null>` - Transaction was successful
|
- `"Ok": <null>` - Transaction was successful
|
||||||
- `"Err": <ERR>` - Transaction failed with TransactionError
|
- `"Err": <ERR>` - Transaction failed with TransactionError
|
||||||
- `rewards: <array>` - an array of JSON objects containing:
|
- `signatures: <array>` - present if "signatures" are requested for transaction details; an array of signatures strings, corresponding to the transaction order in the block
|
||||||
|
- `rewards: <array>` - present if rewards are requested; an array of JSON objects containing:
|
||||||
- `pubkey: <string>` - The public key, as base-58 encoded string, of the account that received the reward
|
- `pubkey: <string>` - The public key, as base-58 encoded string, of the account that received the reward
|
||||||
- `lamports: <i64>`- number of reward lamports credited or debited by the account, as a i64
|
- `lamports: <i64>`- number of reward lamports credited or debited by the account, as a i64
|
||||||
- `postBalance: <u64>` - account balance in lamports after the reward was applied
|
- `postBalance: <u64>` - account balance in lamports after the reward was applied
|
||||||
@ -496,7 +499,7 @@ The result field will be an object with the following fields:
|
|||||||
Request:
|
Request:
|
||||||
```bash
|
```bash
|
||||||
curl http://localhost:8899 -X POST -H "Content-Type: application/json" -d '
|
curl http://localhost:8899 -X POST -H "Content-Type: application/json" -d '
|
||||||
{"jsonrpc": "2.0","id":1,"method":"getConfirmedBlock","params":[430, {"encoding": "json"}]}
|
{"jsonrpc": "2.0","id":1,"method":"getConfirmedBlock","params":[430, {"encoding": "json","transactionDetails":"full","rewards":false}]}
|
||||||
'
|
'
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -509,7 +512,6 @@ Result:
|
|||||||
"blockhash": "3Eq21vXNB5s86c62bVuUfTeaMif1N2kUqRPBmGRJhyTA",
|
"blockhash": "3Eq21vXNB5s86c62bVuUfTeaMif1N2kUqRPBmGRJhyTA",
|
||||||
"parentSlot": 429,
|
"parentSlot": 429,
|
||||||
"previousBlockhash": "mfcyqEXB3DnHXki6KjjmZck6YjmZLvpAByy2fj4nh6B",
|
"previousBlockhash": "mfcyqEXB3DnHXki6KjjmZck6YjmZLvpAByy2fj4nh6B",
|
||||||
"rewards": [],
|
|
||||||
"transactions": [
|
"transactions": [
|
||||||
{
|
{
|
||||||
"meta": {
|
"meta": {
|
||||||
|
@ -362,6 +362,48 @@ impl ConfirmedBlock {
|
|||||||
block_time: self.block_time,
|
block_time: self.block_time,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn configure(
|
||||||
|
self,
|
||||||
|
encoding: UiTransactionEncoding,
|
||||||
|
transaction_details: TransactionDetails,
|
||||||
|
show_rewards: bool,
|
||||||
|
) -> UiConfirmedBlock {
|
||||||
|
let (transactions, signatures) = match transaction_details {
|
||||||
|
TransactionDetails::Full => (
|
||||||
|
Some(
|
||||||
|
self.transactions
|
||||||
|
.into_iter()
|
||||||
|
.map(|tx| tx.encode(encoding))
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
TransactionDetails::Signatures => (
|
||||||
|
None,
|
||||||
|
Some(
|
||||||
|
self.transactions
|
||||||
|
.into_iter()
|
||||||
|
.map(|tx| tx.transaction.signatures[0].to_string())
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TransactionDetails::None => (None, None),
|
||||||
|
};
|
||||||
|
UiConfirmedBlock {
|
||||||
|
previous_blockhash: self.previous_blockhash,
|
||||||
|
blockhash: self.blockhash,
|
||||||
|
parent_slot: self.parent_slot,
|
||||||
|
transactions,
|
||||||
|
signatures,
|
||||||
|
rewards: if show_rewards {
|
||||||
|
Some(self.rewards)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
block_time: self.block_time,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
@ -375,6 +417,49 @@ pub struct EncodedConfirmedBlock {
|
|||||||
pub block_time: Option<UnixTimestamp>,
|
pub block_time: Option<UnixTimestamp>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct UiConfirmedBlock {
|
||||||
|
pub previous_blockhash: String,
|
||||||
|
pub blockhash: String,
|
||||||
|
pub parent_slot: Slot,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub transactions: Option<Vec<EncodedTransactionWithStatusMeta>>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub signatures: Option<Vec<String>>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub rewards: Option<Rewards>,
|
||||||
|
pub block_time: Option<UnixTimestamp>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<EncodedConfirmedBlock> for UiConfirmedBlock {
|
||||||
|
fn from(block: EncodedConfirmedBlock) -> Self {
|
||||||
|
Self {
|
||||||
|
previous_blockhash: block.previous_blockhash,
|
||||||
|
blockhash: block.blockhash,
|
||||||
|
parent_slot: block.parent_slot,
|
||||||
|
transactions: Some(block.transactions),
|
||||||
|
signatures: None,
|
||||||
|
rewards: Some(block.rewards),
|
||||||
|
block_time: block.block_time,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub enum TransactionDetails {
|
||||||
|
Full,
|
||||||
|
Signatures,
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for TransactionDetails {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Full
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ConfirmedTransaction {
|
pub struct ConfirmedTransaction {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user