diff --git a/runtime/src/bank_client.rs b/runtime/src/bank_client.rs index 4607d9fb4f..c2452eec31 100644 --- a/runtime/src/bank_client.rs +++ b/runtime/src/bank_client.rs @@ -1,4 +1,5 @@ use crate::bank::Bank; +use solana_sdk::async_client::AsyncClient; use solana_sdk::instruction::Instruction; use solana_sdk::message::Message; use solana_sdk::pubkey::Pubkey; @@ -8,11 +9,48 @@ use solana_sdk::sync_client::SyncClient; use solana_sdk::system_instruction; use solana_sdk::transaction::Transaction; use solana_sdk::transport::Result; +use std::io; pub struct BankClient<'a> { bank: &'a Bank, } +impl<'a> AsyncClient for BankClient<'a> { + fn async_send_transaction(&self, transaction: Transaction) -> io::Result { + // Ignore the result. Client must use get_signature_status() instead. + let _ = self.bank.process_transaction(&transaction); + + Ok(transaction.signatures.get(0).cloned().unwrap_or_default()) + } + + fn async_send_message(&self, keypairs: &[&Keypair], message: Message) -> io::Result { + let blockhash = self.bank.last_blockhash(); + let transaction = Transaction::new(&keypairs, message, blockhash); + self.async_send_transaction(transaction) + } + + fn async_send_instruction( + &self, + keypair: &Keypair, + instruction: Instruction, + ) -> io::Result { + let message = Message::new(vec![instruction]); + self.async_send_message(&[keypair], message) + } + + /// Transfer `lamports` from `keypair` to `pubkey` + fn async_transfer( + &self, + lamports: u64, + keypair: &Keypair, + pubkey: &Pubkey, + ) -> io::Result { + let transfer_instruction = + system_instruction::transfer(&keypair.pubkey(), pubkey, lamports); + self.async_send_instruction(keypair, transfer_instruction) + } +} + impl<'a> SyncClient for BankClient<'a> { fn send_message(&self, keypairs: &[&Keypair], message: Message) -> Result { let blockhash = self.bank.last_blockhash(); @@ -29,8 +67,9 @@ impl<'a> SyncClient for BankClient<'a> { /// Transfer `lamports` from `keypair` to `pubkey` fn transfer(&self, lamports: u64, keypair: &Keypair, pubkey: &Pubkey) -> Result { - let move_instruction = system_instruction::transfer(&keypair.pubkey(), pubkey, lamports); - self.send_instruction(keypair, move_instruction) + let transfer_instruction = + system_instruction::transfer(&keypair.pubkey(), pubkey, lamports); + self.send_instruction(keypair, transfer_instruction) } fn get_account_data(&self, pubkey: &Pubkey) -> Result>> { diff --git a/sdk/src/async_client.rs b/sdk/src/async_client.rs new file mode 100644 index 0000000000..64440a1aaa --- /dev/null +++ b/sdk/src/async_client.rs @@ -0,0 +1,35 @@ +//! Defines a trait for non-blocking (asynchronous) communication with a Solana server. +//! Implementations are expected to create tranasctions, sign them, and send +//! them but without waiting to see if the server accepted it. + +use crate::instruction::Instruction; +use crate::message::Message; +use crate::pubkey::Pubkey; +use crate::signature::{Keypair, Signature}; +use crate::transaction::Transaction; +use std::io; + +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) -> io::Result; + + /// 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. + fn async_send_message(&self, keypairs: &[&Keypair], message: Message) -> io::Result; + + /// 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. + fn async_send_instruction( + &self, + keypair: &Keypair, + instruction: Instruction, + ) -> io::Result; + + /// Attempt to transfer lamports from `keypair` to `pubkey`, but don't wait to confirm. + fn async_transfer( + &self, + lamports: u64, + keypair: &Keypair, + pubkey: &Pubkey, + ) -> io::Result; +} diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index d3185e3745..49f25fd5fb 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -1,4 +1,5 @@ pub mod account; +pub mod async_client; pub mod bpf_loader; pub mod fee_calculator; pub mod genesis_block;