diff --git a/rust/c509-certificate/src/lib.rs b/rust/c509-certificate/src/lib.rs index ae223655b9..434631b2c8 100644 --- a/rust/c509-certificate/src/lib.rs +++ b/rust/c509-certificate/src/lib.rs @@ -124,7 +124,10 @@ mod test { fn test_generate_and_verify_signed_c509_cert() { let tbs_cert = tbs(); - let private_key = FromStr::from_str(&private_key_str()).expect("Cannot create private key"); + let private_key = FromStr::from_str(&private_key_str()).expect( + "Cannot create +private key", + ); let signed_c509 = generate(&tbs_cert, Some(&private_key)) .expect("Failed to generate signed C509 certificate"); diff --git a/rust/cardano-chain-follower/src/metadata/cip509/decode_helper.rs b/rust/cardano-chain-follower/src/metadata/cip509/decode_helper.rs index 5fcf1227a2..366c20b892 100644 --- a/rust/cardano-chain-follower/src/metadata/cip509/decode_helper.rs +++ b/rust/cardano-chain-follower/src/metadata/cip509/decode_helper.rs @@ -2,86 +2,52 @@ use minicbor::{data::Tag, decode, Decoder}; -/// Helper function for decoding map. -pub(crate) fn decode_map_len(d: &mut Decoder, from: &str) -> Result { - d.map() - .map_err(|e| decode::Error::message(format!("Failed to decode map in {from}: {e}")))? - .ok_or(decode::Error::message(format!( - "Failed to decode map in {from}, unexpected indefinite length", - ))) -} - -/// Helper function for decoding u8. -pub(crate) fn decode_u8(d: &mut Decoder, from: &str) -> Result { - d.u8() - .map_err(|e| decode::Error::message(format!("Failed to decode u8 in {from}: {e}"))) -} - -/// Helper function for decoding u16. -pub(crate) fn decode_u16(d: &mut Decoder, from: &str) -> Result { - d.u16() - .map_err(|e| decode::Error::message(format!("Failed to decode u16 in {from}: {e}"))) -} - -/// Helper function for decoding u32. -pub(crate) fn decode_u32(d: &mut Decoder, from: &str) -> Result { - d.u32() - .map_err(|e| decode::Error::message(format!("Failed to decode u32 in {from}: {e}"))) -} - -/// Helper function for decoding u64. -pub(crate) fn decode_u64(d: &mut Decoder, from: &str) -> Result { - d.u64() - .map_err(|e| decode::Error::message(format!("Failed to decode u64 in {from}: {e}"))) -} - -/// Helper function for decoding i8. -pub(crate) fn decode_i8(d: &mut Decoder, from: &str) -> Result { - d.i8() - .map_err(|e| decode::Error::message(format!("Failed to decode i8 in {from}: {e}"))) -} - -/// Helper function for decoding i16. -pub(crate) fn decode_i16(d: &mut Decoder, from: &str) -> Result { - d.i16() - .map_err(|e| decode::Error::message(format!("Failed to decode i16 in {from}: {e}"))) -} - -/// Helper function for decoding i32. -pub(crate) fn decode_i32(d: &mut Decoder, from: &str) -> Result { - d.i32() - .map_err(|e| decode::Error::message(format!("Failed to decode i32 in {from}: {e}"))) -} - -/// Helper function for decoding i64. -pub(crate) fn decode_i64(d: &mut Decoder, from: &str) -> Result { - d.i64() - .map_err(|e| decode::Error::message(format!("Failed to decode i64 in {from}: {e}"))) -} - -/// Helper function for decoding string. -pub(crate) fn decode_string(d: &mut Decoder, from: &str) -> Result { - d.str() - .map(std::borrow::ToOwned::to_owned) - .map_err(|e| decode::Error::message(format!("Failed to decode string in {from}: {e}"))) +/// Generic helper function for decoding different types. +pub(crate) fn decode_helper<'a, T, C>( + d: &mut Decoder<'a>, from: &str, context: &mut C, +) -> Result +where T: minicbor::Decode<'a, C> { + T::decode(d, context).map_err(|e| { + decode::Error::message(&format!( + "Failed to decode {:?} in {from}: {e}", + std::any::type_name::() + )) + }) } /// Helper function for decoding bytes. pub(crate) fn decode_bytes(d: &mut Decoder, from: &str) -> Result, decode::Error> { - d.bytes() - .map(<[u8]>::to_vec) - .map_err(|e| decode::Error::message(format!("Failed to decode bytes in {from}: {e}"))) + d.bytes().map(<[u8]>::to_vec).map_err(|e| { + decode::Error::message(&format!( + "Failed to decode bytes in {from}: + {e}" + )) + }) } /// Helper function for decoding array. pub(crate) fn decode_array_len(d: &mut Decoder, from: &str) -> Result { d.array() - .map_err(|e| decode::Error::message(format!("Failed to decode array in {from}: {e}")))? - .ok_or(decode::Error::message(format!( + .map_err(|e| { + decode::Error::message(&format!( + "Failed to decode array in {from}: + {e}" + )) + })? + .ok_or(decode::Error::message(&format!( "Failed to decode array in {from}, unexpected indefinite length", ))) } +/// Helper function for decoding map. +pub(crate) fn decode_map_len(d: &mut Decoder, from: &str) -> Result { + d.map() + .map_err(|e| decode::Error::message(format!("Failed to decode map in {from}: {e}")))? + .ok_or(decode::Error::message(format!( + "Failed to decode map in {from}, unexpected indefinite length", + ))) +} + /// Helper function for decoding tag. pub(crate) fn decode_tag(d: &mut Decoder, from: &str) -> Result { d.tag() @@ -91,50 +57,63 @@ pub(crate) fn decode_tag(d: &mut Decoder, from: &str) -> Result Result, decode::Error> { match d.datatype()? { - minicbor::data::Type::Bytes => Ok(decode_bytes(d, &format!("{from} Any"))?), minicbor::data::Type::String => { - Ok(decode_string(d, &format!("{from} Any"))? - .as_bytes() - .to_vec()) - }, - minicbor::data::Type::Array => { - Ok(decode_array_len(d, &format!("{from} Any"))? - .to_be_bytes() - .to_vec()) + match decode_helper::(d, &format!("{from} Any"), &mut ()) { + Ok(i) => Ok(i.as_bytes().to_vec()), + Err(e) => Err(e), + } }, minicbor::data::Type::U8 => { - Ok(decode_u8(d, &format!("{from} Any"))?.to_be_bytes().to_vec()) + match decode_helper::(d, &format!("{from} Any"), &mut ()) { + Ok(i) => Ok(i.to_be_bytes().to_vec()), + Err(e) => Err(e), + } }, minicbor::data::Type::U16 => { - Ok(decode_u16(d, &format!("{from} Any"))? - .to_be_bytes() - .to_vec()) + match decode_helper::(d, &format!("{from} Any"), &mut ()) { + Ok(i) => Ok(i.to_be_bytes().to_vec()), + Err(e) => Err(e), + } }, minicbor::data::Type::U32 => { - Ok(decode_u32(d, &format!("{from} Any"))? - .to_be_bytes() - .to_vec()) + match decode_helper::(d, &format!("{from} Any"), &mut ()) { + Ok(i) => Ok(i.to_be_bytes().to_vec()), + Err(e) => Err(e), + } }, minicbor::data::Type::U64 => { - Ok(decode_u64(d, &format!("{from} Any"))? - .to_be_bytes() - .to_vec()) + match decode_helper::(d, &format!("{from} Any"), &mut ()) { + Ok(i) => Ok(i.to_be_bytes().to_vec()), + Err(e) => Err(e), + } }, minicbor::data::Type::I8 => { - Ok(decode_i8(d, &format!("{from} Any"))?.to_be_bytes().to_vec()) + match decode_helper::(d, &format!("{from} Any"), &mut ()) { + Ok(i) => Ok(i.to_be_bytes().to_vec()), + Err(e) => Err(e), + } }, minicbor::data::Type::I16 => { - Ok(decode_i16(d, &format!("{from} Any"))? - .to_be_bytes() - .to_vec()) + match decode_helper::(d, &format!("{from} Any"), &mut ()) { + Ok(i) => Ok(i.to_be_bytes().to_vec()), + Err(e) => Err(e), + } }, minicbor::data::Type::I32 => { - Ok(decode_i32(d, &format!("{from} Any"))? - .to_be_bytes() - .to_vec()) + match decode_helper::(d, &format!("{from} Any"), &mut ()) { + Ok(i) => Ok(i.to_be_bytes().to_vec()), + Err(e) => Err(e), + } }, minicbor::data::Type::I64 => { - Ok(decode_i64(d, &format!("{from} Any"))? + match decode_helper::(d, &format!("{from} Any"), &mut ()) { + Ok(i) => Ok(i.to_be_bytes().to_vec()), + Err(e) => Err(e), + } + }, + minicbor::data::Type::Bytes => Ok(decode_bytes(d, &format!("{from} Any"))?), + minicbor::data::Type::Array => { + Ok(decode_array_len(d, &format!("{from} Any"))? .to_be_bytes() .to_vec()) }, @@ -213,7 +192,6 @@ mod tests { let mut e = Encoder::new(&mut buf); let num: i32 = -123_456_789; e.i32(num).expect("Error encoding i32"); - let mut d = Decoder::new(&buf); let result = decode_any(&mut d, "test").expect("Error decoding i32"); assert_eq!( diff --git a/rust/cardano-chain-follower/src/metadata/cip509/mod.rs b/rust/cardano-chain-follower/src/metadata/cip509/mod.rs index b0f083d9c1..08ae4ce5ea 100644 --- a/rust/cardano-chain-follower/src/metadata/cip509/mod.rs +++ b/rust/cardano-chain-follower/src/metadata/cip509/mod.rs @@ -4,7 +4,7 @@ // cspell: words pkix use c509_certificate::general_names::general_name::GeneralNameValue; -use decode_helper::{decode_bytes, decode_map_len, decode_u8}; +use decode_helper::{decode_bytes, decode_helper, decode_map_len}; use der_parser::{asn1_rs::oid, der::parse_der_sequence, Oid}; use rbac::{certs::C509Cert, role_data::RoleData}; @@ -110,7 +110,7 @@ impl Decode<'_, ()> for Cip509 { let key = d.probe().u8()?; if let Some(key) = Cip509IntIdentifier::from_repr(key) { // Consuming the int - decode_u8(d, "CIP509")?; + let _: u8 = decode_helper(d, "CIP509", ctx)?; match key { Cip509IntIdentifier::Purpose => { cip509_metadatum.purpose = decode_bytes(d, "CIP509 purpose")? @@ -1085,14 +1085,15 @@ mod tests { let transactions = multi_era_block.txs(); // Second transaction of this test data contains the CIP509 auxiliary data - #[allow(clippy::indexing_slicing)] - let tx = transactions[1].clone(); - let aux_data = cip_509_aux_data(&tx); + let tx = transactions + .get(1) + .expect("Failed to get transaction index"); + let aux_data = cip_509_aux_data(tx); let mut decoder = Decoder::new(aux_data.as_slice()); let cip509 = Cip509::decode(&mut decoder, &mut ()).expect("Failed to decode Cip509"); assert!(cip509 - .validate_txn_inputs_hash(&tx, &mut validation_report, &decoded_metadata) + .validate_txn_inputs_hash(tx, &mut validation_report, &decoded_metadata) .unwrap()); } @@ -1106,15 +1107,16 @@ mod tests { let transactions = multi_era_block.txs(); // Second transaction of this test data contains the CIP509 auxiliary data - #[allow(clippy::indexing_slicing)] - let tx = transactions[1].clone(); + let tx = transactions + .get(1) + .expect("Failed to get transaction index"); - let aux_data = cip_509_aux_data(&tx); + let aux_data = cip_509_aux_data(tx); let mut decoder = Decoder::new(aux_data.as_slice()); let mut cip509 = Cip509::decode(&mut decoder, &mut ()).expect("Failed to decode Cip509"); assert!(cip509 - .validate_aux(&tx, &mut validation_report, &decoded_metadata) + .validate_aux(tx, &mut validation_report, &decoded_metadata) .unwrap()); } @@ -1128,15 +1130,16 @@ mod tests { let transactions = multi_era_block.txs(); // Second transaction of this test data contains the CIP509 auxiliary data - #[allow(clippy::indexing_slicing)] - let tx = transactions[1].clone(); + let tx = transactions + .get(1) + .expect("Failed to get transaction index"); - let aux_data = cip_509_aux_data(&tx); + let aux_data = cip_509_aux_data(tx); let mut decoder = Decoder::new(aux_data.as_slice()); let cip509 = Cip509::decode(&mut decoder, &mut ()).expect("Failed to decode Cip509"); assert!(cip509 - .validate_stake_public_key(&tx, &mut validation_report, &decoded_metadata, 0) + .validate_stake_public_key(tx, &mut validation_report, &decoded_metadata, 0) .unwrap()); } @@ -1150,10 +1153,11 @@ mod tests { let transactions = multi_era_block.txs(); // Second transaction of this test data contains the CIP509 auxiliary data - #[allow(clippy::indexing_slicing)] - let tx = transactions[1].clone(); + let tx = transactions + .get(1) + .expect("Failed to get transaction index"); - let aux_data = cip_509_aux_data(&tx); + let aux_data = cip_509_aux_data(tx); let mut decoder = Decoder::new(aux_data.as_slice()); let cip509 = Cip509::decode(&mut decoder, &mut ()).expect("Failed to decode Cip509"); @@ -1163,7 +1167,7 @@ mod tests { if role.role_number == 0 { assert!(cip509 .validate_payment_key( - &tx, + tx, &mut validation_report, &decoded_metadata, 0, @@ -1185,10 +1189,11 @@ mod tests { let transactions = multi_era_block.txs(); // Second transaction of this test data contains the CIP509 auxiliary data - #[allow(clippy::indexing_slicing)] - let tx = transactions[1].clone(); + let tx = transactions + .get(1) + .expect("Failed to get transaction index"); - let aux_data = cip_509_aux_data(&tx); + let aux_data = cip_509_aux_data(tx); let mut decoder = Decoder::new(aux_data.as_slice()); let cip509 = Cip509::decode(&mut decoder, &mut ()).expect("Failed to decode Cip509"); @@ -1199,7 +1204,7 @@ mod tests { println!( "{:?}", cip509.validate_payment_key( - &tx, + tx, &mut validation_report, &decoded_metadata, 0, @@ -1221,15 +1226,16 @@ mod tests { let transactions = multi_era_block.txs(); // Fifth transaction of this test data contains the CIP509 auxiliary data - #[allow(clippy::indexing_slicing)] - let tx = transactions[4].clone(); + let tx = transactions + .get(4) + .expect("Failed to get transaction index"); - let aux_data = cip_509_aux_data(&tx); + let aux_data = cip_509_aux_data(tx); let mut decoder = Decoder::new(aux_data.as_slice()); let cip509 = Cip509::decode(&mut decoder, &mut ()).expect("Failed to decode Cip509"); assert!(!cip509 - .validate_stake_public_key(&tx, &mut validation_report, &decoded_metadata, 0) + .validate_stake_public_key(tx, &mut validation_report, &decoded_metadata, 0) .unwrap()); } } diff --git a/rust/cardano-chain-follower/src/metadata/cip509/rbac/certs.rs b/rust/cardano-chain-follower/src/metadata/cip509/rbac/certs.rs index 58b77911f9..df27f4fa43 100644 --- a/rust/cardano-chain-follower/src/metadata/cip509/rbac/certs.rs +++ b/rust/cardano-chain-follower/src/metadata/cip509/rbac/certs.rs @@ -4,9 +4,7 @@ use c509_certificate::c509::C509; use minicbor::{decode, Decode, Decoder}; use x509_cert::{der::Decode as x509Decode, Certificate}; -use crate::metadata::cip509::decode_helper::{ - decode_array_len, decode_bytes, decode_u64, decode_u8, -}; +use crate::metadata::cip509::decode_helper::{decode_array_len, decode_bytes, decode_helper}; // ------------------x509------------------------ @@ -72,9 +70,11 @@ pub struct C509CertInMetadatumReference { } impl Decode<'_, ()> for C509CertInMetadatumReference { - fn decode(d: &mut Decoder, _ctx: &mut ()) -> Result { - let txn_output_field = decode_u8(d, "txn output field in C509CertInMetadatumReference")?; - let txn_output_index = decode_u64(d, "txn output index in C509CertInMetadatumReference")?; + fn decode(d: &mut Decoder, ctx: &mut ()) -> Result { + let txn_output_field: u8 = + decode_helper(d, "txn output field in C509CertInMetadatumReference", ctx)?; + let txn_output_index: u64 = + decode_helper(d, "txn output index in C509CertInMetadatumReference", ctx)?; let cert_ref = match d.datatype()? { minicbor::data::Type::Array => { let len = decode_array_len(d, "cert ref in C509CertInMetadatumReference")?; @@ -82,7 +82,13 @@ impl Decode<'_, ()> for C509CertInMetadatumReference { arr.map(Some) }, minicbor::data::Type::Null => Ok(None), - _ => Ok(Some(vec![decode_u64(d, "C509CertInMetadatumReference")?])), + _ => { + Ok(Some(vec![decode_helper( + d, + "C509CertInMetadatumReference", + ctx, + )?])) + }, }?; Ok(Self { txn_output_field, diff --git a/rust/cardano-chain-follower/src/metadata/cip509/rbac/mod.rs b/rust/cardano-chain-follower/src/metadata/cip509/rbac/mod.rs index 78b766d7f7..3dbf5da106 100644 --- a/rust/cardano-chain-follower/src/metadata/cip509/rbac/mod.rs +++ b/rust/cardano-chain-follower/src/metadata/cip509/rbac/mod.rs @@ -15,7 +15,7 @@ use role_data::RoleData; use strum::FromRepr; use super::decode_helper::{ - decode_any, decode_array_len, decode_bytes, decode_map_len, decode_u16, + decode_any, decode_array_len, decode_bytes, decode_helper, decode_map_len, }; /// Struct of Cip509 RBAC metadata. @@ -98,13 +98,13 @@ impl Cip509RbacMetadata { } impl Decode<'_, ()> for Cip509RbacMetadata { - fn decode(d: &mut Decoder, _ctx: &mut ()) -> Result { + fn decode(d: &mut Decoder, ctx: &mut ()) -> Result { let map_len = decode_map_len(d, "Cip509RbacMetadata")?; let mut x509_rbac_metadata = Cip509RbacMetadata::new(); for _ in 0..map_len { - let key = decode_u16(d, "key in Cip509RbacMetadata")?; + let key: u16 = decode_helper(d, "key in Cip509RbacMetadata", ctx)?; if let Some(key) = Cip509RbacMetadataInt::from_repr(key) { match key { Cip509RbacMetadataInt::X509Certs => { diff --git a/rust/cardano-chain-follower/src/metadata/cip509/rbac/role_data.rs b/rust/cardano-chain-follower/src/metadata/cip509/rbac/role_data.rs index 8845941723..b56f16f0f3 100644 --- a/rust/cardano-chain-follower/src/metadata/cip509/rbac/role_data.rs +++ b/rust/cardano-chain-follower/src/metadata/cip509/rbac/role_data.rs @@ -7,7 +7,7 @@ use strum::FromRepr; use super::Cip509RbacMetadataInt; use crate::metadata::cip509::decode_helper::{ - decode_any, decode_array_len, decode_bytes, decode_i16, decode_map_len, decode_u64, decode_u8, + decode_any, decode_array_len, decode_bytes, decode_helper, decode_map_len, }; /// Struct of role data. @@ -51,11 +51,11 @@ impl Decode<'_, ()> for RoleData { let map_len = decode_map_len(d, "RoleData")?; let mut role_data = RoleData::default(); for _ in 0..map_len { - let key = decode_u8(d, "key in RoleData")?; + let key: u8 = decode_helper(d, "key in RoleData", ctx)?; if let Some(key) = RoleDataInt::from_repr(key) { match key { RoleDataInt::RoleNumber => { - role_data.role_number = decode_u8(d, "RoleNumber in RoleData")?; + role_data.role_number = decode_helper(d, "RoleNumber in RoleData", ctx)?; }, RoleDataInt::RoleSigningKey => { role_data.role_signing_key = Some(KeyReference::decode(d, ctx)?); @@ -64,7 +64,8 @@ impl Decode<'_, ()> for RoleData { role_data.role_encryption_key = Some(KeyReference::decode(d, ctx)?); }, RoleDataInt::PaymentKey => { - role_data.payment_key = Some(decode_i16(d, "PaymentKey in RoleData")?); + role_data.payment_key = + Some(decode_helper(d, "PaymentKey in RoleData", ctx)?); }, } } else { @@ -129,11 +130,11 @@ enum LocalRefInt { } impl Decode<'_, ()> for KeyLocalRef { - fn decode(d: &mut Decoder, _ctx: &mut ()) -> Result { + fn decode(d: &mut Decoder, ctx: &mut ()) -> Result { decode_array_len(d, "KeyLocalRef")?; - let local_ref = LocalRefInt::from_repr(decode_u8(d, "LocalRef in KeyLocalRef")?) + let local_ref = LocalRefInt::from_repr(decode_helper(d, "LocalRef in KeyLocalRef", ctx)?) .ok_or(decode::Error::message("Invalid local reference"))?; - let key_offset = decode_u64(d, "KeyOffset in KeyLocalRef")?; + let key_offset: u64 = decode_helper(d, "KeyOffset in KeyLocalRef", ctx)?; Ok(Self { local_ref, key_offset, diff --git a/rust/cardano-chain-follower/src/metadata/cip509/x509_chunks.rs b/rust/cardano-chain-follower/src/metadata/cip509/x509_chunks.rs index c6ba7bd64d..0cb4700b7c 100644 --- a/rust/cardano-chain-follower/src/metadata/cip509/x509_chunks.rs +++ b/rust/cardano-chain-follower/src/metadata/cip509/x509_chunks.rs @@ -5,7 +5,7 @@ use std::io::Read; use minicbor::{decode, Decode, Decoder}; use strum::FromRepr; -use super::{decode_helper::decode_u8, rbac::Cip509RbacMetadata}; +use super::{decode_helper::decode_helper, rbac::Cip509RbacMetadata}; use crate::metadata::cip509::decode_helper::{decode_array_len, decode_bytes}; /// Enum of compression algorithms used to compress chunks. @@ -34,9 +34,9 @@ impl X509Chunks { } impl Decode<'_, ()> for X509Chunks { - fn decode(d: &mut Decoder, _ctx: &mut ()) -> Result { + fn decode(d: &mut Decoder, ctx: &mut ()) -> Result { // Determine the algorithm - let algo = decode_u8(d, "algorithm in X509Chunks")?; + let algo: u8 = decode_helper(d, "algorithm in X509Chunks", ctx)?; let algorithm = CompressionAlgorithm::from_repr(algo) .ok_or(decode::Error::message("Invalid chunk data type"))?;