Skip to content

Commit

Permalink
Remove wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
garious committed Jun 26, 2020
1 parent f70bf79 commit 9e6224c
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 146 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

84 changes: 40 additions & 44 deletions runtime/src/banks_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use futures::{
prelude::stream,
};
use solana_sdk::{
banks_client::{BanksClient, BanksRpc, BanksRpcClient},
banks_client::{Banks, BanksClient},
clock::Slot,
fee_calculator::FeeCalculator,
hash::Hash,
Expand Down Expand Up @@ -90,13 +90,13 @@ async fn poll_transaction_status(
status
}

impl BanksRpc for BanksServer {
type GetRecentBlockhashFut = Ready<(Hash, FeeCalculator, Slot)>;
fn get_recent_blockhash(self, _: Context) -> Self::GetRecentBlockhashFut {
impl Banks for BanksServer {
type GetFeesFut = Ready<(FeeCalculator, Hash, Slot)>;
fn get_fees(self, _: Context) -> Self::GetFeesFut {
let bank = self.bank_forks.root_bank();
let (blockhash, fee_calculator) = bank.last_blockhash_with_fee_calculator();
let last_valid_slot = bank.get_blockhash_last_valid_slot(&blockhash).unwrap();
future::ready((blockhash, fee_calculator, last_valid_slot))
future::ready((fee_calculator, blockhash, last_valid_slot))
}

type SendTransactionFut = Ready<()>;
Expand Down Expand Up @@ -150,16 +150,16 @@ pub fn start_local_server(
.respond_with(banks_server.serve());
runtime.spawn(server);

let banks_rpc_client = BanksRpcClient::new(client::Config::default(), client_transport);
let rpc_client = runtime.enter(|| banks_rpc_client.spawn())?;
Ok(BanksClient::new(rpc_client))
let banks_client = BanksClient::new(client::Config::default(), client_transport);
runtime.enter(|| banks_client.spawn())
}

#[cfg(test)]
mod tests {
use super::*;
use crate::genesis_utils::create_genesis_config;
use solana_sdk::{message::Message, pubkey::Pubkey, signature::Signer, system_instruction};
use tarpc::context;

#[test]
fn test_banks_server_transfer_via_server() -> io::Result<()> {
Expand All @@ -173,13 +173,23 @@ mod tests {
let mut banks_client = start_local_server(&mut runtime, &bank_forks)?;

let bob_pubkey = Pubkey::new_rand();
let mint_pubkey = genesis.mint_keypair.pubkey();
let instruction = system_instruction::transfer(&mint_pubkey, &bob_pubkey, 1);
let message = Message::new(&[instruction], Some(&mint_pubkey));

runtime.block_on(async {
let (_transaction, status) = banks_client
.transfer_and_confirm(&genesis.mint_keypair, &bob_pubkey, 1)
let recent_blockhash = banks_client.get_fees(context::current()).await?.1;
let transaction = Transaction::new(&[&genesis.mint_keypair], message, recent_blockhash);
let status = banks_client
.send_and_confirm_transaction(context::current(), transaction)
.await?;
assert_eq!(status, Some(Ok(())));
assert_eq!(banks_client.get_balance(&bob_pubkey).await?, 1);
assert_eq!(
banks_client
.get_balance(context::current(), bob_pubkey)
.await?,
1
);
Ok(())
})
}
Expand All @@ -201,51 +211,37 @@ mod tests {
let message = Message::new(&[instruction], Some(&mint_pubkey));

runtime.block_on(async {
let (transaction, last_valid_slot, send_transaction) = banks_client
.send_message(&[&genesis.mint_keypair], message)
.await?;
let (_, recent_blockhash, last_valid_slot) =
banks_client.get_fees(context::current()).await?;
let transaction = Transaction::new(&[&genesis.mint_keypair], message, recent_blockhash);
let signature = transaction.signatures[0];
banks_client
.send_transaction(context::current(), transaction)
.await?;

// Now that we've recorded the signature, go ahead and send the transaction.
send_transaction.await?;

let mut status = banks_client.get_signature_status(&signature).await?;
let mut status = banks_client
.get_signature_status(context::current(), signature)
.await?;
assert_eq!(status, None, "process_transaction() called synchronously");

while status.is_none() {
let root_slot = banks_client.get_root_slot().await?;
let root_slot = banks_client.get_root_slot(context::current()).await?;
if root_slot > last_valid_slot {
break;
}
delay_for(Duration::from_millis(100)).await;
status = banks_client.get_signature_status(&signature).await?;
status = banks_client
.get_signature_status(context::current(), signature)
.await?;
}
assert_eq!(status, Some(Ok(())));
assert_eq!(banks_client.get_balance(&bob_pubkey).await?, 1);
assert_eq!(
banks_client
.get_balance(context::current(), bob_pubkey)
.await?,
1
);
Ok(())
})
}

#[test]
fn test_banks_server_transfer_via_blocking_call() -> io::Result<()> {
// This test shows how `runtime.block_on()` could be used to implement
// a fully synchronous interface. Ideally, you'd only use this as a shim
// to replace some existing synchronous interface.

let genesis = create_genesis_config(10);
let bank_forks = Arc::new(BankForks::new(Bank::new(&genesis.genesis_config)));

let mut runtime = Runtime::new()?;
let mut banks_client = start_local_server(&mut runtime, &bank_forks)?;

let bob_pubkey = Pubkey::new_rand();
let (_transaction, status) = runtime.block_on(banks_client.transfer_and_confirm(
&genesis.mint_keypair,
&bob_pubkey,
1,
))?;
assert_eq!(status, Some(Ok(())));
assert_eq!(runtime.block_on(banks_client.get_balance(&bob_pubkey))?, 1);
Ok(())
}
}
2 changes: 0 additions & 2 deletions sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ default = [
"assert_matches",
"byteorder",
"chrono",
"futures",
"generic-array",
"memmap",
"rand",
Expand All @@ -35,7 +34,6 @@ bs58 = "0.3.1"
bv = { version = "0.11.1", features = ["serde"] }
byteorder = { version = "1.3.4", optional = true }
chrono = { version = "0.4", optional = true }
futures = { version = "0.3", optional = true }
generic-array = { version = "0.14.1", default-features = false, features = ["serde", "more_lengths"], optional = true }
hex = "0.4.2"
hmac = "0.7.0"
Expand Down
104 changes: 5 additions & 99 deletions sdk/src/banks_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,14 @@ use crate::{
clock::Slot,
fee_calculator::FeeCalculator,
hash::Hash,
message::Message,
pubkey::Pubkey,
signature::{Keypair, Signature, Signer},
signers::Signers,
system_instruction,
signature::Signature,
transaction::{self, Transaction},
};
use futures::Future;
use std::io;
use tarpc::context;

#[tarpc::service]
pub trait BanksRpc {
async fn get_recent_blockhash() -> (Hash, FeeCalculator, Slot);
pub trait Banks {
async fn get_fees() -> (FeeCalculator, Hash, Slot);
async fn send_transaction(transaction: Transaction);
async fn get_signature_status(signature: Signature) -> Option<transaction::Result<()>>;
async fn get_root_slot() -> Slot;
Expand All @@ -25,102 +19,14 @@ pub trait BanksRpc {
async fn get_balance(pubkey: Pubkey) -> u64;
}

pub struct BanksClient {
rpc_client: BanksRpcClient,
}

impl BanksClient {
pub fn new(rpc_client: BanksRpcClient) -> Self {
Self { rpc_client }
}

pub async fn get_recent_blockhash(&mut self) -> io::Result<(Hash, FeeCalculator, Slot)> {
self.rpc_client
.get_recent_blockhash(context::current())
.await
}

pub async fn create_transaction<S: Signers>(
&mut self,
signers: &S,
message: Message,
) -> io::Result<(Transaction, Slot)> {
let (recent_blockhash, _fee_calculator, last_valid_slot) =
self.get_recent_blockhash().await?;
let transaction = Transaction::new(signers, message, recent_blockhash);
Ok((transaction, last_valid_slot))
}

pub async fn send_transaction(&mut self, transaction: Transaction) -> io::Result<()> {
self.rpc_client
.send_transaction(context::current(), transaction)
.await
}

pub async fn send_message<'a, S: Signers>(
&'a mut self,
signers: &S,
message: Message,
) -> io::Result<(Transaction, u64, impl Future<Output = io::Result<()>> + 'a)> {
let (transaction, last_valid_slot) = self.create_transaction(signers, message).await?;
let send_transaction = self.send_transaction(transaction.clone());
Ok((transaction, last_valid_slot, send_transaction))
}

pub async fn send_and_confirm_message<S: Signers>(
&mut self,
signers: &S,
message: Message,
) -> io::Result<(Transaction, Option<transaction::Result<()>>)> {
let (transaction, _last_valid_slot) = self.create_transaction(signers, message).await?;
let result = self
.rpc_client
.send_and_confirm_transaction(context::current(), transaction.clone())
.await?;
Ok((transaction, result))
}

pub async fn transfer_and_confirm(
&mut self,
from_keypair: &Keypair,
to_pubkey: &Pubkey,
lamports: u64,
) -> io::Result<(Transaction, Option<transaction::Result<()>>)> {
let from_pubkey = from_keypair.pubkey();
let instruction = system_instruction::transfer(&from_pubkey, &to_pubkey, lamports);
let message = Message::new(&[instruction], Some(&from_pubkey));
self.send_and_confirm_message(&[from_keypair], message)
.await
}

pub async fn get_balance(&mut self, pubkey: &Pubkey) -> io::Result<u64> {
self.rpc_client
.get_balance(context::current(), *pubkey)
.await
}

pub async fn get_signature_status(
&mut self,
signature: &Signature,
) -> io::Result<Option<transaction::Result<()>>> {
self.rpc_client
.get_signature_status(context::current(), *signature)
.await
}

pub async fn get_root_slot(&mut self) -> io::Result<u64> {
self.rpc_client.get_root_slot(context::current()).await
}
}

#[cfg(test)]
mod tests {
use super::*;
use tarpc::{client, transport};

#[test]
fn test_banks_rpc_client_new() {
fn test_banks_client_new() {
let (client_transport, _server_transport) = transport::channel::unbounded();
BanksRpcClient::new(client::Config::default(), client_transport);
BanksClient::new(client::Config::default(), client_transport);
}
}

0 comments on commit 9e6224c

Please sign in to comment.