diff --git a/src/bank.rs b/src/bank.rs index 267326f225..aeaf2acce0 100644 --- a/src/bank.rs +++ b/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 diff --git a/src/rpc.rs b/src/rpc.rs index 524274390b..1e55da3b36 100644 --- a/src/rpc.rs +++ b/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 { 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 { - Ok(self.bank.has_signature(&signature)) + fn get_signature_status(&self, signature: Signature) -> Result> { + Ok(self.bank.get_signature_status(&signature)) } fn get_transaction_count(&self) -> Result { Ok(self.bank.transaction_count() as u64)