From 2f398d6ab55bd4f1448548d45ec720c5afe1e9e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ceyhun=20=C5=9Een?= Date: Tue, 11 Jun 2024 12:01:26 +0300 Subject: [PATCH] errors: Add initial error module. --- Cargo.toml | 2 ++ src/client/rpc_api.rs | 47 +++++++++++++++++++++----------------- src/ledger/errors.rs | 12 ++++++++++ src/ledger/mod.rs | 1 + src/ledger/transactions.rs | 13 +++++------ 5 files changed, 47 insertions(+), 28 deletions(-) create mode 100644 src/ledger/errors.rs diff --git a/Cargo.toml b/Cargo.toml index c1315f1..ddcca24 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,5 @@ serde = { version = "1.0", default-features = false } serde_json = "1.0.108" bitcoincore-rpc = { git = "https://github.com/rust-bitcoin/rust-bitcoincore-rpc.git" } bitcoin-simulator = { git = "https://github.com/chainwayxyz/bitcoin-simulator" } +anyhow = "1.0.86" +thiserror = "1.0.61" diff --git a/src/client/rpc_api.rs b/src/client/rpc_api.rs index 6adc346..ad0a491 100644 --- a/src/client/rpc_api.rs +++ b/src/client/rpc_api.rs @@ -38,6 +38,22 @@ impl RpcApi for Client { ); } + fn send_raw_transaction( + &self, + tx: R, + ) -> bitcoincore_rpc::Result { + let tx: Transaction = encode::deserialize_hex(&tx.raw_hex()).unwrap(); + + if let Err(e) = self.ledger.check_transaction(tx.clone()) { + return Err(bitcoincore_rpc::Error::Io(std::io::Error::other(format!( + "{e}" + )))); + } + + self.ledger.add_transaction_unconditionally(tx.clone()); + + Ok(tx.compute_txid()) + } fn get_raw_transaction( &self, txid: &bitcoin::Txid, @@ -67,22 +83,6 @@ impl RpcApi for Client { blocktime: None, }) } - fn send_raw_transaction( - &self, - tx: R, - ) -> bitcoincore_rpc::Result { - let tx: Transaction = encode::deserialize_hex(&tx.raw_hex()).unwrap(); - - self.ledger.add_transaction_unconditionally(tx.clone()); - - if !self.ledger.check_transaction(tx.clone()) { - return Err(bitcoincore_rpc::Error::Io(std::io::Error::other( - "Transaction not valid.", - ))); - } - - Ok(tx.compute_txid()) - } fn get_transaction( &self, @@ -207,19 +207,24 @@ mod tests { fn raw_transaction() { let rpc = Client::new("", bitcoincore_rpc::Auth::None).unwrap(); + // Get some BTC. + let address = rpc.get_new_address(None, None).unwrap(); + rpc.generate_to_address(101, address.assume_checked_ref()) + .unwrap(); + let prev_tx = rpc.ledger._get_transactions().get(0).unwrap().to_owned(); + // Insert raw transactions to Bitcoin. let txin = TxIn { previous_output: OutPoint { - txid: Txid::from_byte_array([0x45; 32]), + txid: prev_tx.compute_txid(), vout: 0, }, - sequence: bitcoin::transaction::Sequence::ENABLE_RBF_NO_LOCKTIME, - script_sig: ScriptBuf::default(), - witness: Witness::new(), + ..Default::default() }; + println!("----- {:?}", txin.clone()); let txout = TxOut { value: Amount::from_sat(0x1F), - script_pubkey: test_common::get_temp_address().script_pubkey(), + script_pubkey: address.assume_checked().script_pubkey(), }; let inserted_tx1 = test_common::create_transaction(vec![txin], vec![txout]); rpc.send_raw_transaction(&inserted_tx1).unwrap(); diff --git a/src/ledger/errors.rs b/src/ledger/errors.rs new file mode 100644 index 0000000..0b7f5a7 --- /dev/null +++ b/src/ledger/errors.rs @@ -0,0 +1,12 @@ +//! # Errors +//! +//! Errors that can be returned from ledger operations. + +use thiserror::Error; + +/// Ledger error types. +#[derive(Error, Debug)] +pub enum LedgerError { + #[error("Database returned an error: {0}")] + Database(anyhow::Error), +} diff --git a/src/ledger/mod.rs b/src/ledger/mod.rs index 39e8f44..94d7e1f 100644 --- a/src/ledger/mod.rs +++ b/src/ledger/mod.rs @@ -12,6 +12,7 @@ use std::{ sync::{Arc, Mutex}, }; +mod errors; mod transactions; /// Adds a new item to a `Vec` member, guarded by a `Cell`. diff --git a/src/ledger/transactions.rs b/src/ledger/transactions.rs index 7f0a8c0..29abb14 100644 --- a/src/ledger/transactions.rs +++ b/src/ledger/transactions.rs @@ -1,6 +1,6 @@ //! # Transaction Related Ledger Operations -use super::Ledger; +use super::{errors::LedgerError, Ledger}; use crate::{add_item, get_item}; use bitcoin::{Transaction, TxOut, Txid}; @@ -37,17 +37,16 @@ impl Ledger { get_item!(self.transactions); } /// Checks if a transaction is OK or not. - pub fn check_transaction(&self, transaction: Transaction) -> bool { - if let Ok(()) = self + pub fn check_transaction(&self, transaction: Transaction) -> Result<(), LedgerError> { + match self .database .lock() .unwrap() .verify_transaction(&transaction) { - return true; - }; - - false + Ok(()) => Ok(()), + Err(e) => Err(LedgerError::Database(e)), + } } }