From 41e45eb1710326efdccf098a1c2cbfb2554b913c Mon Sep 17 00:00:00 2001 From: Rahul Jain Date: Thu, 11 Jan 2024 16:49:45 -0500 Subject: [PATCH 1/3] add optional prio fees when sending transactions --- Cargo.toml | 2 +- src/lib/processor/process_claim_seat.rs | 11 +++++-- src/lib/processor/process_evict_seat.rs | 11 ++++--- src/lib/processor/process_get_transaction.rs | 8 +++++- src/lib/processor/process_request_seat.rs | 19 ++++++++++--- src/main.rs | 30 ++++++++++++++++++-- 6 files changed, 65 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 96d414c..5757ec7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ anyhow = "1.0.66" clap = { version = "4.0.26", features = ["derive"] } shellexpand = "2.1.2" solana-sdk = "1.10.32" -ellipsis-client = "0.2.0" +ellipsis-client = "0.2.1" solana-client = "1.10.32" solana-account-decoder = "1.14.7" solana-cli-config = "1.14.7" diff --git a/src/lib/processor/process_claim_seat.rs b/src/lib/processor/process_claim_seat.rs index 53b84dd..653235b 100644 --- a/src/lib/processor/process_claim_seat.rs +++ b/src/lib/processor/process_claim_seat.rs @@ -1,18 +1,23 @@ use ellipsis_client::EllipsisClient; use phoenix_sdk::utils::create_claim_seat_ix_if_needed; -use solana_sdk::{pubkey::Pubkey, signer::Signer}; +use solana_sdk::{instruction::Instruction, pubkey::Pubkey, signer::Signer}; pub async fn process_claim_seat( client: &EllipsisClient, market_pubkey: &Pubkey, + prio_fee_instructions: Vec, ) -> anyhow::Result<()> { let claim_seat_ix = create_claim_seat_ix_if_needed(client, market_pubkey, &client.payer.pubkey()).await?; println!("Claiming seat for pubkey: {}", client.payer.pubkey()); if !claim_seat_ix.is_empty() { - let tx = client.sign_send_instructions(claim_seat_ix, vec![]).await?; - println!("Claim seat transaction: {}", tx); + let ix_to_send = prio_fee_instructions + .into_iter() + .chain(claim_seat_ix) + .collect::>(); + let tx = client.sign_send_instructions(ix_to_send, vec![]).await?; + println!("Claim seat transaction sent, signature: {} \nCan check transaction status with: phoenix-cli get-transaction {}", tx, tx); } else { println!("Seat already created for pubkey: {}", client.payer.pubkey()); } diff --git a/src/lib/processor/process_evict_seat.rs b/src/lib/processor/process_evict_seat.rs index c384b4c..aa5ab93 100644 --- a/src/lib/processor/process_evict_seat.rs +++ b/src/lib/processor/process_evict_seat.rs @@ -6,12 +6,13 @@ use phoenix_sdk::utils::get_evictable_trader_ix; use phoenix_seat_manager::instruction_builders::{ create_evict_seat_instruction, EvictTraderAccountBackup, }; -use solana_sdk::pubkey::Pubkey; +use solana_sdk::{instruction::Instruction, pubkey::Pubkey}; pub async fn process_evict_seat( client: &EllipsisClient, market_pubkey: &Pubkey, trader_to_evict: &Option, + prio_fee_instructions: Vec, ) -> anyhow::Result<()> { let market_bytes = client.get_account_data(market_pubkey).await?; let (header_bytes, _market_bytes) = market_bytes.split_at(size_of::()); @@ -37,9 +38,11 @@ pub async fn process_evict_seat( if let Some(evict_trader_ix) = maybe_evict_trader_ix { println!("Evicting trader: {}", evict_trader_ix.accounts[13].pubkey); - let tx = client - .sign_send_instructions(vec![evict_trader_ix], vec![]) - .await?; + let ix_to_send = prio_fee_instructions + .into_iter() + .chain(vec![evict_trader_ix]) + .collect::>(); + let tx = client.sign_send_instructions(ix_to_send, vec![]).await?; println!("Evict trader tx: {}", tx); } else { println!("Cannot evict a trader when the market's trader state is not full."); diff --git a/src/lib/processor/process_get_transaction.rs b/src/lib/processor/process_get_transaction.rs index 98bed23..d415046 100644 --- a/src/lib/processor/process_get_transaction.rs +++ b/src/lib/processor/process_get_transaction.rs @@ -9,7 +9,13 @@ pub async fn process_get_transaction( let events = sdk .parse_events_from_transaction(signature) .await - .ok_or_else(|| anyhow::anyhow!("Failed to parse events from transaction"))?; + .ok_or_else(|| anyhow::anyhow!("Failed to find transaction"))?; + if events.is_empty() { + println!( + "Found Transaction: {} \nTransaction has no Trades, Places, or Cancels to log", + signature + ); + } log_market_events(sdk, events).await?; Ok(()) } diff --git a/src/lib/processor/process_request_seat.rs b/src/lib/processor/process_request_seat.rs index e6a1f41..8e71049 100644 --- a/src/lib/processor/process_request_seat.rs +++ b/src/lib/processor/process_request_seat.rs @@ -1,13 +1,24 @@ use phoenix::program::instruction_builders::create_request_seat_instruction; use phoenix_sdk::sdk_client::*; -use solana_sdk::pubkey::Pubkey; +use solana_sdk::{instruction::Instruction, pubkey::Pubkey}; -pub async fn process_request_seat(market_pubkey: &Pubkey, sdk: &SDKClient) -> anyhow::Result<()> { +pub async fn process_request_seat( + market_pubkey: &Pubkey, + sdk: &SDKClient, + prio_fee_instructions: Vec, +) -> anyhow::Result<()> { let ix = create_request_seat_instruction(&sdk.core.trader, market_pubkey); - let tx = sdk.client.sign_send_instructions(vec![ix], vec![]).await; + let ix_to_send = prio_fee_instructions + .into_iter() + .chain(vec![ix]) + .collect::>(); + let tx = sdk.client.sign_send_instructions(ix_to_send, vec![]).await; match tx { - Ok(tx) => println!("Requested seat, transaction signature: {}", tx), + Ok(tx) => println!( + "Requested seat transaction sent, signature: {} \nCan check transaction status with: phoenix-cli get-transaction {}", + tx, tx + ), Err(e) => println!("Error requesting seat: {}", e), } diff --git a/src/main.rs b/src/main.rs index 79984e9..ea630a3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,7 @@ use phoenix_cli_processor::processor::{ use phoenix_sdk::sdk_client::*; use solana_cli_config::{Config, ConfigInput, CONFIG_FILE}; use solana_client::nonblocking::rpc_client::RpcClient; +use solana_sdk::compute_budget::ComputeBudgetInstruction; use solana_sdk::signer::keypair::{read_keypair_file, Keypair}; use solana_sdk::signer::Signer; @@ -33,6 +34,12 @@ struct Args { /// Optionally include a commitment level. Defaults to your Solana CLI config file. #[clap(global = true, short, long)] commitment: Option, + /// Optionally include a priority fee, in how many micro lamports you want to pay per compute unit. Defaults to no priority fee + #[clap(global = true, short, long)] + prio_fee: Option, + /// Optionally include the number of compute units you want to pay for. Only works if a priority fee is also set. If prio fee is set, this defaults to 1.2 million + #[clap(global = true, short, long)] + num_compute_units: Option, } pub fn get_network(network_str: &str) -> &str { @@ -70,6 +77,17 @@ async fn main() -> anyhow::Result<()> { let mut sdk = SDKClient::new(&payer, network_url).await?; + let prio_fee_instructions = match cli.prio_fee { + Some(compute_unit_price) => { + let cu_limit = ComputeBudgetInstruction::set_compute_unit_limit( + cli.num_compute_units.unwrap_or(1_200_000), + ); + let cu_price = ComputeBudgetInstruction::set_compute_unit_price(compute_unit_price); + vec![cu_limit, cu_price] + } + None => vec![], + }; + match cli.command { PhoenixCLICommand::GetMarket { market_pubkey } => { sdk.add_market(&market_pubkey).await?; @@ -134,7 +152,7 @@ async fn main() -> anyhow::Result<()> { } PhoenixCLICommand::RequestSeat { market_pubkey } => { sdk.add_market(&market_pubkey).await?; - process_request_seat(&market_pubkey, &sdk).await? + process_request_seat(&market_pubkey, &sdk, prio_fee_instructions).await? } PhoenixCLICommand::MintTokens { mint_ticker, @@ -163,14 +181,20 @@ async fn main() -> anyhow::Result<()> { } PhoenixCLICommand::ClaimSeat { market_pubkey } => { sdk.add_market(&market_pubkey).await?; - process_claim_seat(&sdk.client, &market_pubkey).await? + process_claim_seat(&sdk.client, &market_pubkey, prio_fee_instructions).await? } PhoenixCLICommand::EvictSeat { market_pubkey, trader_to_evict, } => { sdk.add_market(&market_pubkey).await?; - process_evict_seat(&sdk.client, &market_pubkey, &trader_to_evict).await? + process_evict_seat( + &sdk.client, + &market_pubkey, + &trader_to_evict, + prio_fee_instructions, + ) + .await? } } From 83aa1acb56096319ddeb7ed98697996dd2df288a Mon Sep 17 00:00:00 2001 From: Rahul Jain Date: Fri, 12 Jan 2024 15:43:11 -0500 Subject: [PATCH 2/3] add prio fee cap --- src/main.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index ea630a3..35e4871 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,7 +34,7 @@ struct Args { /// Optionally include a commitment level. Defaults to your Solana CLI config file. #[clap(global = true, short, long)] commitment: Option, - /// Optionally include a priority fee, in how many micro lamports you want to pay per compute unit. Defaults to no priority fee + /// Optionally include a priority fee, in how many micro lamports you want to pay per compute unit. Defaults to no priority fee. Max is 1 million #[clap(global = true, short, long)] prio_fee: Option, /// Optionally include the number of compute units you want to pay for. Only works if a priority fee is also set. If prio fee is set, this defaults to 1.2 million @@ -79,9 +79,16 @@ async fn main() -> anyhow::Result<()> { let prio_fee_instructions = match cli.prio_fee { Some(compute_unit_price) => { - let cu_limit = ComputeBudgetInstruction::set_compute_unit_limit( - cli.num_compute_units.unwrap_or(1_200_000), + let num_compute_units = cli.num_compute_units.unwrap_or(1_200_000); + assert!( + num_compute_units <= 1_200_000, + "Number of compute units must be less than 1.2 million" ); + assert!( + compute_unit_price <= 1_000_000, + "Priority fee must be less than 1 million micro lamports" + ); + let cu_limit = ComputeBudgetInstruction::set_compute_unit_limit(num_compute_units); let cu_price = ComputeBudgetInstruction::set_compute_unit_price(compute_unit_price); vec![cu_limit, cu_price] } From de4be21dcc32c7cfd4020bf323e6377668ef37fe Mon Sep 17 00:00:00 2001 From: Rahul Jain Date: Tue, 16 Jan 2024 12:45:34 -0500 Subject: [PATCH 3/3] compute units to 1.4 mil --- src/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 35e4871..b77c2ae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,7 +37,7 @@ struct Args { /// Optionally include a priority fee, in how many micro lamports you want to pay per compute unit. Defaults to no priority fee. Max is 1 million #[clap(global = true, short, long)] prio_fee: Option, - /// Optionally include the number of compute units you want to pay for. Only works if a priority fee is also set. If prio fee is set, this defaults to 1.2 million + /// Optionally include the number of compute units you want to pay for. Only works if a priority fee is also set. If prio fee is set, this defaults to 1.4 million #[clap(global = true, short, long)] num_compute_units: Option, } @@ -81,8 +81,8 @@ async fn main() -> anyhow::Result<()> { Some(compute_unit_price) => { let num_compute_units = cli.num_compute_units.unwrap_or(1_200_000); assert!( - num_compute_units <= 1_200_000, - "Number of compute units must be less than 1.2 million" + num_compute_units <= 1_400_000, + "Number of compute units must be less than 1.4 million" ); assert!( compute_unit_price <= 1_000_000,