From 792bbf75abb43b0b42c01e20a9dd160cf1a853b1 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Sat, 2 Apr 2022 11:12:02 +0800 Subject: [PATCH] Support sending versioned txs in AsyncClient (#23982) --- client/src/thin_client.rs | 42 ++++++------------------------ runtime/src/bank_client.rs | 53 ++++++-------------------------------- sdk/src/client.rs | 47 ++++++++++++++++++++++++++++----- 3 files changed, 57 insertions(+), 85 deletions(-) diff --git a/client/src/thin_client.rs b/client/src/thin_client.rs index 9fed050210..8d969ad672 100644 --- a/client/src/thin_client.rs +++ b/client/src/thin_client.rs @@ -595,47 +595,21 @@ impl SyncClient for ThinClient { } impl AsyncClient for ThinClient { - fn async_send_transaction(&self, transaction: Transaction) -> TransportResult { - let transaction = VersionedTransaction::from(transaction); + fn async_send_versioned_transaction( + &self, + transaction: VersionedTransaction, + ) -> TransportResult { serialize_and_send_transaction(&transaction, self.tpu_addr())?; Ok(transaction.signatures[0]) } - fn async_send_batch(&self, transactions: Vec) -> TransportResult<()> { - let batch: Vec = transactions.into_iter().map(Into::into).collect(); + fn async_send_versioned_transaction_batch( + &self, + batch: Vec, + ) -> TransportResult<()> { par_serialize_and_send_transaction_batch(&batch[..], self.tpu_addr())?; Ok(()) } - - fn async_send_message( - &self, - keypairs: &T, - message: Message, - recent_blockhash: Hash, - ) -> TransportResult { - let transaction = Transaction::new(keypairs, message, recent_blockhash); - self.async_send_transaction(transaction) - } - fn async_send_instruction( - &self, - keypair: &Keypair, - instruction: Instruction, - recent_blockhash: Hash, - ) -> TransportResult { - let message = Message::new(&[instruction], Some(&keypair.pubkey())); - self.async_send_message(&[keypair], message, recent_blockhash) - } - fn async_transfer( - &self, - lamports: u64, - keypair: &Keypair, - pubkey: &Pubkey, - recent_blockhash: Hash, - ) -> TransportResult { - let transfer_instruction = - system_instruction::transfer(&keypair.pubkey(), pubkey, lamports); - self.async_send_instruction(keypair, transfer_instruction, recent_blockhash) - } } pub fn create_client((rpc, tpu): (SocketAddr, SocketAddr)) -> ThinClient { diff --git a/runtime/src/bank_client.rs b/runtime/src/bank_client.rs index 742fc98769..b8b4de33af 100644 --- a/runtime/src/bank_client.rs +++ b/runtime/src/bank_client.rs @@ -14,7 +14,7 @@ use { signature::{Keypair, Signature, Signer}, signers::Signers, system_instruction, - transaction::{self, Transaction}, + transaction::{self, Transaction, VersionedTransaction}, transport::{Result, TransportError}, }, std::{ @@ -28,7 +28,7 @@ use { pub struct BankClient { bank: Arc, - transaction_sender: Mutex>, + transaction_sender: Mutex>, } impl Client for BankClient { @@ -38,52 +38,15 @@ impl Client for BankClient { } impl AsyncClient for BankClient { - fn async_send_transaction(&self, transaction: Transaction) -> Result { + fn async_send_versioned_transaction( + &self, + transaction: VersionedTransaction, + ) -> Result { let signature = transaction.signatures.get(0).cloned().unwrap_or_default(); let transaction_sender = self.transaction_sender.lock().unwrap(); transaction_sender.send(transaction).unwrap(); Ok(signature) } - - fn async_send_batch(&self, transactions: Vec) -> Result<()> { - for t in transactions { - self.async_send_transaction(t)?; - } - Ok(()) - } - - fn async_send_message( - &self, - keypairs: &T, - message: Message, - recent_blockhash: Hash, - ) -> Result { - let transaction = Transaction::new(keypairs, message, recent_blockhash); - self.async_send_transaction(transaction) - } - - fn async_send_instruction( - &self, - keypair: &Keypair, - instruction: Instruction, - recent_blockhash: Hash, - ) -> Result { - let message = Message::new(&[instruction], Some(&keypair.pubkey())); - self.async_send_message(&[keypair], message, recent_blockhash) - } - - /// Transfer `lamports` from `keypair` to `pubkey` - fn async_transfer( - &self, - lamports: u64, - keypair: &Keypair, - pubkey: &Pubkey, - recent_blockhash: Hash, - ) -> Result { - let transfer_instruction = - system_instruction::transfer(&keypair.pubkey(), pubkey, lamports); - self.async_send_instruction(keypair, transfer_instruction, recent_blockhash) - } } impl SyncClient for BankClient { @@ -333,13 +296,13 @@ impl SyncClient for BankClient { } impl BankClient { - fn run(bank: &Bank, transaction_receiver: Receiver) { + fn run(bank: &Bank, transaction_receiver: Receiver) { while let Ok(tx) = transaction_receiver.recv() { let mut transactions = vec![tx]; while let Ok(tx) = transaction_receiver.try_recv() { transactions.push(tx); } - let _ = bank.try_process_transactions(transactions.iter()); + let _ = bank.try_process_entry_transactions(transactions); } } diff --git a/sdk/src/client.rs b/sdk/src/client.rs index 3a26974e02..c2f7f62d35 100644 --- a/sdk/src/client.rs +++ b/sdk/src/client.rs @@ -20,8 +20,10 @@ use crate::{ message::Message, pubkey::Pubkey, signature::{Keypair, Signature}, + signer::Signer, signers::Signers, - transaction, + system_instruction, + transaction::{self, Transaction, VersionedTransaction}, transport::Result, }; @@ -173,9 +175,32 @@ pub trait SyncClient { pub trait AsyncClient { /// Send a signed transaction, but don't wait to see if the server accepted it. - fn async_send_transaction(&self, transaction: transaction::Transaction) -> Result; + fn async_send_transaction(&self, transaction: Transaction) -> Result { + self.async_send_versioned_transaction(transaction.into()) + } - fn async_send_batch(&self, transactions: Vec) -> Result<()>; + /// Send a batch of signed transactions without confirmation. + fn async_send_batch(&self, transactions: Vec) -> Result<()> { + let transactions = transactions.into_iter().map(Into::into).collect(); + self.async_send_versioned_transaction_batch(transactions) + } + + /// Send a signed versioned transaction, but don't wait to see if the server accepted it. + fn async_send_versioned_transaction( + &self, + transaction: VersionedTransaction, + ) -> Result; + + /// Send a batch of signed versioned transactions without confirmation. + fn async_send_versioned_transaction_batch( + &self, + transactions: Vec, + ) -> Result<()> { + for t in transactions { + self.async_send_versioned_transaction(t)?; + } + Ok(()) + } /// Create a transaction from the given message, and send it to the /// server, but don't wait for to see if the server accepted it. @@ -184,7 +209,10 @@ pub trait AsyncClient { keypairs: &T, message: Message, recent_blockhash: Hash, - ) -> Result; + ) -> Result { + let transaction = Transaction::new(keypairs, message, recent_blockhash); + self.async_send_transaction(transaction) + } /// Create a transaction from a single instruction that only requires /// a single signer. Then send it to the server, but don't wait for a reply. @@ -193,7 +221,10 @@ pub trait AsyncClient { keypair: &Keypair, instruction: Instruction, recent_blockhash: Hash, - ) -> Result; + ) -> Result { + let message = Message::new(&[instruction], Some(&keypair.pubkey())); + self.async_send_message(&[keypair], message, recent_blockhash) + } /// Attempt to transfer lamports from `keypair` to `pubkey`, but don't wait to confirm. fn async_transfer( @@ -202,5 +233,9 @@ pub trait AsyncClient { keypair: &Keypair, pubkey: &Pubkey, recent_blockhash: Hash, - ) -> Result; + ) -> Result { + let transfer_instruction = + system_instruction::transfer(&keypair.pubkey(), pubkey, lamports); + self.async_send_instruction(keypair, transfer_instruction, recent_blockhash) + } }