Skip to content

Commit

Permalink
rpc: add option skip_sanitize to send_transaction (#177)
Browse files Browse the repository at this point in the history
  • Loading branch information
fanatid committed Oct 7, 2024
1 parent 31ff539 commit 4999921
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 15 deletions.
2 changes: 2 additions & 0 deletions rpc-client-api/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ pub struct RpcSignatureStatusConfig {
pub struct RpcSendTransactionConfig {
#[serde(default)]
pub skip_preflight: bool,
#[serde(default)]
pub skip_sanitize: bool,
pub preflight_commitment: Option<CommitmentLevel>,
pub encoding: Option<UiTransactionEncoding>,
pub max_retries: Option<usize>,
Expand Down
49 changes: 34 additions & 15 deletions rpc/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3631,6 +3631,7 @@ pub mod rpc_full {
debug!("send_transaction rpc request received");
let RpcSendTransactionConfig {
skip_preflight,
skip_sanitize,
preflight_commitment,
encoding,
max_retries,
Expand All @@ -3655,27 +3656,45 @@ pub mod rpc_full {
min_context_slot,
})?;

let transaction = sanitize_transaction(unsanitized_tx, preflight_bank)?;
let signature = *transaction.signature();
let recent_blockhash = *unsanitized_tx.message.recent_blockhash();
let (signature, sanitized_tx) = if skip_preflight && skip_sanitize {
unsanitized_tx.sanitize().map_err(|_err| {
Error::invalid_params(format!(
"invalid transaction: {}",
TransactionError::SanitizeFailure
))
})?;
(unsanitized_tx.signatures[0], None)
} else {
let tx = sanitize_transaction(unsanitized_tx, preflight_bank)?;
(*tx.signature(), Some(tx))
};

let mut last_valid_block_height = preflight_bank
.get_blockhash_last_valid_block_height(transaction.message().recent_blockhash())
.get_blockhash_last_valid_block_height(&recent_blockhash)
.unwrap_or(0);

let durable_nonce_info = transaction
.get_durable_nonce()
.map(|&pubkey| (pubkey, *transaction.message().recent_blockhash()));
if durable_nonce_info.is_some() || (skip_preflight && last_valid_block_height == 0) {
// While it uses a defined constant, this last_valid_block_height value is chosen arbitrarily.
// It provides a fallback timeout for durable-nonce transaction retries in case of
// malicious packing of the retry queue. Durable-nonce transactions are otherwise
// retried until the nonce is advanced.
last_valid_block_height =
preflight_bank.block_height() + MAX_RECENT_BLOCKHASHES as u64;
let mut durable_nonce_info = None;
if let Some(sanitized_tx) = &sanitized_tx {
durable_nonce_info = sanitized_tx
.get_durable_nonce()
.map(|&pubkey| (pubkey, recent_blockhash));
if durable_nonce_info.is_some() || (skip_preflight && last_valid_block_height == 0)
{
// While it uses a defined constant, this last_valid_block_height value is chosen arbitrarily.
// It provides a fallback timeout for durable-nonce transaction retries in case of
// malicious packing of the retry queue. Durable-nonce transactions are otherwise
// retried until the nonce is advanced.
last_valid_block_height =
preflight_bank.block_height() + MAX_RECENT_BLOCKHASHES as u64;
}
}

if !skip_preflight {
verify_transaction(&transaction, &preflight_bank.feature_set)?;
let Some(sanitized_tx) = sanitized_tx else {
return Err(Error::invalid_params("sanitized transaction should exists"));
};
verify_transaction(&sanitized_tx, &preflight_bank.feature_set)?;

match meta.health.check() {
RpcHealthStatus::Ok => (),
Expand All @@ -3702,7 +3721,7 @@ pub mod rpc_full {
units_consumed,
return_data,
inner_instructions: _, // Always `None` due to `enable_cpi_recording = false`
} = preflight_bank.simulate_transaction(&transaction, false)
} = preflight_bank.simulate_transaction(&sanitized_tx, false)
{
match err {
TransactionError::BlockhashNotFound => {
Expand Down

0 comments on commit 4999921

Please sign in to comment.