Enforce tx metadata upload with static types (#23028)
This commit is contained in:
153
rpc/src/rpc.rs
153
rpc/src/rpc.rs
@ -80,10 +80,10 @@ use {
|
||||
solana_storage_bigtable::Error as StorageError,
|
||||
solana_streamer::socket::SocketAddrSpace,
|
||||
solana_transaction_status::{
|
||||
ConfirmedTransactionStatusWithSignature, Encodable,
|
||||
EncodedConfirmedTransactionWithStatusMeta, Reward, RewardType,
|
||||
TransactionConfirmationStatus, TransactionStatus, UiConfirmedBlock, UiTransactionEncoding,
|
||||
VersionedConfirmedBlock,
|
||||
ConfirmedBlock, ConfirmedTransactionStatusWithSignature,
|
||||
ConfirmedTransactionWithStatusMeta, Encodable, EncodedConfirmedTransactionWithStatusMeta,
|
||||
Reward, RewardType, TransactionConfirmationStatus, TransactionStatus, UiConfirmedBlock,
|
||||
UiTransactionEncoding,
|
||||
},
|
||||
solana_vote_program::vote_state::{VoteState, MAX_LOCKOUT_HISTORY},
|
||||
spl_token::{
|
||||
@ -918,12 +918,8 @@ impl JsonRpcRequestProcessor {
|
||||
&self,
|
||||
result: &std::result::Result<T, BlockstoreError>,
|
||||
slot: Slot,
|
||||
) -> Result<()>
|
||||
where
|
||||
T: std::fmt::Debug,
|
||||
{
|
||||
if result.is_err() {
|
||||
let err = result.as_ref().unwrap_err();
|
||||
) -> Result<()> {
|
||||
if let Err(err) = result {
|
||||
debug!(
|
||||
"check_blockstore_root, slot: {:?}, max root: {:?}, err: {:?}",
|
||||
slot,
|
||||
@ -944,21 +940,16 @@ impl JsonRpcRequestProcessor {
|
||||
&self,
|
||||
result: &std::result::Result<T, BlockstoreError>,
|
||||
slot: Slot,
|
||||
) -> Result<()>
|
||||
where
|
||||
T: std::fmt::Debug,
|
||||
{
|
||||
if result.is_err() {
|
||||
if let BlockstoreError::SlotCleanedUp = result.as_ref().unwrap_err() {
|
||||
return Err(RpcCustomError::BlockCleanedUp {
|
||||
slot,
|
||||
first_available_block: self
|
||||
.blockstore
|
||||
.get_first_available_block()
|
||||
.unwrap_or_default(),
|
||||
}
|
||||
.into());
|
||||
) -> Result<()> {
|
||||
if let Err(BlockstoreError::SlotCleanedUp) = result {
|
||||
return Err(RpcCustomError::BlockCleanedUp {
|
||||
slot,
|
||||
first_available_block: self
|
||||
.blockstore
|
||||
.get_first_available_block()
|
||||
.unwrap_or_default(),
|
||||
}
|
||||
.into());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -966,15 +957,9 @@ impl JsonRpcRequestProcessor {
|
||||
fn check_bigtable_result<T>(
|
||||
&self,
|
||||
result: &std::result::Result<T, solana_storage_bigtable::Error>,
|
||||
) -> Result<()>
|
||||
where
|
||||
T: std::fmt::Debug,
|
||||
{
|
||||
if result.is_err() {
|
||||
let err = result.as_ref().unwrap_err();
|
||||
if let solana_storage_bigtable::Error::BlockNotFound(slot) = err {
|
||||
return Err(RpcCustomError::LongTermStorageSlotSkipped { slot: *slot }.into());
|
||||
}
|
||||
) -> Result<()> {
|
||||
if let Err(solana_storage_bigtable::Error::BlockNotFound(slot)) = result {
|
||||
return Err(RpcCustomError::LongTermStorageSlotSkipped { slot: *slot }.into());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -1017,12 +1002,12 @@ impl JsonRpcRequestProcessor {
|
||||
self.check_status_is_complete(slot)?;
|
||||
let result = self.blockstore.get_rooted_block(slot, true);
|
||||
self.check_blockstore_root(&result, slot)?;
|
||||
let configure_block = |versioned_block: VersionedConfirmedBlock| {
|
||||
let confirmed_block = versioned_block
|
||||
let configure_block = |confirmed_block: ConfirmedBlock| {
|
||||
let legacy_block = confirmed_block
|
||||
.into_legacy_block()
|
||||
.ok_or(RpcCustomError::UnsupportedTransactionVersion)?;
|
||||
let mut confirmed_block =
|
||||
confirmed_block.configure(encoding, transaction_details, show_rewards);
|
||||
legacy_block.configure(encoding, transaction_details, show_rewards);
|
||||
if slot == 0 {
|
||||
confirmed_block.block_time = Some(self.genesis_creation_time());
|
||||
confirmed_block.block_height = Some(0);
|
||||
@ -1038,7 +1023,11 @@ impl JsonRpcRequestProcessor {
|
||||
}
|
||||
}
|
||||
self.check_slot_cleaned_up(&result, slot)?;
|
||||
return result.ok().map(configure_block).transpose();
|
||||
return result
|
||||
.ok()
|
||||
.map(ConfirmedBlock::from)
|
||||
.map(configure_block)
|
||||
.transpose();
|
||||
} else if commitment.is_confirmed() {
|
||||
// Check if block is confirmed
|
||||
let confirmed_bank = self.bank(Some(CommitmentConfig::confirmed()));
|
||||
@ -1047,30 +1036,28 @@ impl JsonRpcRequestProcessor {
|
||||
let result = self.blockstore.get_complete_block(slot, true);
|
||||
return result
|
||||
.ok()
|
||||
.map(|versioned_block| {
|
||||
let mut confirmed_block = versioned_block
|
||||
.map(ConfirmedBlock::from)
|
||||
.map(|confirmed_block| -> Result<UiConfirmedBlock> {
|
||||
let mut legacy_block = confirmed_block
|
||||
.into_legacy_block()
|
||||
.ok_or(RpcCustomError::UnsupportedTransactionVersion)?;
|
||||
if confirmed_block.block_time.is_none()
|
||||
|| confirmed_block.block_height.is_none()
|
||||
|
||||
if legacy_block.block_time.is_none()
|
||||
|| legacy_block.block_height.is_none()
|
||||
{
|
||||
let r_bank_forks = self.bank_forks.read().unwrap();
|
||||
let bank = r_bank_forks.get(slot).cloned();
|
||||
if let Some(bank) = bank {
|
||||
if confirmed_block.block_time.is_none() {
|
||||
confirmed_block.block_time =
|
||||
Some(bank.clock().unix_timestamp);
|
||||
if legacy_block.block_time.is_none() {
|
||||
legacy_block.block_time = Some(bank.clock().unix_timestamp);
|
||||
}
|
||||
if confirmed_block.block_height.is_none() {
|
||||
confirmed_block.block_height = Some(bank.block_height());
|
||||
if legacy_block.block_height.is_none() {
|
||||
legacy_block.block_height = Some(bank.block_height());
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(confirmed_block.configure(
|
||||
encoding,
|
||||
transaction_details,
|
||||
show_rewards,
|
||||
))
|
||||
|
||||
Ok(legacy_block.configure(encoding, transaction_details, show_rewards))
|
||||
})
|
||||
.transpose();
|
||||
}
|
||||
@ -1397,7 +1384,7 @@ impl JsonRpcRequestProcessor {
|
||||
|
||||
if self.config.enable_rpc_transaction_history {
|
||||
let confirmed_bank = self.bank(Some(CommitmentConfig::confirmed()));
|
||||
let versioned_confirmed_tx = if commitment.is_confirmed() {
|
||||
let confirmed_transaction = if commitment.is_confirmed() {
|
||||
let highest_confirmed_slot = confirmed_bank.slot();
|
||||
self.blockstore
|
||||
.get_complete_transaction(signature, highest_confirmed_slot)
|
||||
@ -1405,12 +1392,16 @@ impl JsonRpcRequestProcessor {
|
||||
self.blockstore.get_rooted_transaction(signature)
|
||||
};
|
||||
|
||||
match versioned_confirmed_tx.unwrap_or(None) {
|
||||
Some(versioned_confirmed_tx) => {
|
||||
let mut confirmed_transaction = versioned_confirmed_tx
|
||||
.into_legacy_confirmed_transaction()
|
||||
let encode_transaction =
|
||||
|confirmed_tx_with_meta: ConfirmedTransactionWithStatusMeta| -> Result<EncodedConfirmedTransactionWithStatusMeta> {
|
||||
let legacy_tx_with_meta = confirmed_tx_with_meta.into_legacy_confirmed_transaction()
|
||||
.ok_or(RpcCustomError::UnsupportedTransactionVersion)?;
|
||||
|
||||
Ok(legacy_tx_with_meta.encode(encoding))
|
||||
};
|
||||
|
||||
match confirmed_transaction.unwrap_or(None) {
|
||||
Some(mut confirmed_transaction) => {
|
||||
if commitment.is_confirmed()
|
||||
&& confirmed_bank // should be redundant
|
||||
.status_cache_ancestors()
|
||||
@ -1422,8 +1413,9 @@ impl JsonRpcRequestProcessor {
|
||||
.get(confirmed_transaction.slot)
|
||||
.map(|bank| bank.clock().unix_timestamp);
|
||||
}
|
||||
return Ok(Some(confirmed_transaction.encode(encoding)));
|
||||
return Ok(Some(encode_transaction(confirmed_transaction)?));
|
||||
}
|
||||
|
||||
if confirmed_transaction.slot
|
||||
<= self
|
||||
.block_commitment_cache
|
||||
@ -1431,7 +1423,7 @@ impl JsonRpcRequestProcessor {
|
||||
.unwrap()
|
||||
.highest_confirmed_root()
|
||||
{
|
||||
return Ok(Some(confirmed_transaction.encode(encoding)));
|
||||
return Ok(Some(encode_transaction(confirmed_transaction)?));
|
||||
}
|
||||
}
|
||||
None => {
|
||||
@ -1440,13 +1432,7 @@ impl JsonRpcRequestProcessor {
|
||||
.get_confirmed_transaction(&signature)
|
||||
.await
|
||||
.unwrap_or(None)
|
||||
.map(|versioned_confirmed_tx| {
|
||||
let confirmed_tx = versioned_confirmed_tx
|
||||
.into_legacy_confirmed_transaction()
|
||||
.ok_or(RpcCustomError::UnsupportedTransactionVersion)?;
|
||||
|
||||
Ok(confirmed_tx.encode(encoding))
|
||||
})
|
||||
.map(encode_transaction)
|
||||
.transpose();
|
||||
}
|
||||
}
|
||||
@ -4328,15 +4314,7 @@ pub fn create_test_transactions_and_populate_blockstore(
|
||||
);
|
||||
let ix_error_signature = ix_error_tx.signatures[0];
|
||||
let entry_2 = solana_entry::entry::next_entry(&entry_1.hash, 1, vec![ix_error_tx]);
|
||||
// Failed transaction
|
||||
let fail_tx = solana_sdk::system_transaction::transfer(
|
||||
mint_keypair,
|
||||
&keypair2.pubkey(),
|
||||
rent_exempt_amount,
|
||||
Hash::default(),
|
||||
);
|
||||
let entry_3 = solana_entry::entry::next_entry(&entry_2.hash, 1, vec![fail_tx]);
|
||||
let entries = vec![entry_1, entry_2, entry_3];
|
||||
let entries = vec![entry_1, entry_2];
|
||||
|
||||
let shreds =
|
||||
solana_ledger::blockstore::entries_to_test_shreds(&entries, slot, previous_slot, true, 0);
|
||||
@ -4357,17 +4335,20 @@ pub fn create_test_transactions_and_populate_blockstore(
|
||||
|
||||
// Check that process_entries successfully writes can_commit transactions statuses, and
|
||||
// that they are matched properly by get_rooted_block
|
||||
let _result = solana_ledger::blockstore_processor::process_entries_for_tests(
|
||||
&bank,
|
||||
entries,
|
||||
true,
|
||||
Some(
|
||||
&solana_ledger::blockstore_processor::TransactionStatusSender {
|
||||
sender: transaction_status_sender,
|
||||
enable_cpi_and_log_storage: false,
|
||||
},
|
||||
assert_eq!(
|
||||
solana_ledger::blockstore_processor::process_entries_for_tests(
|
||||
&bank,
|
||||
entries,
|
||||
true,
|
||||
Some(
|
||||
&solana_ledger::blockstore_processor::TransactionStatusSender {
|
||||
sender: transaction_status_sender,
|
||||
enable_cpi_and_log_storage: false,
|
||||
},
|
||||
),
|
||||
Some(&replay_vote_sender),
|
||||
),
|
||||
Some(&replay_vote_sender),
|
||||
Ok(())
|
||||
);
|
||||
|
||||
transaction_status_service.join().unwrap();
|
||||
@ -6613,7 +6594,7 @@ pub mod tests {
|
||||
let confirmed_block: Option<EncodedConfirmedBlock> =
|
||||
serde_json::from_value(result["result"].clone()).unwrap();
|
||||
let confirmed_block = confirmed_block.unwrap();
|
||||
assert_eq!(confirmed_block.transactions.len(), 3);
|
||||
assert_eq!(confirmed_block.transactions.len(), 2);
|
||||
assert_eq!(confirmed_block.rewards, vec![]);
|
||||
|
||||
for EncodedTransactionWithStatusMeta { transaction, meta } in
|
||||
@ -6658,7 +6639,7 @@ pub mod tests {
|
||||
let confirmed_block: Option<EncodedConfirmedBlock> =
|
||||
serde_json::from_value(result["result"].clone()).unwrap();
|
||||
let confirmed_block = confirmed_block.unwrap();
|
||||
assert_eq!(confirmed_block.transactions.len(), 3);
|
||||
assert_eq!(confirmed_block.transactions.len(), 2);
|
||||
assert_eq!(confirmed_block.rewards, vec![]);
|
||||
|
||||
for EncodedTransactionWithStatusMeta { transaction, meta } in
|
||||
|
Reference in New Issue
Block a user