Update getBlock/getTransaction rpc handling of return_data (#27672)

* Move return_data type to transaction-status crate

* Use UiTransactionReturnData in UiTransactionStatusMeta

* Fixup display handling

* Update docs
This commit is contained in:
Tyera Eulberg 2022-09-08 14:10:57 -07:00 committed by GitHub
parent 7a1f4ffa6b
commit 0bfc188375
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 32 deletions

View File

@ -15,9 +15,10 @@ use {
signature::Signature,
stake,
transaction::{TransactionError, TransactionVersion, VersionedTransaction},
transaction_context::TransactionReturnData,
},
solana_transaction_status::{Rewards, UiTransactionStatusMeta},
solana_transaction_status::{
Rewards, UiReturnDataEncoding, UiTransactionReturnData, UiTransactionStatusMeta,
},
spl_memo::{id as spl_memo_id, v1::id as spl_memo_v1_id},
std::{collections::HashMap, fmt, io, time::Duration},
};
@ -597,18 +598,27 @@ fn write_balances<W: io::Write>(
fn write_return_data<W: io::Write>(
w: &mut W,
return_data: Option<&TransactionReturnData>,
return_data: Option<&UiTransactionReturnData>,
prefix: &str,
) -> io::Result<()> {
if let Some(return_data) = return_data {
if !return_data.data.is_empty() {
let (data, encoding) = &return_data.data;
let raw_return_data = match encoding {
UiReturnDataEncoding::Base64 => base64::decode(data).map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!("could not parse data as {:?}: {:?}", encoding, err),
)
})?,
};
if !raw_return_data.is_empty() {
use pretty_hex::*;
writeln!(
w,
"{}Return Data from Program {}:",
prefix, return_data.program_id
)?;
writeln!(w, "{} {:?}", prefix, return_data.data.hex_dump())?;
writeln!(w, "{} {:?}", prefix, raw_return_data.hex_dump())?;
}
}
Ok(())
@ -724,6 +734,7 @@ mod test {
pubkey::Pubkey,
signature::{Keypair, Signer},
transaction::Transaction,
transaction_context::TransactionReturnData,
},
solana_transaction_status::{Reward, RewardType, TransactionStatusMeta},
std::io::BufWriter,

View File

@ -449,6 +449,9 @@ The result field will be an object with the following fields:
- `loadedAddresses: <object|undefined>` - Transaction addresses loaded from address lookup tables. Undefined if `maxSupportedTransactionVersion` is not set in request params.
- `writable: <array[string]>` - Ordered list of base-58 encoded addresses for writable loaded accounts
- `readonly: <array[string]>` - Ordered list of base-58 encoded addresses for readonly loaded accounts
- `returnData: <object|undefined>` - the most-recent return data generated by an instruction in the transaction, with the following fields:
- `programId: <string>`, the program that generated the return data, as base-58 encoded Pubkey
- `data: <[string, encoding]>`, the return data itself, as base-64 encoded binary data
- `version: <"legacy"|number|undefined>` - Transaction version. Undefined if `maxSupportedTransactionVersion` is not set in request params.
- `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|undefined>` - block-level rewards, present if rewards are requested; an array of JSON objects containing:
@ -3053,6 +3056,9 @@ Returns transaction details for a confirmed transaction
- `loadedAddresses: <object|undefined>` - Transaction addresses loaded from address lookup tables. Undefined if `maxSupportedTransactionVersion` is not set in request params.
- `writable: <array[string]>` - Ordered list of base-58 encoded addresses for writable loaded accounts
- `readonly: <array[string]>` - Ordered list of base-58 encoded addresses for readonly loaded accounts
- `returnData: <object|undefined>` - the most-recent return data generated by an instruction in the transaction, with the following fields:
- `programId: <string>`, the program that generated the return data, as base-58 encoded Pubkey
- `data: <[string, encoding]>`, the return data itself, as base-64 encoded binary data
- `version: <"legacy"|number|undefined>` - Transaction version. Undefined if `maxSupportedTransactionVersion` is not set in request params.
#### Example:

View File

@ -8,10 +8,10 @@ use {
hash::Hash,
inflation::Inflation,
transaction::{Result, TransactionError},
transaction_context::TransactionReturnData,
},
solana_transaction_status::{
ConfirmedTransactionStatusWithSignature, TransactionConfirmationStatus, UiConfirmedBlock,
UiTransactionReturnData,
},
std::{collections::HashMap, fmt, net::SocketAddr, str::FromStr},
thiserror::Error,
@ -399,29 +399,7 @@ pub struct RpcSimulateTransactionResult {
pub logs: Option<Vec<String>>,
pub accounts: Option<Vec<Option<UiAccount>>>,
pub units_consumed: Option<u64>,
pub return_data: Option<RpcTransactionReturnData>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct RpcTransactionReturnData {
pub program_id: String,
pub data: (String, ReturnDataEncoding),
}
impl From<TransactionReturnData> for RpcTransactionReturnData {
fn from(return_data: TransactionReturnData) -> Self {
Self {
program_id: return_data.program_id.to_string(),
data: (base64::encode(return_data.data), ReturnDataEncoding::Base64),
}
}
}
#[derive(Serialize, Deserialize, Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[serde(rename_all = "camelCase")]
pub enum ReturnDataEncoding {
Base64,
pub return_data: Option<UiTransactionReturnData>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]

View File

@ -327,7 +327,8 @@ pub struct UiTransactionStatusMeta {
pub rewards: Option<Rewards>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub loaded_addresses: Option<UiLoadedAddresses>,
pub return_data: Option<TransactionReturnData>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub return_data: Option<UiTransactionReturnData>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub compute_units_consumed: Option<u64>,
}
@ -380,7 +381,7 @@ impl UiTransactionStatusMeta {
.map(|balance| balance.into_iter().map(Into::into).collect()),
rewards: if show_rewards { meta.rewards } else { None },
loaded_addresses: None,
return_data: meta.return_data,
return_data: meta.return_data.map(|return_data| return_data.into()),
compute_units_consumed: meta.compute_units_consumed,
}
}
@ -406,7 +407,7 @@ impl From<TransactionStatusMeta> for UiTransactionStatusMeta {
.map(|balance| balance.into_iter().map(Into::into).collect()),
rewards: meta.rewards,
loaded_addresses: Some(UiLoadedAddresses::from(&meta.loaded_addresses)),
return_data: meta.return_data,
return_data: meta.return_data.map(|return_data| return_data.into()),
compute_units_consumed: meta.compute_units_consumed,
}
}
@ -1031,6 +1032,31 @@ pub struct TransactionByAddrInfo {
pub block_time: Option<UnixTimestamp>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct UiTransactionReturnData {
pub program_id: String,
pub data: (String, UiReturnDataEncoding),
}
impl From<TransactionReturnData> for UiTransactionReturnData {
fn from(return_data: TransactionReturnData) -> Self {
Self {
program_id: return_data.program_id.to_string(),
data: (
base64::encode(return_data.data),
UiReturnDataEncoding::Base64,
),
}
}
}
#[derive(Serialize, Deserialize, Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[serde(rename_all = "camelCase")]
pub enum UiReturnDataEncoding {
Base64,
}
#[cfg(test)]
mod test {
use super::*;