Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jstarry committed Jan 16, 2022
1 parent 3bd5a89 commit 7bea926
Show file tree
Hide file tree
Showing 9 changed files with 300 additions and 45 deletions.
1 change: 1 addition & 0 deletions cli/src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,7 @@ pub fn process_confirm(
RpcTransactionConfig {
encoding: Some(UiTransactionEncoding::Base64),
commitment: Some(CommitmentConfig::confirmed()),
enable_versioned_transactions: Some(true),
},
) {
Ok(confirmed_transaction) => {
Expand Down
3 changes: 2 additions & 1 deletion client/src/mock_sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ impl RpcSender for MockSender {
transaction: EncodedTransaction::Json(
UiTransaction {
signatures: vec!["3AsdoALgZFuq2oUVWrDYhg2pNeaLJKPLf8hU2mQ6U8qJxeJ6hsrPVpMn9ma39DtfYCrDQSvngWRP8NnTpEhezJpE".to_string()],
message: UiMessage::Raw(
message: UiMessage::RawLegacy(
UiRawMessage {
header: MessageHeader {
num_required_signatures: 1,
Expand Down Expand Up @@ -222,6 +222,7 @@ impl RpcSender for MockSender {
pre_token_balances: None,
post_token_balances: None,
rewards: None,
loaded_addresses: vec![],
}),
},
block_time: Some(1628633791),
Expand Down
3 changes: 3 additions & 0 deletions client/src/rpc_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ pub struct RpcBlockSubscribeConfig {
pub encoding: Option<UiTransactionEncoding>,
pub transaction_details: Option<TransactionDetails>,
pub show_rewards: Option<bool>,
pub enable_versioned_transactions: Option<bool>,
}

#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
Expand Down Expand Up @@ -248,6 +249,7 @@ pub struct RpcBlockConfig {
pub rewards: Option<bool>,
#[serde(flatten)]
pub commitment: Option<CommitmentConfig>,
pub enable_versioned_transactions: Option<bool>,
}

impl EncodingConfig for RpcBlockConfig {
Expand Down Expand Up @@ -288,6 +290,7 @@ pub struct RpcTransactionConfig {
pub encoding: Option<UiTransactionEncoding>,
#[serde(flatten)]
pub commitment: Option<CommitmentConfig>,
pub enable_versioned_transactions: Option<bool>,
}

impl EncodingConfig for RpcTransactionConfig {
Expand Down
2 changes: 2 additions & 0 deletions client/src/rpc_deprecated_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ impl From<RpcConfirmedBlockConfig> for RpcBlockConfig {
transaction_details: config.transaction_details,
rewards: config.rewards,
commitment: config.commitment,
enable_versioned_transactions: Some(false),
}
}
}
Expand Down Expand Up @@ -98,6 +99,7 @@ impl From<RpcConfirmedTransactionConfig> for RpcTransactionConfig {
Self {
encoding: config.encoding,
commitment: config.commitment,
enable_versioned_transactions: Some(false),
}
}
}
Expand Down
95 changes: 74 additions & 21 deletions rpc/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ use {
feature_set::{self, nonce_must_be_writable},
fee_calculator::FeeCalculator,
hash::Hash,
message::{Message, SanitizedMessage},
message::{
v0::{LoadedAddresses, MessageAddressTableLookup},
Message, SanitizedMessage,
},
pubkey::{Pubkey, PUBKEY_BYTES},
signature::{Keypair, Signature, Signer},
stake::state::{StakeActivationStatus, StakeState},
Expand Down Expand Up @@ -990,6 +993,8 @@ impl JsonRpcRequestProcessor {
let transaction_details = config.transaction_details.unwrap_or_default();
let show_rewards = config.rewards.unwrap_or(true);
let commitment = config.commitment.unwrap_or_default();
let reject_versioned_transactions =
!config.enable_versioned_transactions.unwrap_or_default();
check_is_at_least_confirmed(commitment)?;

// Block is old enough to be finalized
Expand All @@ -1003,10 +1008,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
.into_legacy_block()
.ok_or(RpcCustomError::UnsupportedTransactionVersion)?;
let configure_block = |confirmed_block: VersionedConfirmedBlock| {
if reject_versioned_transactions && confirmed_block.has_versioned_transactions()
{
return Err(RpcCustomError::UnsupportedTransactionVersion);
}

let mut confirmed_block =
confirmed_block.configure(encoding, transaction_details, show_rewards);
if slot == 0 {
Expand All @@ -1033,10 +1040,13 @@ impl JsonRpcRequestProcessor {
let result = self.blockstore.get_complete_block(slot, true);
return result
.ok()
.map(|versioned_block| {
let mut confirmed_block = versioned_block
.into_legacy_block()
.ok_or(RpcCustomError::UnsupportedTransactionVersion)?;
.map(|mut confirmed_block| {
if reject_versioned_transactions
&& confirmed_block.has_versioned_transactions()
{
return Err(RpcCustomError::UnsupportedTransactionVersion);
}

if confirmed_block.block_time.is_none()
|| confirmed_block.block_height.is_none()
{
Expand Down Expand Up @@ -1379,6 +1389,8 @@ impl JsonRpcRequestProcessor {
.unwrap_or_default();
let encoding = config.encoding.unwrap_or(UiTransactionEncoding::Json);
let commitment = config.commitment.unwrap_or_default();
let reject_versioned_transactions =
!config.enable_versioned_transactions.unwrap_or_default();
check_is_at_least_confirmed(commitment)?;

if self.config.enable_rpc_transaction_history {
Expand All @@ -1392,10 +1404,12 @@ impl JsonRpcRequestProcessor {
};

match versioned_confirmed_tx.unwrap_or(None) {
Some(versioned_confirmed_tx) => {
let mut confirmed_transaction = versioned_confirmed_tx
.into_legacy_confirmed_transaction()
.ok_or(RpcCustomError::UnsupportedTransactionVersion)?;
Some(confirmed_transaction) => {
if reject_versioned_transactions
&& confirmed_transaction.has_versioned_transactions()
{
return Err(RpcCustomError::UnsupportedTransactionVersion);
}

if commitment.is_confirmed()
&& confirmed_bank // should be redundant
Expand Down Expand Up @@ -1426,10 +1440,12 @@ 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)?;
.map(|confirmed_tx| {
if reject_versioned_transactions
&& confirmed_tx.has_versioned_transactions()
{
return Err(RpcCustomError::UnsupportedTransactionVersion);
}

Ok(confirmed_tx.encode(encoding))
})
Expand Down Expand Up @@ -3475,6 +3491,7 @@ pub mod rpc_full {
.preflight_commitment
.map(|commitment| CommitmentConfig { commitment });
let preflight_bank = &*meta.bank(preflight_commitment);
let finalized_bank = &*meta.bank(Some(CommitmentConfig::finalized()));
let transaction = sanitize_transaction(unsanitized_tx)?;
let signature = *transaction.signature();

Expand Down Expand Up @@ -3583,6 +3600,7 @@ pub mod rpc_full {
.set_recent_blockhash(bank.last_blockhash());
}

let finalized_bank = &*meta.bank(Some(CommitmentConfig::finalized()));
let transaction = sanitize_transaction(unsanitized_tx)?;
if config.sig_verify {
verify_transaction(&transaction, &bank.feature_set)?;
Expand Down Expand Up @@ -4400,12 +4418,12 @@ pub mod tests {
fee_calculator::DEFAULT_BURN_PERCENT,
hash::{hash, Hash},
instruction::InstructionError,
message::Message,
message::{v0, Message, MessageHeader, VersionedMessage},
nonce, rpc_port,
signature::{Keypair, Signer},
system_program, system_transaction,
timing::slot_duration_from_slots_per_year,
transaction::{self, Transaction, TransactionError},
transaction::{self, AddressLookupError, Transaction, TransactionError},
},
solana_transaction_status::{
EncodedConfirmedBlock, EncodedTransaction, EncodedTransactionWithStatusMeta,
Expand Down Expand Up @@ -6613,7 +6631,8 @@ pub mod tests {
let meta = meta.unwrap();
let transaction_recent_blockhash = match transaction.message {
UiMessage::Parsed(message) => message.recent_blockhash,
UiMessage::Raw(message) => message.recent_blockhash,
UiMessage::RawLegacy(message) => message.recent_blockhash,
UiMessage::RawVersioned(message) => message.recent_blockhash,
};
assert_eq!(transaction_recent_blockhash, blockhash.to_string());
assert_eq!(meta.status, Ok(()));
Expand Down Expand Up @@ -6712,6 +6731,7 @@ pub mod tests {
transaction_details: Some(TransactionDetails::Signatures),
rewards: Some(false),
commitment: None,
enable_versioned_transactions: None,
})
);
let res = io.handle_request_sync(&req, meta.clone());
Expand All @@ -6733,6 +6753,7 @@ pub mod tests {
transaction_details: Some(TransactionDetails::None),
rewards: Some(true),
commitment: None,
enable_versioned_transactions: None,
})
);
let res = io.handle_request_sync(&req, meta);
Expand Down Expand Up @@ -8090,8 +8111,40 @@ pub mod tests {
.to_string(),
);
assert_eq!(
sanitize_transaction(unsanitary_versioned_tx).unwrap_err(),
sanitize_transaction(unsanitary_versioned_tx, |_| Ok(LoadedAddresses::default()))
.unwrap_err(),
expect58
);
}

#[test]
fn test_sanitize_invalid_lookups() {
let versioned_tx = VersionedTransaction {
signatures: vec![Signature::default()],
message: VersionedMessage::V0(v0::Message {
header: MessageHeader {
num_required_signatures: 1,
..MessageHeader::default()
},
account_keys: vec![Pubkey::new_unique()],
address_table_lookups: vec![MessageAddressTableLookup {
account_key: Pubkey::new_unique(),
writable_indexes: vec![255],
readonly_indexes: vec![],
}],
..v0::Message::default()
}),
};

let sanitize_err = sanitize_transaction(versioned_tx, |_| {
Err(AddressLookupError::InvalidLookupIndex.into())
})
.unwrap_err();
assert_eq!(
sanitize_err,
Error::invalid_params(
"invalid transaction: Transaction address table lookup failed".to_string(),
)
);
}
}
3 changes: 3 additions & 0 deletions rpc/src/rpc_pubsub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,9 @@ impl RpcSolPubSubInternal for RpcSolPubSubImpl {
},
transaction_details: config.transaction_details.unwrap_or_default(),
show_rewards: config.show_rewards.unwrap_or_default(),
reject_versioned_transactions: !config
.enable_versioned_transactions
.unwrap_or_default(),
};
self.subscribe(SubscriptionParams::Block(params))
}
Expand Down
1 change: 1 addition & 0 deletions rpc/src/rpc_subscription_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ pub struct BlockSubscriptionParams {
pub kind: BlockSubscriptionKind,
pub transaction_details: TransactionDetails,
pub show_rewards: bool,
pub reject_versioned_transactions: bool,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
Expand Down
33 changes: 23 additions & 10 deletions rpc/src/rpc_subscriptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,19 +281,26 @@ fn filter_block_result_txs(
block: ConfirmedBlock,
last_modified_slot: Slot,
params: &BlockSubscriptionParams,
) -> Option<RpcBlockUpdate> {
) -> Result<Option<RpcBlockUpdate>, RpcBlockUpdateError> {
let transactions = match params.kind {
BlockSubscriptionKind::All => block.transactions,
BlockSubscriptionKind::MentionsAccountOrProgram(pk) => block
.transactions
.into_iter()
.filter(|tx| tx.transaction.message.account_keys.contains(&pk))
.filter(|tx| {
tx.transaction.message.static_account_keys().contains(&pk)
|| tx
.meta
.as_ref()
.map(|meta| meta.loaded_addresses.contains(&pk))
.unwrap_or_default()
})
.collect(),
};

if transactions.is_empty() {
if let BlockSubscriptionKind::MentionsAccountOrProgram(_) = params.kind {
return None;
return Ok(None);
}
}

Expand All @@ -305,16 +312,17 @@ fn filter_block_result_txs(
params.encoding,
params.transaction_details,
params.show_rewards,
);
params.reject_versioned_transactions,
)?;

// If last_modified_slot < last_notified_slot, then the last notif was for a fork.
// That's the risk clients take when subscribing to non-finalized commitments.
// This code lets the logic for dealing with forks live on the client side.
Some(RpcBlockUpdate {
Ok(Some(RpcBlockUpdate {
slot: last_modified_slot,
block: Some(block),
err: None,
})
}))
}

fn filter_account_result(
Expand Down Expand Up @@ -964,10 +972,15 @@ impl RpcSubscriptions {
error!("get_complete_block error: {}", e);
RpcBlockUpdateError::BlockStoreError
})
.and_then(|versioned_block| {
versioned_block.into_legacy_block().ok_or(
RpcBlockUpdateError::UnsupportedTransactionVersion,
)
.and_then(|confirmed_block| {
if reject_versioned_transactions
&& confirmed_block.has_versioned_transactions()
{
return Err(
RpcBlockUpdateError::UnsupportedTransactionVersion,
);
}
Ok(confirmed_block)
});

match block_result {
Expand Down
Loading

0 comments on commit 7bea926

Please sign in to comment.