diff --git a/Cargo.lock b/Cargo.lock index 657fa0005..e07f54e78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -489,9 +489,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.70" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "arrayref" diff --git a/plugin/src/builders/pool_rotation.rs b/plugin/src/builders/pool_rotation.rs index 85c2f504b..3376a5e19 100644 --- a/plugin/src/builders/pool_rotation.rs +++ b/plugin/src/builders/pool_rotation.rs @@ -1,13 +1,12 @@ use std::sync::Arc; -use anchor_lang::{ - solana_program::instruction::Instruction, - InstructionData, ToAccountMetas -}; +use anchor_lang::{solana_program::instruction::Instruction, InstructionData, ToAccountMetas}; use clockwork_network_program::state::{Config, Pool, Registry, Snapshot, SnapshotFrame, Worker}; use log::info; use solana_client::nonblocking::rpc_client::RpcClient; -use solana_sdk::{signature::Keypair, signer::Signer, transaction::Transaction}; +use solana_geyser_plugin_interface::geyser_plugin_interface::GeyserPluginError; +use solana_program::message::{VersionedMessage, v0}; +use solana_sdk::{signature::Keypair, signer::Signer, transaction::VersionedTransaction}; use crate::pool_position::PoolPosition; @@ -19,7 +18,7 @@ pub async fn build_pool_rotation_tx<'a>( snapshot: Snapshot, snapshot_frame: SnapshotFrame, worker_id: u64, -) -> Option { +) -> Option { info!("nonce: {:?} total_stake: {:?} current_position: {:?} stake_offset: {:?} stake_amount: {:?}", registry.nonce.checked_rem(snapshot.total_stake), snapshot.total_stake, @@ -81,7 +80,23 @@ pub async fn build_pool_rotation_tx<'a>( }; // Build and sign tx. - let mut tx = Transaction::new_with_payer(&[ix.clone()], Some(&keypair.pubkey())); - tx.sign(&[keypair], client.get_latest_blockhash().await.unwrap()); - return Some(tx); + let blockhash = client.get_latest_blockhash().await.unwrap(); + + let tx = match v0::Message::try_compile( + &keypair.pubkey(), + &[ix.clone()], + &[], + blockhash, + ) { + Err(_) => Err(GeyserPluginError::Custom(format!("Failed to compile to v0 message ").into())), + Ok(message) => match VersionedTransaction::try_new( + VersionedMessage::V0(message), + &[keypair] + ) { + Err(_) => Err(GeyserPluginError::Custom(format!("Failed to create versioned transaction ").into())), + Ok(tx) => Ok(tx) + } + + }; + return tx.ok(); } diff --git a/plugin/src/builders/thread_exec.rs b/plugin/src/builders/thread_exec.rs index e0ac02df7..46c339fa0 100644 --- a/plugin/src/builders/thread_exec.rs +++ b/plugin/src/builders/thread_exec.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use anchor_lang::{InstructionData, ToAccountMetas}; use clockwork_thread_program::state::{VersionedThread, Trigger}; use clockwork_network_program::state::Worker; +use bincode::serialize; use clockwork_utils::thread::PAYER_PUBKEY; use log::info; use solana_account_decoder::UiAccountEncoding; @@ -16,12 +17,16 @@ use solana_geyser_plugin_interface::geyser_plugin_interface::{ }; use solana_program::{ instruction::{AccountMeta, Instruction}, - pubkey::Pubkey, + pubkey::Pubkey, address_lookup_table_account::AddressLookupTableAccount, }; use solana_sdk::{ - account::Account, commitment_config::CommitmentConfig, - compute_budget::ComputeBudgetInstruction, signature::Keypair, signer::Signer, - transaction::Transaction, + account::Account, + commitment_config::CommitmentConfig, + compute_budget::ComputeBudgetInstruction, + message::{v0, VersionedMessage}, + signature::Keypair, + signer::Signer, + transaction::VersionedTransaction, }; /// Max byte size of a serialized transaction. @@ -40,7 +45,8 @@ pub async fn build_thread_exec_tx( thread: VersionedThread, thread_pubkey: Pubkey, worker_id: u64, -) -> PluginResult> { + address_lookup_tables: Vec +) -> PluginResult> { // Grab the thread and relevant data. let now = std::time::Instant::now(); let blockhash = client.get_latest_blockhash().await.unwrap(); @@ -73,11 +79,24 @@ pub async fn build_thread_exec_tx( let mut successful_ixs: Vec = vec![]; let mut units_consumed: Option = None; loop { - let mut sim_tx = Transaction::new_with_payer(&ixs, Some(&signatory_pubkey)); - sim_tx.sign(&[payer], blockhash); + let sim_tx = match v0::Message::try_compile( + &signatory_pubkey, + &ixs, + &address_lookup_tables, + blockhash, + ) { + Err(_) => Err(GeyserPluginError::Custom(format!("Failed to compile to v0 message ").into())), + Ok(message) => match VersionedTransaction::try_new( + VersionedMessage::V0(message), + &[payer] + ) { + Err(_) => Err(GeyserPluginError::Custom(format!("Failed to create versioned transaction ").into())), + Ok(tx) => Ok(tx) + } + }?; // Exit early if the transaction exceeds the size limit. - if sim_tx.message_data().len() > TRANSACTION_MESSAGE_SIZE_LIMIT { + if serialize(&sim_tx).unwrap().len() > TRANSACTION_MESSAGE_SIZE_LIMIT { break; } @@ -199,8 +218,23 @@ pub async fn build_thread_exec_tx( } // Build and return the signed transaction. - let mut tx = Transaction::new_with_payer(&successful_ixs, Some(&signatory_pubkey)); - tx.sign(&[payer], blockhash); + let tx = match v0::Message::try_compile( + &signatory_pubkey, + &ixs, + &address_lookup_tables, + blockhash, + ) { + Err(_) => Err(GeyserPluginError::Custom(format!("Failed to compile to v0 message ").into())), + Ok(message) => match VersionedTransaction::try_new( + VersionedMessage::V0(message), + &[payer] + ) { + Err(_) => Err(GeyserPluginError::Custom(format!("Failed to create versioned transaction ").into())), + Ok(tx) => Ok(tx) + } + + }?; + info!( "slot: {:?} thread: {:?} sim_duration: {:?} instruction_count: {:?} compute_units: {:?} tx_sig: {:?}", slot, diff --git a/plugin/src/executors/tx.rs b/plugin/src/executors/tx.rs index 8ff4d0511..bdd928d94 100644 --- a/plugin/src/executors/tx.rs +++ b/plugin/src/executors/tx.rs @@ -25,7 +25,7 @@ use solana_program::pubkey::Pubkey; use solana_sdk::{ commitment_config::CommitmentConfig, signature::{Keypair, Signature}, - transaction::Transaction, + transaction::VersionedTransaction, }; use tokio::{runtime::Runtime, sync::RwLock}; @@ -428,7 +428,7 @@ impl TxExecutor { observed_slot: u64, due_slot: u64, thread_pubkey: Pubkey, - ) -> Option<(Pubkey, Transaction, u64)> { + ) -> Option<(Pubkey, VersionedTransaction, u64)> { let thread = match client.clone().get::(&thread_pubkey).await { Err(_err) => { self.increment_simulation_failure(thread_pubkey).await; @@ -455,6 +455,7 @@ impl TxExecutor { thread, thread_pubkey, self.config.worker_id, + vec![], ) .await { @@ -490,7 +491,7 @@ impl TxExecutor { self: Arc, slot: u64, thread_pubkey: Pubkey, - tx: &Transaction, + tx: &VersionedTransaction, ) -> PluginResult<()> { let r_transaction_history = self.transaction_history.read().await; if let Some(metadata) = r_transaction_history.get(&thread_pubkey) { @@ -502,7 +503,10 @@ impl TxExecutor { Ok(()) } - async fn simulate_tx(self: Arc, tx: &Transaction) -> PluginResult { + async fn simulate_tx( + self: Arc, + tx: &VersionedTransaction, + ) -> PluginResult { TPU_CLIENT .get() .await @@ -531,8 +535,13 @@ impl TxExecutor { })? } - async fn submit_tx(self: Arc, tx: &Transaction) -> PluginResult { - if !TPU_CLIENT.get().await.send_transaction(tx).await { + async fn submit_tx( + self: Arc, + tx: &VersionedTransaction, + ) -> PluginResult { + let serialized_tx = serialize(tx).unwrap(); + + if !TPU_CLIENT.get().await.send_wire_transaction(serialized_tx).await { return Err(GeyserPluginError::Custom( "Failed to send transaction".into(), ));