Wrap all client errors with TransportError
This commit is contained in:
parent
167f5bdc58
commit
1598a02a7a
@ -172,7 +172,7 @@ mod tests {
|
||||
bank_client
|
||||
.send_message(&[&alice_keypair], message)
|
||||
.unwrap();
|
||||
assert_eq!(bank_client.get_balance(&bob_pubkey), 100);
|
||||
assert_eq!(bank_client.get_balance(&bob_pubkey).unwrap(), 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -214,11 +214,11 @@ mod tests {
|
||||
|
||||
// Ensure the transaction fails because of the unsigned key.
|
||||
assert_eq!(
|
||||
bank_client.send_message(&[&mallory_keypair], message),
|
||||
Err(TransactionError::InstructionError(
|
||||
0,
|
||||
InstructionError::MissingRequiredSignature
|
||||
))
|
||||
bank_client
|
||||
.send_message(&[&mallory_keypair], message)
|
||||
.unwrap_err()
|
||||
.unwrap(),
|
||||
TransactionError::InstructionError(0, InstructionError::MissingRequiredSignature)
|
||||
);
|
||||
}
|
||||
|
||||
@ -262,11 +262,11 @@ mod tests {
|
||||
|
||||
// Ensure the transaction fails because of the unsigned key.
|
||||
assert_eq!(
|
||||
bank_client.send_message(&[&mallory_keypair], message),
|
||||
Err(TransactionError::InstructionError(
|
||||
0,
|
||||
InstructionError::MissingRequiredSignature
|
||||
))
|
||||
bank_client
|
||||
.send_message(&[&mallory_keypair], message)
|
||||
.unwrap_err()
|
||||
.unwrap(),
|
||||
TransactionError::InstructionError(0, InstructionError::MissingRequiredSignature)
|
||||
);
|
||||
}
|
||||
|
||||
@ -292,10 +292,13 @@ mod tests {
|
||||
bank_client
|
||||
.send_message(&[&alice_keypair], message)
|
||||
.unwrap();
|
||||
assert_eq!(bank_client.get_balance(&alice_pubkey), 1);
|
||||
assert_eq!(bank_client.get_balance(&budget_pubkey), 1);
|
||||
assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 1);
|
||||
assert_eq!(bank_client.get_balance(&budget_pubkey).unwrap(), 1);
|
||||
|
||||
let contract_account = bank_client.get_account_data(&budget_pubkey).unwrap();
|
||||
let contract_account = bank_client
|
||||
.get_account_data(&budget_pubkey)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let budget_state = BudgetState::deserialize(&contract_account).unwrap();
|
||||
assert!(budget_state.is_pending());
|
||||
|
||||
@ -305,17 +308,21 @@ mod tests {
|
||||
assert_eq!(
|
||||
bank_client
|
||||
.send_instruction(&alice_keypair, instruction)
|
||||
.unwrap_err(),
|
||||
.unwrap_err()
|
||||
.unwrap(),
|
||||
TransactionError::InstructionError(
|
||||
0,
|
||||
InstructionError::CustomError(serialize(&BudgetError::DestinationMissing).unwrap())
|
||||
)
|
||||
);
|
||||
assert_eq!(bank_client.get_balance(&alice_pubkey), 1);
|
||||
assert_eq!(bank_client.get_balance(&budget_pubkey), 1);
|
||||
assert_eq!(bank_client.get_balance(&bob_pubkey), 0);
|
||||
assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 1);
|
||||
assert_eq!(bank_client.get_balance(&budget_pubkey).unwrap(), 1);
|
||||
assert_eq!(bank_client.get_balance(&bob_pubkey).unwrap(), 0);
|
||||
|
||||
let contract_account = bank_client.get_account_data(&budget_pubkey).unwrap();
|
||||
let contract_account = bank_client
|
||||
.get_account_data(&budget_pubkey)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let budget_state = BudgetState::deserialize(&contract_account).unwrap();
|
||||
assert!(budget_state.is_pending());
|
||||
|
||||
@ -326,10 +333,10 @@ mod tests {
|
||||
bank_client
|
||||
.send_instruction(&alice_keypair, instruction)
|
||||
.unwrap();
|
||||
assert_eq!(bank_client.get_balance(&alice_pubkey), 1);
|
||||
assert_eq!(bank_client.get_balance(&budget_pubkey), 0);
|
||||
assert_eq!(bank_client.get_balance(&bob_pubkey), 1);
|
||||
assert_eq!(bank_client.get_account_data(&budget_pubkey), None);
|
||||
assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 1);
|
||||
assert_eq!(bank_client.get_balance(&budget_pubkey).unwrap(), 0);
|
||||
assert_eq!(bank_client.get_balance(&bob_pubkey).unwrap(), 1);
|
||||
assert_eq!(bank_client.get_account_data(&budget_pubkey).unwrap(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -354,10 +361,13 @@ mod tests {
|
||||
bank_client
|
||||
.send_message(&[&alice_keypair], message)
|
||||
.unwrap();
|
||||
assert_eq!(bank_client.get_balance(&alice_pubkey), 2);
|
||||
assert_eq!(bank_client.get_balance(&budget_pubkey), 1);
|
||||
assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 2);
|
||||
assert_eq!(bank_client.get_balance(&budget_pubkey).unwrap(), 1);
|
||||
|
||||
let contract_account = bank_client.get_account_data(&budget_pubkey).unwrap();
|
||||
let contract_account = bank_client
|
||||
.get_account_data(&budget_pubkey)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let budget_state = BudgetState::deserialize(&contract_account).unwrap();
|
||||
assert!(budget_state.is_pending());
|
||||
|
||||
@ -367,7 +377,7 @@ mod tests {
|
||||
bank_client
|
||||
.transfer(1, &alice_keypair, &mallory_pubkey)
|
||||
.unwrap();
|
||||
assert_eq!(bank_client.get_balance(&alice_pubkey), 1);
|
||||
assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 1);
|
||||
|
||||
let instruction =
|
||||
budget_instruction::apply_signature(&mallory_pubkey, &budget_pubkey, &bob_pubkey);
|
||||
@ -375,9 +385,9 @@ mod tests {
|
||||
.send_instruction(&mallory_keypair, instruction)
|
||||
.unwrap();
|
||||
// nothing should be changed because apply witness didn't finalize a payment
|
||||
assert_eq!(bank_client.get_balance(&alice_pubkey), 1);
|
||||
assert_eq!(bank_client.get_balance(&budget_pubkey), 1);
|
||||
assert_eq!(bank_client.get_account_data(&bob_pubkey), None);
|
||||
assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 1);
|
||||
assert_eq!(bank_client.get_balance(&budget_pubkey).unwrap(), 1);
|
||||
assert_eq!(bank_client.get_account_data(&bob_pubkey).unwrap(), None);
|
||||
|
||||
// Now, cancel the transaction. mint gets her funds back
|
||||
let instruction =
|
||||
@ -385,8 +395,8 @@ mod tests {
|
||||
bank_client
|
||||
.send_instruction(&alice_keypair, instruction)
|
||||
.unwrap();
|
||||
assert_eq!(bank_client.get_balance(&alice_pubkey), 2);
|
||||
assert_eq!(bank_client.get_account_data(&budget_pubkey), None);
|
||||
assert_eq!(bank_client.get_account_data(&bob_pubkey), None);
|
||||
assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 2);
|
||||
assert_eq!(bank_client.get_account_data(&budget_pubkey).unwrap(), None);
|
||||
assert_eq!(bank_client.get_account_data(&bob_pubkey).unwrap(), None);
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,10 @@ mod tests {
|
||||
.send_message(&[&from_keypair, &config_keypair], message)
|
||||
.unwrap();
|
||||
|
||||
let config_account_data = bank_client.get_account_data(&config_pubkey).unwrap();
|
||||
let config_account_data = bank_client
|
||||
.get_account_data(&config_pubkey)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
my_config,
|
||||
MyConfig::deserialize(&config_account_data).unwrap()
|
||||
|
@ -652,7 +652,7 @@ mod test {
|
||||
let (client, owner) = create_client(&bank, mint_keypair);
|
||||
|
||||
let new = create_token_account(&client, &owner);
|
||||
let new_account_data = client.get_account_data(&new).unwrap();
|
||||
let new_account_data = client.get_account_data(&new).unwrap().unwrap();
|
||||
|
||||
// Check results
|
||||
|
||||
@ -691,7 +691,7 @@ mod test {
|
||||
.send_instruction(&owner, instruction)
|
||||
.expect(&format!("{}:{}", line!(), file!()));
|
||||
|
||||
let new_account_data = client.get_account_data(&new).unwrap();
|
||||
let new_account_data = client.get_account_data(&new).unwrap().unwrap();
|
||||
|
||||
// Check results
|
||||
|
||||
@ -720,9 +720,9 @@ mod test {
|
||||
1000,
|
||||
);
|
||||
|
||||
let trade_account_data = client.get_account_data(&trade).unwrap();
|
||||
let src_account_data = client.get_account_data(&src).unwrap();
|
||||
let dst_account_data = client.get_account_data(&dst).unwrap();
|
||||
let trade_account_data = client.get_account_data(&trade).unwrap().unwrap();
|
||||
let src_account_data = client.get_account_data(&src).unwrap().unwrap();
|
||||
let dst_account_data = client.get_account_data(&dst).unwrap().unwrap();
|
||||
|
||||
// check results
|
||||
|
||||
@ -794,14 +794,14 @@ mod test {
|
||||
.send_instruction(&owner, instruction)
|
||||
.expect(&format!("{}:{}", line!(), file!()));
|
||||
|
||||
let to_trade_account_data = client.get_account_data(&to_trade).unwrap();
|
||||
let to_src_account_data = client.get_account_data(&to_src).unwrap();
|
||||
let to_dst_account_data = client.get_account_data(&to_dst).unwrap();
|
||||
let from_trade_account_data = client.get_account_data(&from_trade).unwrap();
|
||||
let from_src_account_data = client.get_account_data(&from_src).unwrap();
|
||||
let from_dst_account_data = client.get_account_data(&from_dst).unwrap();
|
||||
let profit_account_data = client.get_account_data(&profit).unwrap();
|
||||
let swap_account_data = client.get_account_data(&swap).unwrap();
|
||||
let to_trade_account_data = client.get_account_data(&to_trade).unwrap().unwrap();
|
||||
let to_src_account_data = client.get_account_data(&to_src).unwrap().unwrap();
|
||||
let to_dst_account_data = client.get_account_data(&to_dst).unwrap().unwrap();
|
||||
let from_trade_account_data = client.get_account_data(&from_trade).unwrap().unwrap();
|
||||
let from_src_account_data = client.get_account_data(&from_src).unwrap().unwrap();
|
||||
let from_dst_account_data = client.get_account_data(&from_dst).unwrap().unwrap();
|
||||
let profit_account_data = client.get_account_data(&profit).unwrap().unwrap();
|
||||
let swap_account_data = client.get_account_data(&swap).unwrap().unwrap();
|
||||
|
||||
// check results
|
||||
|
||||
|
@ -20,10 +20,10 @@ fn test_program_native_failure() {
|
||||
// Call user program
|
||||
let instruction = create_invoke_instruction(alice_keypair.pubkey(), program_id, &1u8);
|
||||
assert_eq!(
|
||||
bank_client.send_instruction(&alice_keypair, instruction),
|
||||
Err(TransactionError::InstructionError(
|
||||
0,
|
||||
InstructionError::GenericError
|
||||
))
|
||||
bank_client
|
||||
.send_instruction(&alice_keypair, instruction)
|
||||
.unwrap_err()
|
||||
.unwrap(),
|
||||
TransactionError::InstructionError(0, InstructionError::GenericError)
|
||||
);
|
||||
}
|
||||
|
@ -557,7 +557,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn get_storage_entry_height<C: SyncClient>(client: &C, account: &Pubkey) -> u64 {
|
||||
match client.get_account_data(&account) {
|
||||
match client.get_account_data(&account).unwrap() {
|
||||
Some(storage_system_account_data) => {
|
||||
let contract = deserialize(&storage_system_account_data);
|
||||
if let Ok(contract) = contract {
|
||||
@ -577,7 +577,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn get_storage_blockhash<C: SyncClient>(client: &C, account: &Pubkey) -> Hash {
|
||||
if let Some(storage_system_account_data) = client.get_account_data(&account) {
|
||||
if let Some(storage_system_account_data) = client.get_account_data(&account).unwrap() {
|
||||
let contract = deserialize(&storage_system_account_data);
|
||||
if let Ok(contract) = contract {
|
||||
match contract {
|
||||
|
@ -73,7 +73,9 @@ mod tests {
|
||||
) -> Result<()> {
|
||||
let ixs = vote_instruction::create_account(&from_keypair.pubkey(), vote_id, lamports);
|
||||
let message = Message::new(ixs);
|
||||
bank_client.send_message(&[from_keypair], message)?;
|
||||
bank_client
|
||||
.send_message(&[from_keypair], message)
|
||||
.map_err(|err| err.unwrap())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -89,7 +91,9 @@ mod tests {
|
||||
let delegate_ix = vote_instruction::delegate_stake(&vote_id, delegate_id);
|
||||
ixs.push(delegate_ix);
|
||||
let message = Message::new(ixs);
|
||||
bank_client.send_message(&[&from_keypair, vote_keypair], message)?;
|
||||
bank_client
|
||||
.send_message(&[from_keypair, vote_keypair], message)
|
||||
.map_err(|err| err.unwrap())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -99,7 +103,9 @@ mod tests {
|
||||
tick_height: u64,
|
||||
) -> Result<()> {
|
||||
let vote_ix = vote_instruction::vote(&vote_keypair.pubkey(), Vote::new(tick_height));
|
||||
bank_client.send_instruction(&vote_keypair, vote_ix)?;
|
||||
bank_client
|
||||
.send_instruction(vote_keypair, vote_ix)
|
||||
.map_err(|err| err.unwrap())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -114,7 +120,7 @@ mod tests {
|
||||
create_vote_account(&bank_client, &from_keypair, &vote_id, 100).unwrap();
|
||||
submit_vote(&bank_client, &vote_keypair, 0).unwrap();
|
||||
|
||||
let vote_account_data = bank_client.get_account_data(&vote_id).unwrap();
|
||||
let vote_account_data = bank_client.get_account_data(&vote_id).unwrap().unwrap();
|
||||
let vote_state = VoteState::deserialize(&vote_account_data).unwrap();
|
||||
assert_eq!(vote_state.votes.len(), 1);
|
||||
}
|
||||
@ -157,16 +163,13 @@ mod tests {
|
||||
let result = bank_client.send_message(&[&mallory_keypair], message);
|
||||
|
||||
// And ensure there's no vote.
|
||||
let vote_account_data = bank_client.get_account_data(&vote_id).unwrap();
|
||||
let vote_account_data = bank_client.get_account_data(&vote_id).unwrap().unwrap();
|
||||
let vote_state = VoteState::deserialize(&vote_account_data).unwrap();
|
||||
assert_eq!(vote_state.votes.len(), 0);
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
Err(TransactionError::InstructionError(
|
||||
1,
|
||||
InstructionError::InvalidArgument
|
||||
))
|
||||
result.unwrap_err().unwrap(),
|
||||
TransactionError::InstructionError(1, InstructionError::InvalidArgument)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -6,18 +6,15 @@ use solana_sdk::signature::Signature;
|
||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||
use solana_sdk::sync_client::SyncClient;
|
||||
use solana_sdk::system_instruction;
|
||||
use solana_sdk::transaction::{Transaction, TransactionError};
|
||||
use solana_sdk::transaction::Transaction;
|
||||
use solana_sdk::transport::Result;
|
||||
|
||||
pub struct BankClient<'a> {
|
||||
bank: &'a Bank,
|
||||
}
|
||||
|
||||
impl<'a> SyncClient for BankClient<'a> {
|
||||
fn send_message(
|
||||
&self,
|
||||
keypairs: &[&Keypair],
|
||||
message: Message,
|
||||
) -> Result<Signature, TransactionError> {
|
||||
fn send_message(&self, keypairs: &[&Keypair], message: Message) -> Result<Signature> {
|
||||
let blockhash = self.bank.last_blockhash();
|
||||
let transaction = Transaction::new(&keypairs, message, blockhash);
|
||||
self.bank.process_transaction(&transaction)?;
|
||||
@ -25,33 +22,23 @@ impl<'a> SyncClient for BankClient<'a> {
|
||||
}
|
||||
|
||||
/// Create and process a transaction from a single instruction.
|
||||
fn send_instruction(
|
||||
&self,
|
||||
keypair: &Keypair,
|
||||
instruction: Instruction,
|
||||
) -> Result<Signature, TransactionError> {
|
||||
fn send_instruction(&self, keypair: &Keypair, instruction: Instruction) -> Result<Signature> {
|
||||
let message = Message::new(vec![instruction]);
|
||||
self.send_message(&[keypair], message)
|
||||
}
|
||||
|
||||
/// Transfer `lamports` from `keypair` to `pubkey`
|
||||
fn transfer(
|
||||
&self,
|
||||
lamports: u64,
|
||||
keypair: &Keypair,
|
||||
pubkey: &Pubkey,
|
||||
) -> Result<Signature, TransactionError> {
|
||||
fn transfer(&self, lamports: u64, keypair: &Keypair, pubkey: &Pubkey) -> Result<Signature> {
|
||||
let move_instruction = system_instruction::transfer(&keypair.pubkey(), pubkey, lamports);
|
||||
self.send_instruction(keypair, move_instruction)
|
||||
}
|
||||
|
||||
fn get_account_data(&self, pubkey: &Pubkey) -> Option<Vec<u8>> {
|
||||
let account = self.bank.get_account(pubkey)?;
|
||||
Some(account.data)
|
||||
fn get_account_data(&self, pubkey: &Pubkey) -> Result<Option<Vec<u8>>> {
|
||||
Ok(self.bank.get_account(pubkey).map(|account| account.data))
|
||||
}
|
||||
|
||||
fn get_balance(&self, pubkey: &Pubkey) -> u64 {
|
||||
self.bank.get_balance(pubkey)
|
||||
fn get_balance(&self, pubkey: &Pubkey) -> Result<u64> {
|
||||
Ok(self.bank.get_balance(pubkey))
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,6 +73,6 @@ mod tests {
|
||||
|
||||
let message = Message::new(vec![move_instruction]);
|
||||
bank_client.send_message(&doe_keypairs, message).unwrap();
|
||||
assert_eq!(bank_client.get_balance(&bob_pubkey), 42);
|
||||
assert_eq!(bank_client.get_balance(&bob_pubkey).unwrap(), 42);
|
||||
}
|
||||
}
|
||||
|
@ -301,13 +301,13 @@ mod tests {
|
||||
account_metas,
|
||||
);
|
||||
assert_eq!(
|
||||
bank_client.send_instruction(&mallory_keypair, malicious_instruction),
|
||||
Err(TransactionError::InstructionError(
|
||||
0,
|
||||
InstructionError::MissingRequiredSignature
|
||||
))
|
||||
bank_client
|
||||
.send_instruction(&mallory_keypair, malicious_instruction)
|
||||
.unwrap_err()
|
||||
.unwrap(),
|
||||
TransactionError::InstructionError(0, InstructionError::MissingRequiredSignature)
|
||||
);
|
||||
assert_eq!(bank_client.get_balance(&alice_pubkey), 50);
|
||||
assert_eq!(bank_client.get_balance(&mallory_pubkey), 50);
|
||||
assert_eq!(bank_client.get_balance(&alice_pubkey).unwrap(), 50);
|
||||
assert_eq!(bank_client.get_balance(&mallory_pubkey).unwrap(), 50);
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ pub mod system_program;
|
||||
pub mod system_transaction;
|
||||
pub mod timing;
|
||||
pub mod transaction;
|
||||
pub mod transport;
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
@ -6,37 +6,24 @@ use crate::instruction::Instruction;
|
||||
use crate::message::Message;
|
||||
use crate::pubkey::Pubkey;
|
||||
use crate::signature::{Keypair, Signature};
|
||||
use crate::transaction::TransactionError;
|
||||
use crate::transport::Result;
|
||||
|
||||
pub trait SyncClient {
|
||||
/// Create a transaction from the given message, and send it to the
|
||||
/// server, retrying as-needed.
|
||||
fn send_message(
|
||||
&self,
|
||||
keypairs: &[&Keypair],
|
||||
message: Message,
|
||||
) -> Result<Signature, TransactionError>;
|
||||
fn send_message(&self, keypairs: &[&Keypair], message: Message) -> Result<Signature>;
|
||||
|
||||
/// Create a transaction from a single instruction that only requires
|
||||
/// a single signer. Then send it to the server, retrying as-needed.
|
||||
fn send_instruction(
|
||||
&self,
|
||||
keypair: &Keypair,
|
||||
instruction: Instruction,
|
||||
) -> Result<Signature, TransactionError>;
|
||||
fn send_instruction(&self, keypair: &Keypair, instruction: Instruction) -> Result<Signature>;
|
||||
|
||||
/// Transfer lamports from `keypair` to `pubkey`, retrying until the
|
||||
/// transfer completes or produces and error.
|
||||
fn transfer(
|
||||
&self,
|
||||
lamports: u64,
|
||||
keypair: &Keypair,
|
||||
pubkey: &Pubkey,
|
||||
) -> Result<Signature, TransactionError>;
|
||||
fn transfer(&self, lamports: u64, keypair: &Keypair, pubkey: &Pubkey) -> Result<Signature>;
|
||||
|
||||
/// Get an account or None if not found.
|
||||
fn get_account_data(&self, pubkey: &Pubkey) -> Option<Vec<u8>>;
|
||||
fn get_account_data(&self, pubkey: &Pubkey) -> Result<Option<Vec<u8>>>;
|
||||
|
||||
/// Get account balance or 0 if not found.
|
||||
fn get_balance(&self, pubkey: &Pubkey) -> u64;
|
||||
fn get_balance(&self, pubkey: &Pubkey) -> Result<u64>;
|
||||
}
|
||||
|
32
sdk/src/transport.rs
Normal file
32
sdk/src/transport.rs
Normal file
@ -0,0 +1,32 @@
|
||||
use crate::transaction::TransactionError;
|
||||
use std::io;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TransportError {
|
||||
IoError(io::Error),
|
||||
TransactionError(TransactionError),
|
||||
}
|
||||
|
||||
impl TransportError {
|
||||
pub fn unwrap(&self) -> TransactionError {
|
||||
if let TransportError::TransactionError(err) = self {
|
||||
err.clone()
|
||||
} else {
|
||||
panic!("unexpected transport error")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<io::Error> for TransportError {
|
||||
fn from(err: io::Error) -> TransportError {
|
||||
TransportError::IoError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransactionError> for TransportError {
|
||||
fn from(err: TransactionError) -> TransportError {
|
||||
TransportError::TransactionError(err)
|
||||
}
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, TransportError>;
|
Loading…
x
Reference in New Issue
Block a user