Let clients know when transactions failed
This commit is contained in:
parent
25edb9e447
commit
e416cf7adf
23
src/bank.rs
23
src/bank.rs
|
@ -89,6 +89,10 @@ pub enum BankError {
|
|||
/// the `last_id` has been discarded.
|
||||
LastIdNotFound(Hash),
|
||||
|
||||
/// The bank has not seen a transaction with the given `Signature` or the transaction is
|
||||
/// too old and has been discarded.
|
||||
SignatureNotFound,
|
||||
|
||||
/// Proof of History verification failed.
|
||||
LedgerVerificationFailed,
|
||||
/// Contract's transaction token balance does not equal the balance after the transaction
|
||||
|
@ -711,17 +715,18 @@ impl Bank {
|
|||
self.transaction_count.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
pub fn has_signature(&self, signature: &Signature) -> bool {
|
||||
let last_ids_sigs = self
|
||||
.last_ids_sigs
|
||||
.read()
|
||||
.expect("'last_ids_sigs' read lock");
|
||||
for (_hash, signatures) in last_ids_sigs.iter() {
|
||||
if signatures.0.contains_key(signature) {
|
||||
return true;
|
||||
pub fn get_signature_status(&self, signature: &Signature) -> Result<()> {
|
||||
let last_ids_sigs = self.last_ids_sigs.read().unwrap();
|
||||
for (_hash, (signatures, _)) in last_ids_sigs.iter() {
|
||||
if let Some(res) = signatures.get(signature) {
|
||||
return res.clone();
|
||||
}
|
||||
}
|
||||
false
|
||||
Err(BankError::SignatureNotFound)
|
||||
}
|
||||
|
||||
pub fn has_signature(&self, signature: &Signature) -> bool {
|
||||
self.get_signature_status(signature) != Err(BankError::SignatureNotFound)
|
||||
}
|
||||
|
||||
/// Hash the `accounts` HashMap. This represents a validator's interpretation
|
||||
|
|
13
src/rpc.rs
13
src/rpc.rs
|
@ -1,6 +1,6 @@
|
|||
//! The `rpc` module implements the Solana RPC interface.
|
||||
|
||||
use bank::{Account, Bank};
|
||||
use bank::{Account, Bank, BankError};
|
||||
use bincode::deserialize;
|
||||
use bs58;
|
||||
use jsonrpc_core::*;
|
||||
|
@ -9,6 +9,7 @@ use service::Service;
|
|||
use signature::{Pubkey, Signature};
|
||||
use std::mem;
|
||||
use std::net::{SocketAddr, UdpSocket};
|
||||
use std::result;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::thread::{self, sleep, Builder, JoinHandle};
|
||||
|
@ -125,7 +126,9 @@ impl RpcSol for RpcSolImpl {
|
|||
return Err(Error::invalid_request());
|
||||
}
|
||||
let signature = Signature::new(&signature_vec);
|
||||
meta.request_processor.get_signature_status(signature)
|
||||
meta.request_processor
|
||||
.get_signature_status(signature)
|
||||
.map(|res| res.is_ok())
|
||||
}
|
||||
fn get_account_info(&self, meta: Self::Metadata, id: String) -> Result<Account> {
|
||||
let pubkey_vec = bs58::decode(id)
|
||||
|
@ -174,7 +177,7 @@ impl RpcSol for RpcSolImpl {
|
|||
.get_signature_status(signature)
|
||||
.map_err(|_| Error::internal_error())?;
|
||||
|
||||
if signature_status {
|
||||
if signature_status.is_ok() {
|
||||
return Ok(bs58::encode(signature).into_string());
|
||||
} else if now.elapsed().as_secs() > 5 {
|
||||
return Err(Error::internal_error());
|
||||
|
@ -224,8 +227,8 @@ impl JsonRpcRequestProcessor {
|
|||
let id = self.bank.last_id();
|
||||
Ok(bs58::encode(id).into_string())
|
||||
}
|
||||
fn get_signature_status(&self, signature: Signature) -> Result<bool> {
|
||||
Ok(self.bank.has_signature(&signature))
|
||||
fn get_signature_status(&self, signature: Signature) -> Result<result::Result<(), BankError>> {
|
||||
Ok(self.bank.get_signature_status(&signature))
|
||||
}
|
||||
fn get_transaction_count(&self) -> Result<u64> {
|
||||
Ok(self.bank.transaction_count() as u64)
|
||||
|
|
Loading…
Reference in New Issue