Skip to content

Commit

Permalink
Add CommitmentLevel variants
Browse files Browse the repository at this point in the history
  • Loading branch information
garious committed Jul 7, 2020
1 parent b31f1d7 commit 7ba3d79
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 24 deletions.
62 changes: 47 additions & 15 deletions runtime/src/banks_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use solana_sdk::{
account::Account,
banks_client::{start_tcp_client, Banks, BanksClient},
clock::Slot,
commitment_config::CommitmentLevel,
fee_calculator::FeeCalculator,
hash::Hash,
pubkey::Pubkey,
Expand Down Expand Up @@ -73,29 +74,51 @@ impl BanksService {
.unwrap();
Self::new_with_sender(bank_forks, transaction_sender)
}

fn slot(&self, commitment: CommitmentLevel) -> Slot {
match commitment {
CommitmentLevel::Recent => self.bank_forks.highest_slot(),
CommitmentLevel::Root => self.bank_forks.root(),
CommitmentLevel::Single | CommitmentLevel::SingleGossip => {
//TODO: self.block_commitment_cache.highest_confirmed_slot()
todo!();
}
CommitmentLevel::Max => {
//TODO: self.block_commitment_cache.largest_confirmed_root()
self.bank_forks.root()
}
}
}

fn bank(&self, commitment: CommitmentLevel) -> &Arc<Bank> {
&self.bank_forks[self.slot(commitment)]
}
}

async fn poll_transaction_status(
root_bank: Arc<Bank>,
bank: Arc<Bank>,
signature: Signature,
last_valid_slot: Slot,
) -> Option<transaction::Result<()>> {
let mut status = root_bank.get_signature_status(&signature);
let mut status = bank.get_signature_status(&signature);
while status.is_none() {
let root_slot = root_bank.slot();
if root_slot > last_valid_slot {
if bank.slot() > last_valid_slot {
break;
}
delay_for(Duration::from_millis(100)).await;
status = root_bank.get_signature_status(&signature);
status = bank.get_signature_status(&signature);
}
status
}

#[tarpc::server]
impl Banks for BanksService {
async fn get_fees(self, _: Context) -> (FeeCalculator, Hash, Slot) {
let bank = self.bank_forks.root_bank();
async fn get_fees_with_commitment(
self,
_: Context,
commitment: CommitmentLevel,
) -> (FeeCalculator, Hash, Slot) {
let bank = self.bank(commitment);
let (blockhash, fee_calculator) = bank.last_blockhash_with_fee_calculator();
let last_valid_slot = bank.get_blockhash_last_valid_slot(&blockhash).unwrap();
(fee_calculator, blockhash, last_valid_slot)
Expand All @@ -105,45 +128,54 @@ impl Banks for BanksService {
self.transaction_sender.send(transaction).unwrap();
}

async fn get_signature_status(
async fn get_signature_status_with_commitment(
self,
_: Context,
signature: Signature,
commitment: CommitmentLevel,
) -> Option<transaction::Result<()>> {
let bank = self.bank_forks.root_bank();
let bank = self.bank(commitment);
bank.get_signature_status(&signature)
}

async fn get_signature_statuses(
async fn get_signature_statuses_with_commitment(
self,
_: Context,
signatures: Vec<Signature>,
commitment: CommitmentLevel,
) -> Vec<Option<transaction::Result<()>>> {
let bank = self.bank_forks.root_bank();
let bank = self.bank(commitment);
signatures
.iter()
.map(|x| bank.get_signature_status(x))
.collect()
}

async fn get_root_slot(self, _: Context) -> Slot {
self.bank_forks.root()
async fn get_slot(self, _: Context, commitment: CommitmentLevel) -> Slot {
self.slot(commitment)
}

async fn send_and_confirm_transaction(
self,
_: Context,
transaction: Transaction,
commitment: CommitmentLevel,
) -> Option<transaction::Result<()>> {
let blockhash = &transaction.message.recent_blockhash;
let root_bank = self.bank_forks.root_bank();
let last_valid_slot = root_bank.get_blockhash_last_valid_slot(&blockhash).unwrap();
let signature = transaction.signatures.get(0).cloned().unwrap_or_default();
self.transaction_sender.send(transaction).unwrap();
poll_transaction_status(root_bank.clone(), signature, last_valid_slot).await
let bank = self.bank(commitment).clone();
poll_transaction_status(bank, signature, last_valid_slot).await
}

async fn get_account(self, _: Context, pubkey: Pubkey) -> Option<Account> {
async fn get_account_with_commitment(
self,
_: Context,
pubkey: Pubkey,
_commitment: CommitmentLevel,
) -> Option<Account> {
let bank = self.bank_forks.root_bank();
bank.get_account(&pubkey)
}
Expand Down
110 changes: 101 additions & 9 deletions sdk/src/banks_client.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
account::Account,
clock::Slot,
commitment_config::CommitmentLevel,
fee_calculator::FeeCalculator,
hash::Hash,
pubkey::Pubkey,
Expand All @@ -16,54 +17,145 @@ use tokio_serde::formats::Bincode;

#[tarpc::service]
pub trait Banks {
async fn get_fees() -> (FeeCalculator, Hash, Slot);
async fn get_fees_with_commitment(commitement: CommitmentLevel) -> (FeeCalculator, Hash, Slot);
async fn send_transaction(transaction: Transaction);
async fn get_signature_status(signature: Signature) -> Option<transaction::Result<()>>;
async fn get_signature_statuses(
async fn get_signature_status_with_commitment(
signature: Signature,
commitement: CommitmentLevel,
) -> Option<transaction::Result<()>>;
async fn get_signature_statuses_with_commitment(
signatures: Vec<Signature>,
commitment: CommitmentLevel,
) -> Vec<Option<transaction::Result<()>>>;
async fn get_root_slot() -> Slot;
async fn get_slot(commitment: CommitmentLevel) -> Slot;
async fn send_and_confirm_transaction(
transaction: Transaction,
commitment: CommitmentLevel,
) -> Option<transaction::Result<()>>;
async fn get_account(pubkey: Pubkey) -> Option<Account>;
async fn get_account_with_commitment(
pubkey: Pubkey,
commitment: CommitmentLevel,
) -> Option<Account>;
}

#[async_trait]
pub trait BanksClientExt {
async fn get_recent_blockhash(&mut self, _: Context) -> io::Result<Hash>;
async fn process_transaction_with_commitment(
&mut self,
_: Context,
transaction: Transaction,
commitment: CommitmentLevel,
) -> transport::Result<()>;
async fn process_transaction(
&mut self,
_: Context,
transaction: Transaction,
) -> transport::Result<()>;
async fn get_fees(&mut self, _: Context) -> io::Result<(FeeCalculator, Hash, Slot)>;
async fn get_signature_status(
&mut self,
_: Context,
signature: Signature,
) -> io::Result<Option<transaction::Result<()>>>;
async fn get_signature_statuses(
&mut self,
_: Context,
signatures: Vec<Signature>,
) -> io::Result<Vec<Option<transaction::Result<()>>>>;
async fn get_root_slot(&mut self, _: Context) -> io::Result<Slot>;
async fn get_account(&mut self, _: Context, pubkey: Pubkey) -> io::Result<Option<Account>>;
async fn get_balance_with_commitment(
&mut self,
_: Context,
pubkey: Pubkey,
commitment: CommitmentLevel,
) -> io::Result<u64>;
async fn get_balance(&mut self, _: Context, pubkey: Pubkey) -> io::Result<u64>;
}

#[async_trait]
impl BanksClientExt for BanksClient {
async fn get_fees(&mut self, context: Context) -> io::Result<(FeeCalculator, Hash, Slot)> {
self.get_fees_with_commitment(context, CommitmentLevel::Root)
.await
}

async fn get_recent_blockhash(&mut self, context: Context) -> io::Result<Hash> {
Ok(self.get_fees(context).await?.1)
}

async fn process_transaction(
async fn process_transaction_with_commitment(
&mut self,
context: Context,
transaction: Transaction,
commitment: CommitmentLevel,
) -> transport::Result<()> {
let result = self
.send_and_confirm_transaction(context, transaction)
.send_and_confirm_transaction(context, transaction, commitment)
.await?;
match result {
None => Err(Error::new(ErrorKind::TimedOut, "invalid blockhash or fee-payer").into()),
Some(transaction_result) => Ok(transaction_result?),
}
}

async fn get_balance(&mut self, context: Context, pubkey: Pubkey) -> io::Result<u64> {
let account = self.get_account(context, pubkey).await?;
async fn process_transaction(
&mut self,
context: Context,
transaction: Transaction,
) -> transport::Result<()> {
self.process_transaction_with_commitment(context, transaction, CommitmentLevel::default())
.await
}

async fn get_root_slot(&mut self, context: Context) -> io::Result<Slot> {
self.get_slot(context, CommitmentLevel::Root).await
}

async fn get_account(
&mut self,
context: Context,
pubkey: Pubkey,
) -> io::Result<Option<Account>> {
self.get_account_with_commitment(context, pubkey, CommitmentLevel::default())
.await
}

async fn get_balance_with_commitment(
&mut self,
context: Context,
pubkey: Pubkey,
commitment: CommitmentLevel,
) -> io::Result<u64> {
let account = self
.get_account_with_commitment(context, pubkey, commitment)
.await?;
Ok(account.map(|x| x.lamports).unwrap_or(0))
}

async fn get_balance(&mut self, context: Context, pubkey: Pubkey) -> io::Result<u64> {
self.get_balance_with_commitment(context, pubkey, CommitmentLevel::default())
.await
}

async fn get_signature_status(
&mut self,
context: Context,
signature: Signature,
) -> io::Result<Option<transaction::Result<()>>> {
self.get_signature_status_with_commitment(context, signature, CommitmentLevel::default())
.await
}

async fn get_signature_statuses(
&mut self,
context: Context,
signatures: Vec<Signature>,
) -> io::Result<Vec<Option<transaction::Result<()>>>> {
self.get_signature_statuses_with_commitment(context, signatures, CommitmentLevel::default())
.await
}
}

pub async fn start_tcp_client<T: ToSocketAddrs>(addr: T) -> io::Result<BanksClient> {
Expand Down

0 comments on commit 7ba3d79

Please sign in to comment.