Skip to content

Commit

Permalink
Merge pull request #49 from helius-labs/fix/smrt-txt-transaction-time…
Browse files Browse the repository at this point in the history
…s-out-but-is-confirmed

fix(optimized_transaction): Better Transaction Confirmation
  • Loading branch information
0xIchigo authored Jun 20, 2024
2 parents 5a18ded + 9f1fb25 commit 705d66f
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 13 deletions.
12 changes: 6 additions & 6 deletions src/jito.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@ impl Helius {
/// * `tip_amount` - The amount of lamports to tip. Defaults to `1000`
///
/// # Returns
/// A `Result` containing the serialized transaction as a base58-encoded string
/// A `Result` containing the serialized transaction as a base58-encoded string and the last valid block height
pub async fn create_smart_transaction_with_tip(
&self,
mut config: CreateSmartTransactionConfig<'_>,
tip_amount: Option<u64>,
) -> Result<String> {
) -> Result<(String, u64)> {
if config.signers.is_empty() {
return Err(HeliusError::InvalidInput(
"The transaction must have at least one signer".to_string(),
Expand All @@ -109,7 +109,7 @@ impl Helius {

self.add_tip_instruction(&mut config.instructions, payer_key, random_tip_account, tip_amount);

let smart_transaction: SmartTransaction = self.create_smart_transaction(&config).await?;
let (smart_transaction, last_valid_block_height) = self.create_smart_transaction(&config).await?;
let serialized_transaction: Vec<u8> = match smart_transaction {
SmartTransaction::Legacy(tx) => {
serialize(&tx).map_err(|e: Box<ErrorKind>| HeliusError::InvalidInput(e.to_string()))?
Expand All @@ -120,7 +120,7 @@ impl Helius {
};
let transaction_base58: String = encode(&serialized_transaction).into_string();

Ok(transaction_base58)
Ok((transaction_base58, last_valid_block_height))
}

/// Sends a bundle of transactions to the Jito Block Engine
Expand Down Expand Up @@ -231,7 +231,7 @@ impl Helius {
let jito_api_url: &str = jito_api_url_string.as_str();

// Create the smart transaction with tip
let serialized_transaction: String = self
let (serialized_transaction, last_valid_block_height) = self
.create_smart_transaction_with_tip(config.create_config, Some(tip))
.await?;

Expand All @@ -245,7 +245,7 @@ impl Helius {
let interval: Duration = Duration::from_secs(5);
let start: tokio::time::Instant = tokio::time::Instant::now();

while start.elapsed() < timeout {
while start.elapsed() < timeout || self.connection().get_block_height()? <= last_valid_block_height {
let bundle_statuses: Value = self.get_bundle_statuses(vec![bundle_id.clone()], jito_api_url).await?;

if let Some(values) = bundle_statuses["result"]["value"].as_array() {
Expand Down
24 changes: 17 additions & 7 deletions src/optimized_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,11 @@ impl Helius {
/// whether it's a legacy or versioned smart transaction. The transaction's send configuration can also be changed, if provided
///
/// # Returns
/// An optimized `Transaction` or `VersionedTransaction`
/// An optimized `SmartTransaction` (i.e., `Transaction` or `VersionedTransaction`) and the `last_valid_block_height`
pub async fn create_smart_transaction(
&self,
config: &CreateSmartTransactionConfig<'_>,
) -> Result<SmartTransaction> {
) -> Result<(SmartTransaction, u64)> {
if config.signers.is_empty() {
return Err(HeliusError::InvalidInput(
"The fee payer must sign the transaction".to_string(),
Expand All @@ -131,7 +131,9 @@ impl Helius {
let payer_pubkey: Pubkey = config
.fee_payer
.map_or(config.signers[0].pubkey(), |signer| signer.pubkey());
let recent_blockhash: Hash = self.connection().get_latest_blockhash()?;
let (recent_blockhash, last_valid_block_hash) = self
.connection()
.get_latest_blockhash_with_commitment(CommitmentConfig::confirmed())?;
let mut final_instructions: Vec<Instruction> = vec![];

// Check if any of the instructions provided set the compute unit price and/or limit, and throw an error if `true`
Expand Down Expand Up @@ -288,7 +290,10 @@ impl Helius {
message: versioned_message,
});

Ok(SmartTransaction::Versioned(versioned_transaction.unwrap()))
Ok((
SmartTransaction::Versioned(versioned_transaction.unwrap()),
last_valid_block_hash,
))
} else {
let mut tx: Transaction = Transaction::new_with_payer(&final_instructions, Some(&payer_pubkey));
tx.try_partial_sign(&config.signers, recent_blockhash)?;
Expand All @@ -299,7 +304,10 @@ impl Helius {

legacy_transaction = Some(tx);

Ok(SmartTransaction::Legacy(legacy_transaction.unwrap()))
Ok((
SmartTransaction::Legacy(legacy_transaction.unwrap()),
last_valid_block_hash,
))
}
}

Expand All @@ -312,7 +320,7 @@ impl Helius {
/// # Returns
/// The transaction signature, if successful
pub async fn send_smart_transaction(&self, config: SmartTransactionConfig<'_>) -> Result<Signature> {
let transaction: SmartTransaction = self.create_smart_transaction(&config.create_config).await?;
let (transaction, last_valid_block_height) = self.create_smart_transaction(&config.create_config).await?;

// Common logic for sending transactions
let send_transaction_config: RpcSendTransactionConfig = RpcSendTransactionConfig {
Expand All @@ -336,7 +344,9 @@ impl Helius {
let timeout: Duration = Duration::from_secs(60);
let start_time: Instant = Instant::now();

while Instant::now().duration_since(start_time) < timeout {
while Instant::now().duration_since(start_time) < timeout
|| self.connection().get_block_height()? <= last_valid_block_height
{
let result = match &transaction {
SmartTransaction::Legacy(tx) => send_result(tx),
SmartTransaction::Versioned(tx) => send_versioned_result(tx),
Expand Down

0 comments on commit 705d66f

Please sign in to comment.