Skip to content

Commit

Permalink
Merge pull request #89 from grandima/wip-lifetime-to-arc
Browse files Browse the repository at this point in the history
feat: Replace lifetimes with Arc for CreateSmartTransactionConfig
  • Loading branch information
0xIchigo authored Nov 26, 2024
2 parents ce06a59 + ead3c5d commit bd9e0b1
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 33 deletions.
3 changes: 2 additions & 1 deletion examples/send_smart_transaction_with_tip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use solana_sdk::{
system_instruction::transfer,
};
use std::str::FromStr;
use std::sync::Arc;
use std::time::Duration;
use tokio::time::sleep;

Expand All @@ -28,7 +29,7 @@ async fn main() {

let create_config: CreateSmartTransactionConfig = CreateSmartTransactionConfig {
instructions,
signers: vec![&from_keypair],
signers: vec![Arc::new(from_keypair)],
lookup_tables: None,
fee_payer: None,
};
Expand Down
5 changes: 3 additions & 2 deletions src/jito.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ impl Helius {
/// 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<'_>,
mut config: CreateSmartTransactionConfig,
tip_amount: Option<u64>,
) -> Result<(String, u64)> {
if config.signers.is_empty() {
Expand All @@ -105,6 +105,7 @@ impl Helius {
let random_tip_account: &str = *JITO_TIP_ACCOUNTS.choose(&mut rand::thread_rng()).unwrap();
let payer_key: Pubkey = config
.fee_payer
.as_ref()
.map_or_else(|| config.signers[0].pubkey(), |signer| signer.pubkey());

self.add_tip_instruction(&mut config.instructions, payer_key, random_tip_account, tip_amount);
Expand Down Expand Up @@ -212,7 +213,7 @@ impl Helius {
/// A `Result` containing the bundle IDc
pub async fn send_smart_transaction_with_tip(
&self,
config: SmartTransactionConfig<'_>,
config: SmartTransactionConfig,
tip_amount: Option<u64>,
region: Option<JitoRegion>,
) -> Result<String> {
Expand Down
44 changes: 23 additions & 21 deletions src/optimized_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::types::{
GetPriorityFeeEstimateRequest, GetPriorityFeeEstimateResponse, SmartTransaction, SmartTransactionConfig, Timeout,
};
use crate::Helius;
use std::sync::Arc;

use bincode::{serialize, ErrorKind};
use reqwest::StatusCode;
Expand Down Expand Up @@ -45,7 +46,7 @@ impl Helius {
instructions: Vec<Instruction>,
payer: Pubkey,
lookup_tables: Vec<AddressLookupTableAccount>,
signers: Option<&[&dyn Signer]>,
signers: Option<&[Arc<dyn Signer>]>,
) -> Result<Option<u64>> {
// Set the compute budget limit
let test_instructions: Vec<Instruction> = vec![ComputeBudgetInstruction::set_compute_unit_limit(1_400_000)]
Expand Down Expand Up @@ -137,7 +138,7 @@ impl Helius {
/// An optimized `SmartTransaction` (i.e., `Transaction` or `VersionedTransaction`) and the `last_valid_block_height`
pub async fn create_smart_transaction(
&self,
config: &CreateSmartTransactionConfig<'_>,
config: &CreateSmartTransactionConfig,
) -> Result<(SmartTransaction, u64)> {
if config.signers.is_empty() {
return Err(HeliusError::InvalidInput(
Expand All @@ -147,6 +148,7 @@ impl Helius {

let payer_pubkey: Pubkey = config
.fee_payer
.as_ref()
.map_or(config.signers[0].pubkey(), |signer| signer.pubkey());
let (recent_blockhash, last_valid_block_hash) = self
.connection()
Expand Down Expand Up @@ -177,10 +179,10 @@ impl Helius {
v0::Message::try_compile(&payer_pubkey, &config.instructions, lookup_tables, recent_blockhash)?;
let versioned_message: VersionedMessage = VersionedMessage::V0(v0_message);

let all_signers: Vec<&dyn Signer> = if let Some(fee_payer) = config.fee_payer {
let mut all_signers: Vec<&dyn Signer> = config.signers.clone();
let all_signers: Vec<Arc<dyn Signer>> = if let Some(fee_payer) = &config.fee_payer {
let mut all_signers = config.signers.clone();
if !all_signers.iter().any(|signer| signer.pubkey() == fee_payer.pubkey()) {
all_signers.push(fee_payer);
all_signers.push(fee_payer.clone());
}

all_signers
Expand All @@ -203,7 +205,7 @@ impl Helius {
let mut tx: Transaction = Transaction::new_with_payer(&config.instructions, Some(&payer_pubkey));
tx.try_partial_sign(&config.signers, recent_blockhash)?;

if let Some(fee_payer) = config.fee_payer {
if let Some(fee_payer) = config.fee_payer.as_ref() {
tx.try_partial_sign(&[fee_payer], recent_blockhash)?;
}

Expand Down Expand Up @@ -287,10 +289,10 @@ impl Helius {
v0::Message::try_compile(&payer_pubkey, &final_instructions, lookup_tables, recent_blockhash)?;
let versioned_message: VersionedMessage = VersionedMessage::V0(v0_message);

let all_signers: Vec<&dyn Signer> = if let Some(fee_payer) = config.fee_payer {
let all_signers: Vec<Arc<dyn Signer>> = if let Some(fee_payer) = config.fee_payer.as_ref() {
let mut all_signers = config.signers.clone();
if !all_signers.iter().any(|signer| signer.pubkey() == fee_payer.pubkey()) {
all_signers.push(fee_payer);
all_signers.push(fee_payer.clone());
}
all_signers
} else {
Expand All @@ -315,7 +317,7 @@ impl Helius {
let mut tx: Transaction = Transaction::new_with_payer(&final_instructions, Some(&payer_pubkey));
tx.try_partial_sign(&config.signers, recent_blockhash)?;

if let Some(fee_payer) = config.fee_payer {
if let Some(fee_payer) = config.fee_payer.as_ref() {
tx.try_partial_sign(&[fee_payer], recent_blockhash)?;
}

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

match transaction {
Expand Down Expand Up @@ -449,32 +451,32 @@ impl Helius {
));
}

let mut signers: Vec<Keypair> = create_config
let mut signers: Vec<Arc<dyn Signer>> = create_config
.signer_seeds
.into_iter()
.map(|seed| keypair_from_seed(&seed).expect("Failed to create keypair from seed"))
.map(|seed| {
Arc::new(keypair_from_seed(&seed).expect("Failed to create keypair from seed")) as Arc<dyn Signer>
})
.collect();

// Determine the fee payer
let fee_payer_index: usize = if let Some(fee_payer_seed) = create_config.fee_payer_seed {
let fee_payer: Keypair =
keypair_from_seed(&fee_payer_seed).expect("Failed to create fee payer keypair from seed");
let fee_payer =
Arc::new(keypair_from_seed(&fee_payer_seed).expect("Failed to create fee payer keypair from seed"));
signers.push(fee_payer);
signers.len() - 1 // Index of the last signer (fee payer)
} else {
0 // Index of the first signer
};

let signer_refs: Vec<&dyn Signer> = signers.iter().map(|keypair| keypair as &dyn Signer).collect();

let create_smart_transaction_config: CreateSmartTransactionConfig<'_> = CreateSmartTransactionConfig {
let fee_payer = signers[fee_payer_index].clone();
let create_smart_transaction_config: CreateSmartTransactionConfig = CreateSmartTransactionConfig {
instructions: create_config.instructions,
signers: signer_refs,
signers,
lookup_tables: create_config.lookup_tables,
fee_payer: Some(&signers[fee_payer_index] as &dyn Signer),
fee_payer: Some(fee_payer),
};

let smart_transaction_config: SmartTransactionConfig<'_> = SmartTransactionConfig {
let smart_transaction_config: SmartTransactionConfig = SmartTransactionConfig {
create_config: create_smart_transaction_config,
send_options: send_options.unwrap_or_default(),
timeout: timeout.unwrap_or_default(),
Expand Down
19 changes: 10 additions & 9 deletions src/types/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use super::{
use crate::types::{DisplayOptions, GetAssetOptions};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::sync::Arc;
use std::time::Duration;

use solana_client::rpc_config::RpcSendTransactionConfig;
Expand Down Expand Up @@ -950,15 +951,15 @@ pub struct EditWebhookRequest {
pub encoding: AccountWebhookEncoding,
}

pub struct CreateSmartTransactionConfig<'a> {
pub struct CreateSmartTransactionConfig {
pub instructions: Vec<Instruction>,
pub signers: Vec<&'a dyn Signer>,
pub signers: Vec<Arc<dyn Signer>>,
pub lookup_tables: Option<Vec<AddressLookupTableAccount>>,
pub fee_payer: Option<&'a dyn Signer>,
pub fee_payer: Option<Arc<dyn Signer>>,
}

impl<'a> CreateSmartTransactionConfig<'a> {
pub fn new(instructions: Vec<Instruction>, signers: Vec<&'a dyn Signer>) -> Self {
impl CreateSmartTransactionConfig {
pub fn new(instructions: Vec<Instruction>, signers: Vec<Arc<dyn Signer>>) -> Self {
Self {
instructions,
signers,
Expand All @@ -985,14 +986,14 @@ impl Into<Duration> for Timeout {
}
}

pub struct SmartTransactionConfig<'a> {
pub create_config: CreateSmartTransactionConfig<'a>,
pub struct SmartTransactionConfig {
pub create_config: CreateSmartTransactionConfig,
pub send_options: RpcSendTransactionConfig,
pub timeout: Timeout,
}

impl<'a> SmartTransactionConfig<'a> {
pub fn new(instructions: Vec<Instruction>, signers: Vec<&'a dyn Signer>, timeout: Timeout) -> Self {
impl SmartTransactionConfig {
pub fn new(instructions: Vec<Instruction>, signers: Vec<Arc<dyn Signer>>, timeout: Timeout) -> Self {
Self {
create_config: CreateSmartTransactionConfig::new(instructions, signers),
send_options: RpcSendTransactionConfig::default(),
Expand Down

0 comments on commit bd9e0b1

Please sign in to comment.