From 63e49773656ee293d00c0f3dd190e8c93fb77147 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Thu, 26 Jun 2025 23:20:00 -0500 Subject: [PATCH 1/4] Fix bug with compute instruction calculation --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- solana-transaction-utils/Cargo.toml | 2 +- solana-transaction-utils/src/priority_fee.rs | 18 +++++++++--------- solana-transaction-utils/src/queue.rs | 8 ++++---- tuktuk-cli/Cargo.toml | 2 +- tuktuk-cli/src/cmd/task.rs | 9 ++++----- tuktuk-crank-turner/Cargo.toml | 2 +- 8 files changed, 24 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5792898..0bd7e9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5862,7 +5862,7 @@ dependencies = [ [[package]] name = "solana-transaction-utils" -version = "0.4.0" +version = "0.4.1" dependencies = [ "bincode", "dashmap", @@ -6820,7 +6820,7 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tuktuk-cli" -version = "0.2.11" +version = "0.2.12" dependencies = [ "anchor-client", "anchor-lang", @@ -6849,7 +6849,7 @@ dependencies = [ [[package]] name = "tuktuk-crank-turner" -version = "0.2.22" +version = "0.2.23" dependencies = [ "anchor-client", "anchor-lang", diff --git a/Cargo.toml b/Cargo.toml index 09dc673..5486166 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,7 +57,7 @@ spl-associated-token-account = "6.0.0" spl-token = "4.0.0" itertools = "0.13" tokio-graceful-shutdown = "0.15" -solana-transaction-utils = { version = "0.4.0", path = "./solana-transaction-utils" } +solana-transaction-utils = { version = "0.4.1", path = "./solana-transaction-utils" } tuktuk-sdk = { version = "0.3.5", path = "./tuktuk-sdk" } tuktuk-program = { version = "0.3.2", path = "./tuktuk-program" } solana-account-decoder = { version = "2.2.3" } diff --git a/solana-transaction-utils/Cargo.toml b/solana-transaction-utils/Cargo.toml index 0d59a9d..6d38b37 100644 --- a/solana-transaction-utils/Cargo.toml +++ b/solana-transaction-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "solana-transaction-utils" -version = "0.4.0" +version = "0.4.1" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/solana-transaction-utils/src/priority_fee.rs b/solana-transaction-utils/src/priority_fee.rs index 685f6e7..749d989 100644 --- a/solana-transaction-utils/src/priority_fee.rs +++ b/solana-transaction-utils/src/priority_fee.rs @@ -175,11 +175,11 @@ pub async fn auto_compute_price>( compute_price_instruction_for_accounts(client, &accounts).await?; // Replace or insert compute price instruction - if let Some(pos) = instructions - .iter() - .position(|ix| ix.program_id == solana_sdk::compute_budget::id()) - { - updated_instructions[pos + 1] = compute_price_ix; // Replace existing + if let Some(pos) = instructions.iter().position(|ix| { + ix.program_id == solana_sdk::compute_budget::id() + && ix.data.first() == compute_price_ix.data.first() + }) { + updated_instructions[pos] = compute_price_ix; // Replace existing } else { updated_instructions.insert(1, compute_price_ix); // Insert after compute budget } @@ -239,10 +239,10 @@ pub async fn auto_compute_limit_and_price>( .await?; // Replace or insert compute budget instruction - if let Some(pos) = updated_instructions - .iter() - .position(|ix| ix.program_id == solana_sdk::compute_budget::id()) - { + if let Some(pos) = updated_instructions.iter().position(|ix| { + ix.program_id == solana_sdk::compute_budget::id() + && ix.data.first() == compute_budget_ix.data.first() + }) { updated_instructions[pos] = compute_budget_ix; // Replace existing } else { updated_instructions.insert(0, compute_budget_ix); // Insert at the beginning diff --git a/solana-transaction-utils/src/queue.rs b/solana-transaction-utils/src/queue.rs index a56657b..b2f6546 100644 --- a/solana-transaction-utils/src/queue.rs +++ b/solana-transaction-utils/src/queue.rs @@ -121,10 +121,10 @@ pub async fn create_transaction_queue( let mut updated_instructions = bundle.tx.instructions.clone(); let compute_budget_ix = compute_budget_instruction(compute_units); // Replace or insert compute budget instruction - if let Some(pos) = updated_instructions - .iter() - .position(|ix| ix.program_id == solana_sdk::compute_budget::id()) - { + if let Some(pos) = updated_instructions.iter().position(|ix| { + ix.program_id == solana_sdk::compute_budget::id() + && ix.data.first() == compute_budget_ix.data.first() + }) { updated_instructions[pos] = compute_budget_ix; // Replace existing } else { updated_instructions.insert(0, compute_budget_ix); // Insert at the beginning diff --git a/tuktuk-cli/Cargo.toml b/tuktuk-cli/Cargo.toml index 3700033..4326d11 100644 --- a/tuktuk-cli/Cargo.toml +++ b/tuktuk-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tuktuk-cli" -version = "0.2.11" +version = "0.2.12" description = "A cli for tuktuk" homepage.workspace = true repository.workspace = true diff --git a/tuktuk-cli/src/cmd/task.rs b/tuktuk-cli/src/cmd/task.rs index 7790c9b..30ad4d9 100644 --- a/tuktuk-cli/src/cmd/task.rs +++ b/tuktuk-cli/src/cmd/task.rs @@ -180,11 +180,10 @@ impl TaskCmd { return false; } } - let is_task_active = task.trigger.is_active(now); - if *active != is_task_active { - return false; - } - return true; + + // If active flag is set, only show tasks that are active + // Otherwise, show all tasks + return !*active || task.trigger.is_active(now); } false }); diff --git a/tuktuk-crank-turner/Cargo.toml b/tuktuk-crank-turner/Cargo.toml index a36148d..e007f01 100644 --- a/tuktuk-crank-turner/Cargo.toml +++ b/tuktuk-crank-turner/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tuktuk-crank-turner" -version = "0.2.22" +version = "0.2.23" authors.workspace = true edition.workspace = true license.workspace = true From 4eb0088ba76b85f0b36a107728d9e8a4ab277967 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Thu, 3 Jul 2025 09:45:15 -0700 Subject: [PATCH 2/4] Fix RPC race condition on task fetching, retry RawSimulated failure, add better cli options --- Cargo.lock | 1 + solana-transaction-utils/src/priority_fee.rs | 5 +- tuktuk-cli/Cargo.toml | 1 + tuktuk-cli/src/cmd/task.rs | 264 ++++++++++++++++--- tuktuk-crank-turner/src/task_processor.rs | 3 +- tuktuk-sdk/src/tuktuk.rs | 85 ++++-- 6 files changed, 288 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0bd7e9c..898faa7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6830,6 +6830,7 @@ dependencies = [ "chrono", "clap", "dirs", + "futures", "itertools 0.13.0", "serde", "serde_json", diff --git a/solana-transaction-utils/src/priority_fee.rs b/solana-transaction-utils/src/priority_fee.rs index 749d989..f2009cc 100644 --- a/solana-transaction-utils/src/priority_fee.rs +++ b/solana-transaction-utils/src/priority_fee.rs @@ -145,11 +145,10 @@ pub async fn compute_budget_for_instructions>( // Simulate the transaction to get the actual compute used let simulation_result = client.as_ref().simulate_transaction(&snub_tx).await?; - if let Some(err) = simulation_result.value.err { + if simulation_result.value.err.is_some() { info!(?simulation_result.value.logs, "simulation error"); - return Err(Error::SimulatedTransactionError(err)); } - let actual_compute_used = simulation_result.value.units_consumed.unwrap_or(200000); + let actual_compute_used = simulation_result.value.units_consumed.unwrap_or(1000000); let final_compute_budget = (actual_compute_used as f32 * compute_multiplier) as u32; Ok(( diff --git a/tuktuk-cli/Cargo.toml b/tuktuk-cli/Cargo.toml index 4326d11..dd2370f 100644 --- a/tuktuk-cli/Cargo.toml +++ b/tuktuk-cli/Cargo.toml @@ -38,3 +38,4 @@ spl-token = { workspace = true } solana-program = { workspace = true } itertools = { workspace = true } bs58 = "0.5.1" +futures = { workspace = true } diff --git a/tuktuk-cli/src/cmd/task.rs b/tuktuk-cli/src/cmd/task.rs index 30ad4d9..e2d8de4 100644 --- a/tuktuk-cli/src/cmd/task.rs +++ b/tuktuk-cli/src/cmd/task.rs @@ -1,8 +1,10 @@ -use std::collections::HashSet; +use std::{collections::HashSet, sync::Arc}; use anyhow::anyhow; +use chrono::{Local, TimeZone}; use clap::{Args, Subcommand}; use clock::SYSVAR_CLOCK; +use futures::stream::StreamExt; use itertools::Itertools; use serde::Serialize; use solana_client::rpc_config::RpcSimulateTransactionConfig; @@ -16,7 +18,10 @@ use solana_sdk::{ use solana_transaction_utils::{ pack::pack_instructions_into_transactions, priority_fee::auto_compute_limit_and_price, }; -use tuktuk_program::{types::TriggerV0, TaskQueueV0, TaskV0}; +use tuktuk_program::{ + types::{QueueTaskArgsV0, TriggerV0}, + TaskQueueV0, TaskV0, +}; use tuktuk_sdk::prelude::*; use super::{task_queue::TaskQueueArg, TransactionSource}; @@ -51,6 +56,8 @@ pub enum Cmd { default_value = "false" )] active: bool, + #[arg(long, help = "Show tasks with a succesful/failed simulation")] + successful: Option, #[arg(long, help = "Limit the number of tasks returned")] limit: Option, }, @@ -65,6 +72,20 @@ pub enum Cmd { #[arg(short, long, default_value = "false")] skip_preflight: bool, }, + Requeue { + #[command(flatten)] + task_queue: TaskQueueArg, + #[arg(short, long)] + id: Option, + #[arg(short, long, default_value = "false", help = "Requeue all stale tasks")] + stale: bool, + #[arg(long)] + description: Option, + #[arg(long)] + after_id: Option, + #[arg(long)] + new_timestamp: Option, + }, Close { #[command(flatten)] task_queue: TaskQueueArg, @@ -145,6 +166,13 @@ async fn simulate_task(client: &CliClient, task_key: Pubkey) -> Result, + pub logs: Option>, + pub compute_units: Option, +} + impl TaskCmd { pub async fn run(&self, opts: Opts) -> Result { match &self.cmd { @@ -154,6 +182,7 @@ impl TaskCmd { skip_simulate, active, limit, + successful, } => { let client = opts.client().await?; let task_queue_pubkey = task_queue.get_pubkey(&client).await?.unwrap(); @@ -173,43 +202,50 @@ impl TaskCmd { let clock: solana_sdk::clock::Clock = bincode::deserialize(&clock_acc.data)?; let now = clock.unix_timestamp; - let filtered_tasks = tasks.into_iter().filter(|(_, task)| { - if let Some(task) = task { - if let Some(description) = description { - if !task.description.starts_with(description) { - return false; + let filtered_tasks = tasks + .into_iter() + .filter(|(_, task)| { + if let Some(task) = task { + if let Some(description) = description { + if !task.description.starts_with(description) { + return false; + } } + + // If active flag is set, only show tasks that are active + // Otherwise, show all tasks + return !*active || task.trigger.is_active(now); } + false + }) + .collect::>(); - // If active flag is set, only show tasks that are active - // Otherwise, show all tasks - return !*active || task.trigger.is_active(now); - } - false - }); + let mut json_tasks = Vec::with_capacity(filtered_tasks.len()); + let mut simulation_tasks = Vec::new(); - let mut json_tasks = Vec::new(); - for (pubkey, maybe_task) in filtered_tasks { + for (i, (pubkey, maybe_task)) in filtered_tasks.into_iter().enumerate() { if let Some(task) = maybe_task { - let mut simulation_result = None; if !*skip_simulate && task.trigger.is_active(now) { - simulation_result = simulate_task(&client, pubkey).await?; + simulation_tasks.push((i, pubkey)); } - json_tasks.push(Task { - pubkey, - id: task.id, - description: task.description, - trigger: Trigger::from(task.trigger), - crank_reward: task.crank_reward, - rent_refund: task.rent_refund, - simulation_result, - transaction: if self.verbose { - Some(TransactionSource::from(task.transaction.clone())) - } else { - None + json_tasks.push(( + i, + Task { + pubkey, + id: task.id, + description: task.description, + trigger: Trigger::from(task.trigger), + crank_reward: task.crank_reward, + rent_refund: task.rent_refund, + simulation_result: None, + transaction: if self.verbose { + Some(TransactionSource::from(task.transaction.clone())) + } else { + None + }, }, - }); + )); if let Some(limit) = limit { if json_tasks.len() >= *limit as usize { @@ -218,7 +254,50 @@ impl TaskCmd { } } } - print_json(&json_tasks)?; + + // Run simulations in parallel with a limit of 10 concurrent tasks + let client = Arc::new(client); + let simulation_results = futures::stream::iter(simulation_tasks) + .map(|(i, pubkey)| { + let client = client.clone(); + async move { + let result = simulate_task(&client, pubkey).await; + (i, result) + } + }) + .buffer_unordered(10) + .collect::>() + .await; + + let mut results = vec![None; json_tasks.len()]; + for (i, result) in simulation_results { + if let Ok(sim_result) = result { + results[i] = sim_result; + } + } + + // Update tasks with simulation results + for (i, task) in json_tasks.iter_mut() { + task.simulation_result = results[*i].clone(); + } + + // Filter by simulation success/failure if requested + let mut final_tasks = json_tasks + .into_iter() + .map(|(_, task)| task) + .collect::>(); + if let Some(successful) = successful { + final_tasks.retain(|task| { + if let Some(simulation_result) = &task.simulation_result { + (*successful && simulation_result.error.is_none()) + || (!*successful && simulation_result.error.is_some()) + } else { + !*successful + } + }); + } + + print_json(&final_tasks)?; } Cmd::Close { task_queue, @@ -414,6 +493,107 @@ impl TaskCmd { } } } + Cmd::Requeue { + task_queue, + id, + new_timestamp, + stale, + description, + after_id, + } => { + let client = opts.client().await?; + let task_queue_pubkey = task_queue.get_pubkey(&client).await?.unwrap(); + let task_queue: TaskQueueV0 = client + .as_ref() + .anchor_account(&task_queue_pubkey) + .await? + .ok_or_else(|| anyhow!("Topic account not found"))?; + let task_keys = tuktuk::task::keys(&task_queue_pubkey, &task_queue)?; + let tasks = client + .as_ref() + .anchor_accounts::(&task_keys) + .await?; + + let clock_acc = client.rpc_client.get_account(&SYSVAR_CLOCK).await?; + let clock: solana_sdk::clock::Clock = bincode::deserialize(&clock_acc.data)?; + let now = clock.unix_timestamp; + + let filtered_tasks = tasks.into_iter().filter(|(_, task)| { + if let Some(task) = task { + if *stale { + let is_stale = task.trigger.is_active(now) + && match task.trigger { + TriggerV0::Now => false, + TriggerV0::Timestamp(ts) => { + now - ts > task_queue.stale_task_age as i64 + } + }; + + if !is_stale { + return false; + } + } + + if let Some(description) = description { + if !task.description.starts_with(description) { + return false; + } + } + + if let Some(after_id) = after_id { + if task.id <= *after_id { + return false; + } + } + + if let Some(id) = id { + if task.id != *id { + return false; + } + } + + return true; + } + false + }); + + let collected_tasks = filtered_tasks + .into_iter() + .flat_map(|(_, task)| task) + .collect_vec(); + + println!("Requeueing {} tasks", collected_tasks.len()); + + for task in collected_tasks { + println!("Requeueing task: {:?}", task); + let (new_task_key, ix) = tuktuk::task::queue( + client.as_ref(), + client.payer.pubkey(), + client.payer.pubkey(), + task_queue_pubkey, + QueueTaskArgsV0 { + id: task.id, + trigger: new_timestamp.map_or(TriggerV0::Now, TriggerV0::Timestamp), + transaction: task.transaction.clone(), + crank_reward: Some(task.crank_reward), + free_tasks: task.free_tasks, + description: task.description, + }, + ) + .await?; + + send_instructions( + client.rpc_client.clone(), + &client.payer, + client.opts.ws_url().as_str(), + &[ix], + &[], + ) + .await?; + + println!("New task key: {new_task_key}"); + } + } } Ok(()) } @@ -433,24 +613,28 @@ struct Task { pub transaction: Option, } -#[derive(Serialize)] -struct SimulationResult { - pub error: Option, - pub logs: Option>, - pub compute_units: Option, -} - #[derive(Serialize)] enum Trigger { Now, - Timestamp(i64), + Timestamp { + epoch: i64, + #[serde(rename = "human_readable")] + formatted: String, + }, } impl From for Trigger { fn from(trigger: TriggerV0) -> Self { match trigger { TriggerV0::Now => Trigger::Now, - TriggerV0::Timestamp(ts) => Trigger::Timestamp(ts), + TriggerV0::Timestamp(ts) => Trigger::Timestamp { + epoch: ts, + formatted: Local + .timestamp_opt(ts, 0) + .single() + .unwrap_or_else(Local::now) + .to_rfc3339(), + }, } } } diff --git a/tuktuk-crank-turner/src/task_processor.rs b/tuktuk-crank-turner/src/task_processor.rs index f96baa6..193a73a 100644 --- a/tuktuk-crank-turner/src/task_processor.rs +++ b/tuktuk-crank-turner/src/task_processor.rs @@ -280,7 +280,8 @@ impl TimedTask { | TransactionQueueError::TransactionError(_) | TransactionQueueError::RpcError(_) | TransactionQueueError::ChannelClosed - | TransactionQueueError::MaxRetriesExceeded => { + | TransactionQueueError::MaxRetriesExceeded + | TransactionQueueError::RawSimulatedTransactionError(_) => { if self.total_retries < self.max_retries && !self.is_cleanup_task { let base_delay = 30 * (1 << self.total_retries); let jitter = rand::random_range(0..60); // Jitter up to 1 minute to prevent conflicts with other turners diff --git a/tuktuk-sdk/src/tuktuk.rs b/tuktuk-sdk/src/tuktuk.rs index c1f614a..e7423de 100644 --- a/tuktuk-sdk/src/tuktuk.rs +++ b/tuktuk-sdk/src/tuktuk.rs @@ -677,7 +677,7 @@ pub struct TaskUpdate { } pub mod task { - use std::time::Duration; + use std::{collections::HashMap, time::Duration}; use anchor_lang::{AccountDeserialize, InstructionData, ToAccountMetas}; use futures::{future::BoxFuture, stream::unfold, Stream, StreamExt}; @@ -725,12 +725,12 @@ pub mod task { queue_authority: Pubkey, args: QueueTaskArgsV0, ) -> Result<(Pubkey, Instruction), Error> { - let task_key = self::key( - &task_queue_key, - task_queue - .next_available_task_id() - .ok_or_else(|| Error::TooManyTasks)?, - ); + let id = task_queue + .next_available_task_id() + .ok_or_else(|| Error::TooManyTasks)?; + let task_key = self::key(&task_queue_key, id); + let mut args = args; + args.id = id; Ok(( task_key, @@ -782,11 +782,11 @@ pub mod task { > { let (stream, unsubscribe) = pubsub_tracker.watch_pubkey(*task_queue_key).await?; let stream = Box::pin(stream); - let retry_interval = tokio::time::interval(Duration::from_secs(10)); + let retry_interval = tokio::time::interval(Duration::from_secs(30)); let task_queue = task_queue.clone(); let ret = unfold( - (stream, task_queue, vec![], retry_interval), + (stream, task_queue, HashMap::new(), retry_interval), move |(mut stream, mut last_tq, mut missing_tasks, mut retry_interval)| async move { loop { tokio::select! { @@ -815,8 +815,21 @@ pub mod task { .collect_vec(); let tasks = client.anchor_accounts(&new_task_keys).await?; + + // Add empty tasks to missing_tasks for retry + for (key, task) in tasks.iter() { + if task.is_none() && !missing_tasks.contains_key(key) { + missing_tasks.insert(*key, 0); + } + } + + // Filter out missing tasks from the update + let available_tasks = tasks.into_iter() + .filter(|(_, task)| task.is_some()) + .collect_vec(); + Ok(TaskUpdate { - tasks, + tasks: available_tasks, task_queue: new_task_queue, removed: removed_task_keys, update_type, @@ -831,24 +844,42 @@ pub mod task { } } _ = retry_interval.tick() => { - let searchable_missing_tasks = missing_tasks.clone(); - missing_tasks.clear(); - match client.anchor_accounts(&searchable_missing_tasks).await { - Ok(tasks) => { - let found_tasks = tasks.into_iter().filter(|(_, task)| task.is_some()).collect_vec(); - if !found_tasks.is_empty() { - return Some((Ok(TaskUpdate { - tasks: found_tasks, - task_queue: last_tq.clone(), - removed: vec![], - update_type: UpdateType::Poll, - }), (stream, last_tq, missing_tasks, retry_interval))); + if !missing_tasks.is_empty() { + let retry_keys: Vec<_> = missing_tasks.keys().cloned().collect(); + match client.anchor_accounts(&retry_keys).await { + Ok(tasks) => { + let mut found_tasks = Vec::new(); + + // Update retry counts and collect found tasks + for (key, task) in tasks { + if let Some(task) = task { + found_tasks.push((key, Some(task))); + missing_tasks.remove(&key); + } else { + // Safely increment retry count and remove if exceeded max attempts + if let Some(retry_count) = missing_tasks.get_mut(&key) { + *retry_count += 1; + if *retry_count >= 3 { + missing_tasks.remove(&key); + } + } + } + } + + if !found_tasks.is_empty() { + return Some((Ok(TaskUpdate { + tasks: found_tasks, + task_queue: last_tq.clone(), + removed: vec![], + update_type: UpdateType::Poll, + }), (stream, last_tq, missing_tasks, retry_interval))); + } + }, + Err(e) => { + return Some((Err(e), (stream, last_tq, missing_tasks, retry_interval))); } - }, - Err(e) => { - return Some((Err(e), (stream, last_tq, missing_tasks, retry_interval))); - } - }; + }; + } } } } From 933ac5f6d36af110d63070d6fec17e8901e1bb89 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Thu, 3 Jul 2025 09:46:49 -0700 Subject: [PATCH 3/4] Bump cargos --- Cargo.lock | 6 +++--- Cargo.toml | 4 ++-- solana-transaction-utils/Cargo.toml | 2 +- tuktuk-crank-turner/Cargo.toml | 2 +- tuktuk-sdk/Cargo.toml | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 898faa7..f9b0e9b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5862,7 +5862,7 @@ dependencies = [ [[package]] name = "solana-transaction-utils" -version = "0.4.1" +version = "0.4.2" dependencies = [ "bincode", "dashmap", @@ -6850,7 +6850,7 @@ dependencies = [ [[package]] name = "tuktuk-crank-turner" -version = "0.2.23" +version = "0.2.24" dependencies = [ "anchor-client", "anchor-lang", @@ -6891,7 +6891,7 @@ dependencies = [ [[package]] name = "tuktuk-sdk" -version = "0.3.5" +version = "0.3.6" dependencies = [ "anchor-lang", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 5486166..1e97cfa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,8 +57,8 @@ spl-associated-token-account = "6.0.0" spl-token = "4.0.0" itertools = "0.13" tokio-graceful-shutdown = "0.15" -solana-transaction-utils = { version = "0.4.1", path = "./solana-transaction-utils" } -tuktuk-sdk = { version = "0.3.5", path = "./tuktuk-sdk" } +solana-transaction-utils = { version = "0.4.2", path = "./solana-transaction-utils" } +tuktuk-sdk = { version = "0.3.6", path = "./tuktuk-sdk" } tuktuk-program = { version = "0.3.2", path = "./tuktuk-program" } solana-account-decoder = { version = "2.2.3" } solana-clock = { version = "2.2.1" } diff --git a/solana-transaction-utils/Cargo.toml b/solana-transaction-utils/Cargo.toml index 6d38b37..f508eb2 100644 --- a/solana-transaction-utils/Cargo.toml +++ b/solana-transaction-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "solana-transaction-utils" -version = "0.4.1" +version = "0.4.2" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/tuktuk-crank-turner/Cargo.toml b/tuktuk-crank-turner/Cargo.toml index e007f01..69dc1d1 100644 --- a/tuktuk-crank-turner/Cargo.toml +++ b/tuktuk-crank-turner/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tuktuk-crank-turner" -version = "0.2.23" +version = "0.2.24" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/tuktuk-sdk/Cargo.toml b/tuktuk-sdk/Cargo.toml index 2d2b1cd..8c333c7 100644 --- a/tuktuk-sdk/Cargo.toml +++ b/tuktuk-sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tuktuk-sdk" -version = "0.3.5" +version = "0.3.6" authors.workspace = true edition.workspace = true license.workspace = true From 4cc8752a6e8860bb039049e7607d9f73b6ac03fb Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Thu, 3 Jul 2025 09:58:16 -0700 Subject: [PATCH 4/4] lint --- tuktuk-cli/src/cmd/task.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/tuktuk-cli/src/cmd/task.rs b/tuktuk-cli/src/cmd/task.rs index e2d8de4..81e1e77 100644 --- a/tuktuk-cli/src/cmd/task.rs +++ b/tuktuk-cli/src/cmd/task.rs @@ -565,7 +565,6 @@ impl TaskCmd { println!("Requeueing {} tasks", collected_tasks.len()); for task in collected_tasks { - println!("Requeueing task: {:?}", task); let (new_task_key, ix) = tuktuk::task::queue( client.as_ref(), client.payer.pubkey(),