Remove need for BanksClientExt trait (#13519)
This commit is contained in:
parent
2c2432fddc
commit
2660b44d91
|
@ -3614,7 +3614,6 @@ dependencies = [
|
||||||
name = "solana-banks-client"
|
name = "solana-banks-client"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
|
||||||
"bincode",
|
"bincode",
|
||||||
"futures 0.3.5",
|
"futures 0.3.5",
|
||||||
"solana-banks-interface",
|
"solana-banks-interface",
|
||||||
|
|
|
@ -9,7 +9,6 @@ homepage = "https://solana.com/"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait = "0.1.36"
|
|
||||||
bincode = "1.3.1"
|
bincode = "1.3.1"
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
solana-banks-interface = { path = "../banks-interface", version = "1.5.0" }
|
solana-banks-interface = { path = "../banks-interface", version = "1.5.0" }
|
||||||
|
|
|
@ -5,9 +5,8 @@
|
||||||
//! but they are undocumented, may change over time, and are generally more
|
//! but they are undocumented, may change over time, and are generally more
|
||||||
//! cumbersome to use.
|
//! cumbersome to use.
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use futures::future::join_all;
|
use futures::future::join_all;
|
||||||
pub use solana_banks_interface::{BanksClient, TransactionStatus};
|
pub use solana_banks_interface::{BanksClient as TarpcClient, TransactionStatus};
|
||||||
use solana_banks_interface::{BanksRequest, BanksResponse};
|
use solana_banks_interface::{BanksRequest, BanksResponse};
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::{from_account, Account},
|
account::{from_account, Account},
|
||||||
|
@ -19,107 +18,118 @@ use solana_sdk::{
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
signature::Signature,
|
signature::Signature,
|
||||||
sysvar,
|
sysvar,
|
||||||
transaction::Transaction,
|
transaction::{self, Transaction},
|
||||||
transport,
|
transport,
|
||||||
};
|
};
|
||||||
use std::io::{self, Error, ErrorKind};
|
use std::io::{self, Error, ErrorKind};
|
||||||
use tarpc::{
|
use tarpc::{
|
||||||
client, context,
|
client::{self, channel::RequestDispatch, NewClient},
|
||||||
rpc::{transport::channel::UnboundedChannel, ClientMessage, Response},
|
context::{self, Context},
|
||||||
|
rpc::{ClientMessage, Response},
|
||||||
serde_transport::tcp,
|
serde_transport::tcp,
|
||||||
|
Transport,
|
||||||
};
|
};
|
||||||
use tokio::{net::ToSocketAddrs, time::Duration};
|
use tokio::{net::ToSocketAddrs, time::Duration};
|
||||||
use tokio_serde::formats::Bincode;
|
use tokio_serde::formats::Bincode;
|
||||||
|
|
||||||
#[async_trait]
|
// This exists only for backward compatibility
|
||||||
pub trait BanksClientExt {
|
pub trait BanksClientExt {}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct BanksClient {
|
||||||
|
inner: TarpcClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BanksClient {
|
||||||
|
#[allow(clippy::new_ret_no_self)]
|
||||||
|
pub fn new<C>(
|
||||||
|
config: client::Config,
|
||||||
|
transport: C,
|
||||||
|
) -> NewClient<TarpcClient, RequestDispatch<BanksRequest, BanksResponse, C>>
|
||||||
|
where
|
||||||
|
C: Transport<ClientMessage<BanksRequest>, Response<BanksResponse>>,
|
||||||
|
{
|
||||||
|
TarpcClient::new(config, transport)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_transaction_with_context(
|
||||||
|
&mut self,
|
||||||
|
ctx: Context,
|
||||||
|
transaction: Transaction,
|
||||||
|
) -> io::Result<()> {
|
||||||
|
self.inner
|
||||||
|
.send_transaction_with_context(ctx, transaction)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_fees_with_commitment_and_context(
|
||||||
|
&mut self,
|
||||||
|
ctx: Context,
|
||||||
|
commitment: CommitmentLevel,
|
||||||
|
) -> io::Result<(FeeCalculator, Hash, Slot)> {
|
||||||
|
self.inner
|
||||||
|
.get_fees_with_commitment_and_context(ctx, commitment)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_transaction_status_with_context(
|
||||||
|
&mut self,
|
||||||
|
ctx: Context,
|
||||||
|
signature: Signature,
|
||||||
|
) -> io::Result<Option<TransactionStatus>> {
|
||||||
|
self.inner
|
||||||
|
.get_transaction_status_with_context(ctx, signature)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_slot_with_context(
|
||||||
|
&mut self,
|
||||||
|
ctx: Context,
|
||||||
|
commitment: CommitmentLevel,
|
||||||
|
) -> io::Result<Slot> {
|
||||||
|
self.inner.get_slot_with_context(ctx, commitment).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn process_transaction_with_commitment_and_context(
|
||||||
|
&mut self,
|
||||||
|
ctx: Context,
|
||||||
|
transaction: Transaction,
|
||||||
|
commitment: CommitmentLevel,
|
||||||
|
) -> io::Result<Option<transaction::Result<()>>> {
|
||||||
|
self.inner
|
||||||
|
.process_transaction_with_commitment_and_context(ctx, transaction, commitment)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_account_with_commitment_and_context(
|
||||||
|
&mut self,
|
||||||
|
ctx: Context,
|
||||||
|
address: Pubkey,
|
||||||
|
commitment: CommitmentLevel,
|
||||||
|
) -> io::Result<Option<Account>> {
|
||||||
|
self.inner
|
||||||
|
.get_account_with_commitment_and_context(ctx, address, commitment)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
/// Send a transaction and return immediately. The server will resend the
|
/// Send a transaction and return immediately. The server will resend the
|
||||||
/// transaction until either it is accepted by the cluster or the transaction's
|
/// transaction until either it is accepted by the cluster or the transaction's
|
||||||
/// blockhash expires.
|
/// blockhash expires.
|
||||||
async fn send_transaction(&mut self, transaction: Transaction) -> io::Result<()>;
|
pub async fn send_transaction(&mut self, transaction: Transaction) -> io::Result<()> {
|
||||||
|
|
||||||
/// Return a recent, rooted blockhash from the server. The cluster will only accept
|
|
||||||
/// transactions with a blockhash that has not yet expired. Use the `get_fees`
|
|
||||||
/// method to get both a blockhash and the blockhash's last valid slot.
|
|
||||||
async fn get_recent_blockhash(&mut self) -> io::Result<Hash>;
|
|
||||||
|
|
||||||
/// Return the fee parameters associated with a recent, rooted blockhash. The cluster
|
|
||||||
/// will use the transaction's blockhash to look up these same fee parameters and
|
|
||||||
/// use them to calculate the transaction fee.
|
|
||||||
async fn get_fees(&mut self) -> io::Result<(FeeCalculator, Hash, Slot)>;
|
|
||||||
|
|
||||||
/// Return the cluster rent
|
|
||||||
async fn get_rent(&mut self) -> io::Result<Rent>;
|
|
||||||
|
|
||||||
/// Send a transaction and return after the transaction has been rejected or
|
|
||||||
/// reached the given level of commitment.
|
|
||||||
async fn process_transaction_with_commitment(
|
|
||||||
&mut self,
|
|
||||||
transaction: Transaction,
|
|
||||||
commitment: CommitmentLevel,
|
|
||||||
) -> transport::Result<()>;
|
|
||||||
|
|
||||||
/// Send a transaction and return after the transaction has been finalized or rejected.
|
|
||||||
async fn process_transaction(&mut self, transaction: Transaction) -> transport::Result<()>;
|
|
||||||
|
|
||||||
/// Return the status of a transaction with a signature matching the transaction's first
|
|
||||||
/// signature. Return None if the transaction is not found, which may be because the
|
|
||||||
/// blockhash was expired or the fee-paying account had insufficient funds to pay the
|
|
||||||
/// transaction fee. Note that servers rarely store the full transaction history. This
|
|
||||||
/// method may return None if the transaction status has been discarded.
|
|
||||||
async fn get_transaction_status(
|
|
||||||
&mut self,
|
|
||||||
signature: Signature,
|
|
||||||
) -> io::Result<Option<TransactionStatus>>;
|
|
||||||
|
|
||||||
/// Same as get_transaction_status, but for multiple transactions.
|
|
||||||
async fn get_transaction_statuses(
|
|
||||||
&mut self,
|
|
||||||
signatures: Vec<Signature>,
|
|
||||||
) -> io::Result<Vec<Option<TransactionStatus>>>;
|
|
||||||
|
|
||||||
/// Return the most recent rooted slot height. All transactions at or below this height
|
|
||||||
/// are said to be finalized. The cluster will not fork to a higher slot height.
|
|
||||||
async fn get_root_slot(&mut self) -> io::Result<Slot>;
|
|
||||||
|
|
||||||
/// Return the account at the given address at the slot corresponding to the given
|
|
||||||
/// commitment level. If the account is not found, None is returned.
|
|
||||||
async fn get_account_with_commitment(
|
|
||||||
&mut self,
|
|
||||||
address: Pubkey,
|
|
||||||
commitment: CommitmentLevel,
|
|
||||||
) -> io::Result<Option<Account>>;
|
|
||||||
|
|
||||||
/// Return the account at the given address at the time of the most recent root slot.
|
|
||||||
/// If the account is not found, None is returned.
|
|
||||||
async fn get_account(&mut self, address: Pubkey) -> io::Result<Option<Account>>;
|
|
||||||
|
|
||||||
/// Return the balance in lamports of an account at the given address at the slot
|
|
||||||
/// corresponding to the given commitment level.
|
|
||||||
async fn get_balance_with_commitment(
|
|
||||||
&mut self,
|
|
||||||
address: Pubkey,
|
|
||||||
commitment: CommitmentLevel,
|
|
||||||
) -> io::Result<u64>;
|
|
||||||
|
|
||||||
/// Return the balance in lamports of an account at the given address at the time
|
|
||||||
/// of the most recent root slot.
|
|
||||||
async fn get_balance(&mut self, address: Pubkey) -> io::Result<u64>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl BanksClientExt for BanksClient {
|
|
||||||
async fn send_transaction(&mut self, transaction: Transaction) -> io::Result<()> {
|
|
||||||
self.send_transaction_with_context(context::current(), transaction)
|
self.send_transaction_with_context(context::current(), transaction)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_fees(&mut self) -> io::Result<(FeeCalculator, Hash, Slot)> {
|
/// Return the fee parameters associated with a recent, rooted blockhash. The cluster
|
||||||
|
/// will use the transaction's blockhash to look up these same fee parameters and
|
||||||
|
/// use them to calculate the transaction fee.
|
||||||
|
pub async fn get_fees(&mut self) -> io::Result<(FeeCalculator, Hash, Slot)> {
|
||||||
self.get_fees_with_commitment_and_context(context::current(), CommitmentLevel::Root)
|
self.get_fees_with_commitment_and_context(context::current(), CommitmentLevel::Root)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_rent(&mut self) -> io::Result<Rent> {
|
/// Return the cluster rent
|
||||||
|
pub async fn get_rent(&mut self) -> io::Result<Rent> {
|
||||||
let rent_sysvar = self
|
let rent_sysvar = self
|
||||||
.get_account(sysvar::rent::id())
|
.get_account(sysvar::rent::id())
|
||||||
.await?
|
.await?
|
||||||
|
@ -130,11 +140,16 @@ impl BanksClientExt for BanksClient {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_recent_blockhash(&mut self) -> io::Result<Hash> {
|
/// Return a recent, rooted blockhash from the server. The cluster will only accept
|
||||||
|
/// transactions with a blockhash that has not yet expired. Use the `get_fees`
|
||||||
|
/// method to get both a blockhash and the blockhash's last valid slot.
|
||||||
|
pub async fn get_recent_blockhash(&mut self) -> io::Result<Hash> {
|
||||||
Ok(self.get_fees().await?.1)
|
Ok(self.get_fees().await?.1)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn process_transaction_with_commitment(
|
/// Send a transaction and return after the transaction has been rejected or
|
||||||
|
/// reached the given level of commitment.
|
||||||
|
pub async fn process_transaction_with_commitment(
|
||||||
&mut self,
|
&mut self,
|
||||||
transaction: Transaction,
|
transaction: Transaction,
|
||||||
commitment: CommitmentLevel,
|
commitment: CommitmentLevel,
|
||||||
|
@ -150,17 +165,22 @@ impl BanksClientExt for BanksClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn process_transaction(&mut self, transaction: Transaction) -> transport::Result<()> {
|
/// Send a transaction and return after the transaction has been finalized or rejected.
|
||||||
|
pub async fn process_transaction(&mut self, transaction: Transaction) -> transport::Result<()> {
|
||||||
self.process_transaction_with_commitment(transaction, CommitmentLevel::default())
|
self.process_transaction_with_commitment(transaction, CommitmentLevel::default())
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_root_slot(&mut self) -> io::Result<Slot> {
|
/// Return the most recent rooted slot height. All transactions at or below this height
|
||||||
|
/// are said to be finalized. The cluster will not fork to a higher slot height.
|
||||||
|
pub async fn get_root_slot(&mut self) -> io::Result<Slot> {
|
||||||
self.get_slot_with_context(context::current(), CommitmentLevel::Root)
|
self.get_slot_with_context(context::current(), CommitmentLevel::Root)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_account_with_commitment(
|
/// Return the account at the given address at the slot corresponding to the given
|
||||||
|
/// commitment level. If the account is not found, None is returned.
|
||||||
|
pub async fn get_account_with_commitment(
|
||||||
&mut self,
|
&mut self,
|
||||||
address: Pubkey,
|
address: Pubkey,
|
||||||
commitment: CommitmentLevel,
|
commitment: CommitmentLevel,
|
||||||
|
@ -169,12 +189,16 @@ impl BanksClientExt for BanksClient {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_account(&mut self, address: Pubkey) -> io::Result<Option<Account>> {
|
/// Return the account at the given address at the time of the most recent root slot.
|
||||||
|
/// If the account is not found, None is returned.
|
||||||
|
pub async fn get_account(&mut self, address: Pubkey) -> io::Result<Option<Account>> {
|
||||||
self.get_account_with_commitment(address, CommitmentLevel::default())
|
self.get_account_with_commitment(address, CommitmentLevel::default())
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_balance_with_commitment(
|
/// Return the balance in lamports of an account at the given address at the slot
|
||||||
|
/// corresponding to the given commitment level.
|
||||||
|
pub async fn get_balance_with_commitment(
|
||||||
&mut self,
|
&mut self,
|
||||||
address: Pubkey,
|
address: Pubkey,
|
||||||
commitment: CommitmentLevel,
|
commitment: CommitmentLevel,
|
||||||
|
@ -185,12 +209,19 @@ impl BanksClientExt for BanksClient {
|
||||||
Ok(account.map(|x| x.lamports).unwrap_or(0))
|
Ok(account.map(|x| x.lamports).unwrap_or(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_balance(&mut self, address: Pubkey) -> io::Result<u64> {
|
/// Return the balance in lamports of an account at the given address at the time
|
||||||
|
/// of the most recent root slot.
|
||||||
|
pub async fn get_balance(&mut self, address: Pubkey) -> io::Result<u64> {
|
||||||
self.get_balance_with_commitment(address, CommitmentLevel::default())
|
self.get_balance_with_commitment(address, CommitmentLevel::default())
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_transaction_status(
|
/// Return the status of a transaction with a signature matching the transaction's first
|
||||||
|
/// signature. Return None if the transaction is not found, which may be because the
|
||||||
|
/// blockhash was expired or the fee-paying account had insufficient funds to pay the
|
||||||
|
/// transaction fee. Note that servers rarely store the full transaction history. This
|
||||||
|
/// method may return None if the transaction status has been discarded.
|
||||||
|
pub async fn get_transaction_status(
|
||||||
&mut self,
|
&mut self,
|
||||||
signature: Signature,
|
signature: Signature,
|
||||||
) -> io::Result<Option<TransactionStatus>> {
|
) -> io::Result<Option<TransactionStatus>> {
|
||||||
|
@ -198,7 +229,8 @@ impl BanksClientExt for BanksClient {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_transaction_statuses(
|
/// Same as get_transaction_status, but for multiple transactions.
|
||||||
|
pub async fn get_transaction_statuses(
|
||||||
&mut self,
|
&mut self,
|
||||||
signatures: Vec<Signature>,
|
signatures: Vec<Signature>,
|
||||||
) -> io::Result<Vec<Option<TransactionStatus>>> {
|
) -> io::Result<Vec<Option<TransactionStatus>>> {
|
||||||
|
@ -219,15 +251,20 @@ impl BanksClientExt for BanksClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn start_client(
|
pub async fn start_client<C>(transport: C) -> io::Result<BanksClient>
|
||||||
transport: UnboundedChannel<Response<BanksResponse>, ClientMessage<BanksRequest>>,
|
where
|
||||||
) -> io::Result<BanksClient> {
|
C: Transport<ClientMessage<BanksRequest>, Response<BanksResponse>> + Send + 'static,
|
||||||
BanksClient::new(client::Config::default(), transport).spawn()
|
{
|
||||||
|
Ok(BanksClient {
|
||||||
|
inner: TarpcClient::new(client::Config::default(), transport).spawn()?,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn start_tcp_client<T: ToSocketAddrs>(addr: T) -> io::Result<BanksClient> {
|
pub async fn start_tcp_client<T: ToSocketAddrs>(addr: T) -> io::Result<BanksClient> {
|
||||||
let transport = tcp::connect(addr, Bincode::default).await?;
|
let transport = tcp::connect(addr, Bincode::default).await?;
|
||||||
BanksClient::new(client::Config::default(), transport).spawn()
|
Ok(BanksClient {
|
||||||
|
inner: TarpcClient::new(client::Config::default(), transport).spawn()?,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -264,8 +301,7 @@ mod tests {
|
||||||
|
|
||||||
Runtime::new()?.block_on(async {
|
Runtime::new()?.block_on(async {
|
||||||
let client_transport = start_local_server(&bank_forks).await;
|
let client_transport = start_local_server(&bank_forks).await;
|
||||||
let mut banks_client =
|
let mut banks_client = start_client(client_transport).await?;
|
||||||
BanksClient::new(client::Config::default(), client_transport).spawn()?;
|
|
||||||
|
|
||||||
let recent_blockhash = banks_client.get_recent_blockhash().await?;
|
let recent_blockhash = banks_client.get_recent_blockhash().await?;
|
||||||
let transaction = Transaction::new(&[&genesis.mint_keypair], message, recent_blockhash);
|
let transaction = Transaction::new(&[&genesis.mint_keypair], message, recent_blockhash);
|
||||||
|
@ -293,8 +329,7 @@ mod tests {
|
||||||
|
|
||||||
Runtime::new()?.block_on(async {
|
Runtime::new()?.block_on(async {
|
||||||
let client_transport = start_local_server(&bank_forks).await;
|
let client_transport = start_local_server(&bank_forks).await;
|
||||||
let mut banks_client =
|
let mut banks_client = start_client(client_transport).await?;
|
||||||
BanksClient::new(client::Config::default(), client_transport).spawn()?;
|
|
||||||
let (_, recent_blockhash, last_valid_slot) = banks_client.get_fees().await?;
|
let (_, recent_blockhash, last_valid_slot) = banks_client.get_fees().await?;
|
||||||
let transaction = Transaction::new(&[&genesis.mint_keypair], message, recent_blockhash);
|
let transaction = Transaction::new(&[&genesis.mint_keypair], message, recent_blockhash);
|
||||||
let signature = transaction.signatures[0];
|
let signature = transaction.signatures[0];
|
||||||
|
|
|
@ -7,7 +7,7 @@ use indexmap::IndexMap;
|
||||||
use indicatif::{ProgressBar, ProgressStyle};
|
use indicatif::{ProgressBar, ProgressStyle};
|
||||||
use pickledb::PickleDb;
|
use pickledb::PickleDb;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use solana_banks_client::{BanksClient, BanksClientExt};
|
use solana_banks_client::BanksClient;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
commitment_config::CommitmentLevel,
|
commitment_config::CommitmentLevel,
|
||||||
instruction::Instruction,
|
instruction::Instruction,
|
||||||
|
|
Loading…
Reference in New Issue