From 2d3fdaec75e9d81ec94b968995d6b29c4c3fc3f0 Mon Sep 17 00:00:00 2001 From: thesimplekid Date: Fri, 1 Mar 2024 19:16:06 +0000 Subject: [PATCH] refactor: remove unwraps --- .../src/mint/localstore/redb_store.rs | 38 +++++++++++++--- crates/cashu-sdk/src/mint/mod.rs | 9 ++-- crates/cashu-sdk/src/wallet/mod.rs | 44 ++++++++----------- crates/cashu/src/dhke.rs | 3 +- crates/cashu/src/error.rs | 8 +++- crates/cashu/src/nuts/nut00.rs | 2 +- crates/cashu/src/nuts/nut10.rs | 4 +- crates/cashu/src/nuts/nut11.rs | 33 +++++++------- 8 files changed, 83 insertions(+), 58 deletions(-) diff --git a/crates/cashu-sdk/src/mint/localstore/redb_store.rs b/crates/cashu-sdk/src/mint/localstore/redb_store.rs index f6043ec3..7ef64898 100644 --- a/crates/cashu-sdk/src/mint/localstore/redb_store.rs +++ b/crates/cashu-sdk/src/mint/localstore/redb_store.rs @@ -95,7 +95,7 @@ impl LocalStore for RedbLocalStore { let table = read_txn.open_table(ACTIVE_KEYSETS_TABLE)?; if let Some(id) = table.get(unit.to_string().as_str())? { - return Ok(Some(Id::from_str(id.value()).unwrap())); + return Ok(Some(Id::from_str(id.value())?)); } Ok(None) @@ -142,7 +142,11 @@ impl LocalStore for RedbLocalStore { let keyset = table.get(keyset_id.to_string().as_str())?; - Ok(keyset.map(|k| serde_json::from_str(k.value()).unwrap())) + if let Some(keyset) = keyset { + Ok(serde_json::from_str(keyset.value())?) + } else { + Ok(None) + } } async fn get_keysets(&self) -> Result, Error> { @@ -182,7 +186,11 @@ impl LocalStore for RedbLocalStore { let quote = table.get(quote_id)?; - Ok(quote.map(|q| serde_json::from_str(q.value()).unwrap())) + if let Some(quote) = quote { + Ok(serde_json::from_str(quote.value())?) + } else { + Ok(None) + } } async fn get_mint_quotes(&self) -> Result, Error> { @@ -299,7 +307,11 @@ impl LocalStore for RedbLocalStore { let proof = table.get(secret_point.to_sec1_bytes().as_ref())?; - Ok(proof.map(|p| serde_json::from_str(p.value()).unwrap())) + if let Some(proof) = proof { + Ok(serde_json::from_str(proof.value())?) + } else { + Ok(None) + } } async fn get_spent_proof_by_secret(&self, secret: &Secret) -> Result, Error> { @@ -313,7 +325,11 @@ impl LocalStore for RedbLocalStore { debug!("Checking secret: {}", secret.to_string()); - Ok(proof.map(|p| serde_json::from_str(p.value()).unwrap())) + if let Some(proof) = proof { + Ok(serde_json::from_str(proof.value())?) + } else { + Ok(None) + } } async fn add_pending_proof(&self, proof: Proof) -> Result<(), Error> { @@ -345,7 +361,11 @@ impl LocalStore for RedbLocalStore { let proof = table.get(secret_point.to_sec1_bytes().as_ref())?; - Ok(proof.map(|p| serde_json::from_str(p.value()).unwrap())) + if let Some(proof) = proof { + Ok(serde_json::from_str(proof.value())?) + } else { + Ok(None) + } } async fn get_pending_proof_by_secret(&self, secret: &Secret) -> Result, Error> { @@ -357,7 +377,11 @@ impl LocalStore for RedbLocalStore { let proof = table.get(secret_hash.to_sec1_bytes().as_ref())?; - Ok(proof.map(|p| serde_json::from_str(p.value()).unwrap())) + if let Some(proof) = proof { + Ok(serde_json::from_str(proof.value())?) + } else { + Ok(None) + } } async fn remove_pending_proof(&self, secret: &Secret) -> Result<(), Error> { diff --git a/crates/cashu-sdk/src/mint/mod.rs b/crates/cashu-sdk/src/mint/mod.rs index 966eda5c..0239f8be 100644 --- a/crates/cashu-sdk/src/mint/mod.rs +++ b/crates/cashu-sdk/src/mint/mod.rs @@ -412,7 +412,7 @@ impl Mint { } for proof in swap_request.inputs { - self.localstore.add_spent_proof(proof).await.unwrap(); + self.localstore.add_spent_proof(proof).await?; } let mut promises = Vec::with_capacity(swap_request.outputs.len()); @@ -427,7 +427,7 @@ impl Mint { #[cfg(not(feature = "nut11"))] async fn verify_proof(&self, proof: &Proof) -> Result<(), Error> { - let y = hash_to_curve(&proof.secret.to_bytes().unwrap()).unwrap(); + let y = hash_to_curve(&proof.secret.to_bytes()?)?; if self.localstore.get_spent_proof_by_hash(&y).await?.is_some() { return Err(Error::TokenSpent); } @@ -637,10 +637,7 @@ impl Mint { self.verify_melt_request(melt_request).await?; for input in &melt_request.inputs { - self.localstore - .add_spent_proof(input.clone()) - .await - .unwrap(); + self.localstore.add_spent_proof(input.clone()).await?; } let mut change = None; diff --git a/crates/cashu-sdk/src/wallet/mod.rs b/crates/cashu-sdk/src/wallet/mod.rs index 2d1458eb..61f5547f 100644 --- a/crates/cashu-sdk/src/wallet/mod.rs +++ b/crates/cashu-sdk/src/wallet/mod.rs @@ -41,6 +41,8 @@ pub enum Error { QuoteExpired, #[error("Quote Unknown")] QuoteUnknown, + #[error("No active keyset")] + NoActiveKeyset, #[error("`{0}`")] LocalStore(#[from] localstore::Error), #[error("`{0}`")] @@ -224,11 +226,11 @@ impl Wallet { &mut self, mint_url: &UncheckedUrl, unit: &CurrencyUnit, - ) -> Result, Error> { + ) -> Result { if let Some(keysets) = self.localstore.get_mint_keysets(mint_url.clone()).await? { for keyset in keysets { if keyset.unit.eq(unit) && keyset.active { - return Ok(Some(keyset.id)); + return Ok(keyset.id); } } } @@ -243,11 +245,11 @@ impl Wallet { .await?; for keyset in &keysets.keysets { if keyset.unit.eq(unit) && keyset.active { - return Ok(Some(keyset.id)); + return Ok(keyset.id); } } - Ok(None) + Err(Error::NoActiveKeyset) } async fn active_keys( @@ -255,7 +257,7 @@ impl Wallet { mint_url: &UncheckedUrl, unit: &CurrencyUnit, ) -> Result, Error> { - let active_keyset_id = self.active_mint_keyset(mint_url, unit).await?.unwrap(); + let active_keyset_id = self.active_mint_keyset(mint_url, unit).await?; let keys; @@ -293,10 +295,7 @@ impl Wallet { return Err(Error::QuoteUnknown); }; - let active_keyset_id = self - .active_mint_keyset(&mint_url, "e_info.unit) - .await? - .unwrap(); + let active_keyset_id = self.active_mint_keyset(&mint_url, "e_info.unit).await?; let premint_secrets = match &self.backup_info { Some(backup_info) => PreMintSecrets::from_seed( @@ -353,17 +352,12 @@ impl Wallet { // TODO: if none fetch keyset for mint - let keys = - if let Some(keys) = self.localstore.get_keys(&active_keyset_id.unwrap()).await? { - keys - } else { - self.get_mint_keys(&token.mint, active_keyset_id.unwrap()) - .await?; - self.localstore - .get_keys(&active_keyset_id.unwrap()) - .await? - .unwrap() - }; + let keys = if let Some(keys) = self.localstore.get_keys(&active_keyset_id).await? { + keys + } else { + self.get_mint_keys(&token.mint, active_keyset_id).await?; + self.localstore.get_keys(&active_keyset_id).await?.unwrap() + }; // Sum amount of all proofs let amount: Amount = token.proofs.iter().map(|p| p.amount).sum(); @@ -405,7 +399,7 @@ impl Wallet { amount: Option, proofs: Proofs, ) -> Result { - let active_keyset_id = self.active_mint_keyset(mint_url, unit).await?.unwrap(); + let active_keyset_id = self.active_mint_keyset(mint_url, unit).await?; let pre_mint_secrets = if let Some(amount) = amount { let mut desired_messages = PreMintSecrets::random(active_keyset_id, amount)?; @@ -638,9 +632,7 @@ impl Wallet { let proofs_amount = proofs.iter().map(|p| p.amount).sum(); let blinded = PreMintSecrets::blank( - self.active_mint_keyset(mint_url, "e_info.unit) - .await? - .unwrap(), + self.active_mint_keyset(mint_url, "e_info.unit).await?, proofs_amount, )?; @@ -695,7 +687,7 @@ impl Wallet { conditions: P2PKConditions, ) -> Result { let input_proofs = self.select_proofs(mint_url.clone(), unit, amount).await?; - let active_keyset_id = self.active_mint_keyset(mint_url, unit).await?.unwrap(); + let active_keyset_id = self.active_mint_keyset(mint_url, unit).await?; let input_amount: Amount = input_proofs.iter().map(|p| p.amount).sum(); let change_amount = input_amount - amount; @@ -782,7 +774,7 @@ impl Wallet { // TODO: if none fetch keyset for mint - let keys = self.localstore.get_keys(&active_keyset_id.unwrap()).await?; + let keys = self.localstore.get_keys(&active_keyset_id).await?; // Sum amount of all proofs let amount: Amount = token.proofs.iter().map(|p| p.amount).sum(); diff --git a/crates/cashu/src/dhke.rs b/crates/cashu/src/dhke.rs index 1a9a8b27..4bd68c3a 100644 --- a/crates/cashu/src/dhke.rs +++ b/crates/cashu/src/dhke.rs @@ -149,9 +149,10 @@ mod mint { where V: TryInto>, >>::Error: Debug, + error::mint::Error: From<>>::Error>, { // Y - let y = hash_to_curve(&msg.try_into().unwrap())?; + let y = hash_to_curve(&msg.try_into()?)?; if unblinded_message == k256::PublicKey::try_from(*y.as_affine() * Scalar::from(a.as_scalar_primitive()))? diff --git a/crates/cashu/src/error.rs b/crates/cashu/src/error.rs index 4acd6100..115d3157 100644 --- a/crates/cashu/src/error.rs +++ b/crates/cashu/src/error.rs @@ -13,7 +13,7 @@ pub enum Error { Utf8ParseError(#[from] FromUtf8Error), /// Serde Json error #[error("`{0}`")] - SerdeJsonError(serde_json::Error), + SerdeJsonError(#[from] serde_json::Error), /// Base64 error #[error("`{0}`")] Base64Error(#[from] base64::DecodeError), @@ -22,6 +22,8 @@ pub enum Error { HexError(#[from] hex::FromHexError), #[error("`{0}`")] EllipticCurve(#[from] k256::elliptic_curve::Error), + #[error("`{0}`")] + ECDSA(#[from] k256::ecdsa::Error), #[error("No Key for Amoun")] AmountKey, #[error("Amount miss match")] @@ -50,6 +52,10 @@ pub enum Error { InvalidSignature, #[error("Locktime in past")] LocktimeInPast, + #[error("`{0}`")] + Secret(#[from] super::secret::Error), + #[error("`{0}`")] + ParseInt(#[from] std::num::ParseIntError), /// Custom error #[error("`{0}`")] CustomError(String), diff --git a/crates/cashu/src/nuts/nut00.rs b/crates/cashu/src/nuts/nut00.rs index 2e250917..a06199a3 100644 --- a/crates/cashu/src/nuts/nut00.rs +++ b/crates/cashu/src/nuts/nut00.rs @@ -263,7 +263,7 @@ pub mod wallet { let mut output = Vec::with_capacity(amount_split.len()); for amount in amount_split { - let secret: Secret = conditions.clone().try_into().unwrap(); + let secret: Secret = conditions.clone().try_into()?; let (blinded, r) = blind_message(&secret.to_bytes()?, None)?; let blinded_message = BlindedMessage::new(amount, keyset_id, blinded); diff --git a/crates/cashu/src/nuts/nut10.rs b/crates/cashu/src/nuts/nut10.rs index a17b8c61..ca429834 100644 --- a/crates/cashu/src/nuts/nut10.rs +++ b/crates/cashu/src/nuts/nut10.rs @@ -66,7 +66,9 @@ impl Serialize for Secret { impl TryFrom for crate::secret::Secret { type Error = Error; fn try_from(secret: Secret) -> Result { - Ok(crate::secret::Secret::from_str(&serde_json::to_string(&secret).unwrap()).unwrap()) + Ok(crate::secret::Secret::from_str(&serde_json::to_string( + &secret, + )?)?) } } diff --git a/crates/cashu/src/nuts/nut11.rs b/crates/cashu/src/nuts/nut11.rs index 3c9b8e94..6c8d018c 100644 --- a/crates/cashu/src/nuts/nut11.rs +++ b/crates/cashu/src/nuts/nut11.rs @@ -8,6 +8,7 @@ use std::str::FromStr; use k256::schnorr::signature::{Signer, Verifier}; use k256::schnorr::Signature; +use log::debug; use serde::de::Error as DeserializerError; use serde::ser::SerializeSeq; use serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer}; @@ -246,10 +247,8 @@ impl TryFrom for P2PKConditions { .secret_data .tags .into_iter() - .map(|t| { - let tag = Tag::try_from(t).unwrap(); - (tag.kind(), tag) - }) + .flat_map(|t| Tag::try_from(t)) + .map(|t| (t.kind(), t)) .collect(); let mut pubkeys: Vec = vec![]; @@ -310,7 +309,7 @@ impl TryFrom for P2PKConditions { impl Proof { pub fn verify_p2pk(&self) -> Result<(), Error> { - let secret: Secret = (&self.secret).try_into().unwrap(); + let secret: Secret = (&self.secret).try_into()?; if secret.kind.ne(&super::nut10::Kind::P2PK) { return Err(Error::IncorrectSecretKind); } @@ -319,19 +318,23 @@ impl Proof { let mut valid_sigs = 0; - let msg = &self.secret.to_bytes().unwrap(); + let msg = &self.secret.to_bytes()?; for signature in &self.witness.signatures { let mut pubkeys = spending_conditions.pubkeys.clone(); - let data_key = VerifyingKey::from_str(&secret.secret_data.data).unwrap(); + let data_key = VerifyingKey::from_str(&secret.secret_data.data)?; pubkeys.push(data_key); for v in &spending_conditions.pubkeys { - let sig = Signature::try_from(hex::decode(signature).unwrap().as_slice()).unwrap(); + let sig = Signature::try_from(hex::decode(signature)?.as_slice())?; if v.verify(msg, &sig).is_ok() { valid_sigs += 1; } else { - println!("{:?}", v.verify(msg, &sig).unwrap()); + debug!( + "Could not verify signature: {} on message: {}", + hex::encode(sig.to_bytes()), + self.secret.to_string() + ) } } } @@ -361,7 +364,7 @@ impl Proof { } pub fn sign_p2pk_proof(&mut self, secret_key: SigningKey) -> Result<(), Error> { - let msg_to_sign = &self.secret.to_bytes().unwrap(); + let msg_to_sign = &self.secret.to_bytes()?; let signature = secret_key.sign(msg_to_sign); @@ -493,8 +496,8 @@ where if tag_len.eq(&2) { match tag_kind { TagKind::SigFlag => Ok(Tag::SigFlag(SigFlag::from(tag[1].as_ref()))), - TagKind::NSigs => Ok(Tag::NSigs(tag[1].as_ref().parse().unwrap())), - TagKind::Locktime => Ok(Tag::LockTime(tag[1].as_ref().parse().unwrap())), + TagKind::NSigs => Ok(Tag::NSigs(tag[1].as_ref().parse()?)), + TagKind::Locktime => Ok(Tag::LockTime(tag[1].as_ref().parse()?)), _ => Err(Error::UnknownTag), } } else if tag_len.gt(&1) { @@ -583,9 +586,9 @@ pub struct VerifyingKey(k256::schnorr::VerifyingKey); impl VerifyingKey { pub fn from_bytes(bytes: &[u8]) -> Result { - Ok(VerifyingKey( - k256::schnorr::VerifyingKey::from_bytes(bytes).unwrap(), - )) + Ok(VerifyingKey(k256::schnorr::VerifyingKey::from_bytes( + bytes, + )?)) } pub fn verify(&self, msg: &[u8], signature: &Signature) -> Result<(), Error> {