diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index b1b5fe76..b5176e6f 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -49,7 +49,7 @@ jobs: run: ./contrib/test.sh MSRV: - name: Test - 1.56.1 toolchain + name: Test - 1.63.0 toolchain runs-on: ubuntu-latest strategy: fail-fast: false @@ -57,7 +57,7 @@ jobs: - name: Checkout Crate uses: actions/checkout@v3 - name: Checkout Toolchain - uses: dtolnay/rust-toolchain@1.56.1 + uses: dtolnay/rust-toolchain@1.63.0 - name: Running test script env: DO_DOCS: false diff --git a/Cargo.toml b/Cargo.toml index 12029a50..f6b8444a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,3 +57,129 @@ name = "tx" [workspace] members = ["elementsd-tests"] exclude = ["fuzz"] + +[lints.clippy] +# Exclude lints we don't think are valuable. +needless_question_mark = "allow" # https://github.com/rust-bitcoin/rust-bitcoin/pull/2134 +manual_range_contains = "allow" # More readable than clippy's format. +uninlined_format_args = "allow" # This is a subjective style choice. +float_cmp = "allow" # Bitcoin floats are typically limited to 8 decimal places and we want them exact. +match_bool = "allow" # Adds extra indentation and LOC. +match_same_arms = "allow" # Collapses things that are conceptually unrelated to each other. +must_use_candidate = "allow" # Useful for audit but many false positives. +similar_names = "allow" # Too many (subjectively) false positives. +# Exhaustive list of pedantic clippy lints +assigning_clones = "warn" +bool_to_int_with_if = "warn" +borrow_as_ptr = "warn" +case_sensitive_file_extension_comparisons = "warn" +cast_lossless = "warn" +cast_possible_truncation = "allow" # All casts should include a code comment (except test code). +cast_possible_wrap = "allow" # Same as above re code comment. +cast_precision_loss = "warn" +cast_ptr_alignment = "warn" +cast_sign_loss = "allow" # All casts should include a code comment (except in test code). +checked_conversions = "warn" +cloned_instead_of_copied = "warn" +copy_iterator = "warn" +default_trait_access = "warn" +doc_link_with_quotes = "warn" +doc_markdown = "warn" +empty_enum = "warn" +enum_glob_use = "warn" +expl_impl_clone_on_copy = "warn" +explicit_deref_methods = "warn" +explicit_into_iter_loop = "warn" +explicit_iter_loop = "warn" +filter_map_next = "warn" +flat_map_option = "warn" +fn_params_excessive_bools = "warn" +from_iter_instead_of_collect = "warn" +if_not_else = "warn" +ignored_unit_patterns = "warn" +implicit_clone = "warn" +implicit_hasher = "warn" +inconsistent_struct_constructor = "warn" +index_refutable_slice = "warn" +inefficient_to_string = "warn" +inline_always = "warn" +into_iter_without_iter = "warn" +invalid_upcast_comparisons = "warn" +items_after_statements = "warn" +iter_filter_is_ok = "warn" +iter_filter_is_some = "warn" +iter_not_returning_iterator = "warn" +iter_without_into_iter = "warn" +large_digit_groups = "warn" +large_futures = "warn" +large_stack_arrays = "warn" +large_types_passed_by_value = "warn" +linkedlist = "warn" +macro_use_imports = "warn" +manual_assert = "warn" +manual_instant_elapsed = "warn" +manual_is_power_of_two = "warn" +manual_is_variant_and = "warn" +manual_let_else = "warn" +manual_ok_or = "warn" +manual_string_new = "warn" +many_single_char_names = "warn" +map_unwrap_or = "warn" +match_wildcard_for_single_variants = "warn" +maybe_infinite_iter = "warn" +mismatching_type_param_order = "warn" +missing_errors_doc = "allow" # FIXME this triggers 184 times; we should fix most +missing_fields_in_debug = "warn" +missing_panics_doc = "allow" # FIXME this one has 40 triggers +mut_mut = "warn" +naive_bytecount = "warn" +needless_bitwise_bool = "warn" +needless_continue = "warn" +needless_for_each = "warn" +needless_pass_by_value = "warn" +needless_raw_string_hashes = "warn" +no_effect_underscore_binding = "warn" +no_mangle_with_rust_abi = "warn" +option_as_ref_cloned = "warn" +option_option = "warn" +ptr_as_ptr = "warn" +ptr_cast_constness = "warn" +pub_underscore_fields = "warn" +range_minus_one = "warn" +range_plus_one = "warn" +redundant_closure_for_method_calls = "warn" +redundant_else = "warn" +ref_as_ptr = "warn" +ref_binding_to_reference = "warn" +ref_option = "warn" +ref_option_ref = "warn" +return_self_not_must_use = "warn" +same_functions_in_if_condition = "warn" +semicolon_if_nothing_returned = "warn" +should_panic_without_expect = "warn" +single_char_pattern = "warn" +single_match_else = "warn" +stable_sort_primitive = "warn" +str_split_at_newline = "warn" +string_add_assign = "warn" +struct_excessive_bools = "warn" +struct_field_names = "warn" +too_many_lines = "allow" # FIXME 14 triggers for this lint; probably most should be fixed +transmute_ptr_to_ptr = "warn" +trivially_copy_pass_by_ref = "warn" +unchecked_duration_subtraction = "warn" +unicode_not_nfc = "warn" +unnecessary_box_returns = "warn" +unnecessary_join = "warn" +unnecessary_literal_bound = "warn" +unnecessary_wraps = "warn" +unnested_or_patterns = "warn" +unreadable_literal = "warn" +unsafe_derive_deserialize = "warn" +unused_async = "warn" +unused_self = "warn" +used_underscore_binding = "warn" +used_underscore_items = "warn" +verbose_bit_mask = "warn" +wildcard_imports = "warn" +zero_sized_map_values = "warn" diff --git a/clippy.toml b/clippy.toml index 56ce04e4..c218f7c9 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1 +1,2 @@ -msrv = "1.56.1" +avoid-breaking-exported-api = true +msrv = "1.63.0" diff --git a/examples/raw_blind.rs b/examples/raw_blind.rs index 4447a3b0..0091ceec 100644 --- a/examples/raw_blind.rs +++ b/examples/raw_blind.rs @@ -184,7 +184,7 @@ fn main() { &mut rng, &secp, dest_amt, - Address::p2wsh( + &Address::p2wsh( &Script::new_v0_wsh(&dest_wsh), Some(dest_blind_pk.inner), &PARAMS, @@ -206,7 +206,7 @@ fn main() { &mut rng, &secp, change_amt, - Address::p2wsh( + &Address::p2wsh( &Script::new_v0_wsh(&change_wsh), Some(change_blind_pk.inner), &PARAMS, diff --git a/examples/tx.rs b/examples/tx.rs index ae7cd2f1..3144c3e7 100644 --- a/examples/tx.rs +++ b/examples/tx.rs @@ -32,7 +32,7 @@ fn main() { let res = tx.verify_tx_amt_proofs(&secp, &[txout]); match res { - Ok(_) => {} + Ok(()) => {} Err(e) => { panic!("{}", e); } diff --git a/src/address.rs b/src/address.rs index e4b5fda3..296fa63b 100644 --- a/src/address.rs +++ b/src/address.rs @@ -430,13 +430,14 @@ impl Address { version: witver, program: ref witprog, } => script::Builder::new() - .push_int(witver.to_u8() as i64) + .push_int(i64::from(witver.to_u8())) .push_slice(witprog), } .into_script() } /// Convert this address to an unconfidential address. + #[must_use] pub fn to_unconfidential(&self) -> Address { Address { params: self.params, @@ -446,6 +447,7 @@ impl Address { } /// Convert this address to a confidential address with the given blinding pubkey. + #[must_use] pub fn to_confidential(&self, blinding_pubkey: secp256k1_zkp::PublicKey) -> Address { Address { params: self.params, @@ -492,19 +494,11 @@ impl Address { // When blinded, the structure is: // <1: blinding prefix> <1: regular prefix> <33: blinding pubkey> <20: hash160> - let (blinded, prefix) = match data[0] == params.blinded_prefix { - true => { - if data.len() != 55 { - return Err(AddressError::InvalidLength(data.len())); - } - (true, data[1]) - } - false => { - if data.len() != 21 { - return Err(AddressError::InvalidLength(data.len())); - } - (false, data[0]) - } + let blinded = data[0] == params.blinded_prefix; + let prefix = match (blinded, data.len()) { + (true, 55) => data[1], + (false, 21) => data[0], + (_, len) => return Err(AddressError::InvalidLength(len)), }; let (blinding_pubkey, payload_data) = match blinded { @@ -534,7 +528,7 @@ impl Address { } /// Parse the address using the given parameters. - /// When using the built-in parameters, you can use [FromStr]. + /// When using the built-in parameters, you can use [`FromStr`]. pub fn parse_with_params( s: &str, params: &'static AddressParams, @@ -670,14 +664,10 @@ fn find_prefix(bech32: &str) -> &str { /// The first prefix can be mixed case, but the second one is expected in /// lower case. fn match_prefix(prefix_mixed: &str, target: Hrp) -> bool { - if target.len() != prefix_mixed.len() { - false - } else { - target - .lowercase_char_iter() - .zip(prefix_mixed.chars()) - .all(|(char_lower, char_mixed)| char_lower == char_mixed.to_ascii_lowercase()) - } + target.len() == prefix_mixed.len() && target + .lowercase_char_iter() + .zip(prefix_mixed.chars()) + .all(|(char_lower, char_mixed)| char_lower == char_mixed.to_ascii_lowercase()) } impl FromStr for Address { @@ -692,7 +682,7 @@ impl FromStr for Address { let net_arr = [liq, ele, liq_test]; let prefix = find_prefix(s); - for net in net_arr.iter() { + for net in &net_arr { // Bech32. if match_prefix(prefix, net.bech_hrp) { return Address::from_bech32(s, false, net); @@ -712,7 +702,7 @@ impl FromStr for Address { } let p = data[0]; - for net in net_arr.iter() { + for net in &net_arr { if p == net.p2pkh_prefix || p == net.p2sh_prefix || p == net.blinded_prefix { return Address::from_base58(&data, net); } diff --git a/src/blech32/decode.rs b/src/blech32/decode.rs index b73c80d1..93dfb2d9 100644 --- a/src/blech32/decode.rs +++ b/src/blech32/decode.rs @@ -104,7 +104,7 @@ impl<'s> UncheckedHrpstring<'s> { let ret = UncheckedHrpstring { hrp: Hrp::parse(hrp)?, - data: data[1..].as_bytes(), // Skip the separator. + data: &data.as_bytes()[1..], // Skip the separator. }; Ok(ret) @@ -138,7 +138,7 @@ impl<'s> UncheckedHrpstring<'s> { /// checksum if `NoChecksum` is used). #[inline] pub fn validate_checksum(&self) -> Result<(), ChecksumError> { - use ChecksumError::*; + use ChecksumError as E; if Ck::CHECKSUM_LENGTH == 0 { // Called with NoChecksum @@ -146,7 +146,7 @@ impl<'s> UncheckedHrpstring<'s> { } if self.data.len() < Ck::CHECKSUM_LENGTH { - return Err(InvalidChecksumLength); + return Err(E::InvalidChecksumLength); } let mut checksum_eng = checksum::Engine::::new(); @@ -158,7 +158,7 @@ impl<'s> UncheckedHrpstring<'s> { } if checksum_eng.residue() != &Ck::TARGET_RESIDUE { - return Err(InvalidChecksum); + return Err(E::InvalidChecksum); } Ok(()) @@ -221,7 +221,7 @@ impl<'s> CheckedHrpstring<'s> { /// Converts the ASCII bytes representing field elements to the respective field elements, then /// converts the stream of field elements to a stream of bytes. #[inline] - pub fn byte_iter(&self) -> ByteIter { + pub fn byte_iter(&self) -> ByteIter<'_> { ByteIter { iter: AsciiToFe32Iter { iter: self.data.iter().copied() }.fes_to_bytes() } } @@ -393,7 +393,7 @@ impl<'s> SegwitHrpstring<'s> { /// /// Use `self.witness_version()` to get the witness version. #[inline] - pub fn byte_iter(&self) -> ByteIter { + pub fn byte_iter(&self) -> ByteIter<'_> { ByteIter { iter: AsciiToFe32Iter { iter: self.data.iter().copied() }.fes_to_bytes() } } } @@ -405,7 +405,7 @@ impl<'s> SegwitHrpstring<'s> { /// /// The byte-index into the string where the '1' separator occurs, or an error if it does not. fn check_characters(s: &str) -> Result { - use CharError::*; + use CharError as E; let mut has_upper = false; let mut has_lower = false; @@ -417,7 +417,7 @@ fn check_characters(s: &str) -> Result { sep_pos = Some(n); } if req_bech32 { - Fe32::from_char(ch).map_err(|_| InvalidChar(ch))?; + Fe32::from_char(ch).map_err(|_| E::InvalidChar(ch))?; } if ch.is_ascii_uppercase() { has_upper = true; @@ -426,11 +426,11 @@ fn check_characters(s: &str) -> Result { } } if has_upper && has_lower { - Err(MixedCase) + Err(E::MixedCase) } else if let Some(pos) = sep_pos { Ok(pos) } else { - Err(MissingSeparator) + Err(E::MissingSeparator) } } @@ -505,29 +505,25 @@ pub enum SegwitHrpstringError { impl fmt::Display for SegwitHrpstringError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use SegwitHrpstringError::*; - match *self { - Unchecked(ref e) => write_err!(f, "parsing unchecked hrpstring failed"; e), - MissingWitnessVersion => write!(f, "the witness version byte is missing"), - InvalidWitnessVersion(fe) => write!(f, "invalid segwit witness version: {}", fe.to_u8()), - Padding(ref e) => write_err!(f, "invalid padding on the witness data"; e), - WitnessLength(ref e) => write_err!(f, "invalid witness length"; e), - Checksum(ref e) => write_err!(f, "invalid checksum"; e), + Self::Unchecked(ref e) => write_err!(f, "parsing unchecked hrpstring failed"; e), + Self::MissingWitnessVersion => write!(f, "the witness version byte is missing"), + Self::InvalidWitnessVersion(fe) => write!(f, "invalid segwit witness version: {}", fe.to_u8()), + Self::Padding(ref e) => write_err!(f, "invalid padding on the witness data"; e), + Self::WitnessLength(ref e) => write_err!(f, "invalid witness length"; e), + Self::Checksum(ref e) => write_err!(f, "invalid checksum"; e), } } } impl std::error::Error for SegwitHrpstringError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use SegwitHrpstringError::*; - match *self { - Unchecked(ref e) => Some(e), - Padding(ref e) => Some(e), - WitnessLength(ref e) => Some(e), - Checksum(ref e) => Some(e), - MissingWitnessVersion | InvalidWitnessVersion(_) => None, + Self::Unchecked(ref e) => Some(e), + Self::Padding(ref e) => Some(e), + Self::WitnessLength(ref e) => Some(e), + Self::Checksum(ref e) => Some(e), + Self::MissingWitnessVersion | Self::InvalidWitnessVersion(_) => None, } } } @@ -564,22 +560,18 @@ pub enum CheckedHrpstringError { impl fmt::Display for CheckedHrpstringError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use CheckedHrpstringError::*; - match *self { - Parse(ref e) => write_err!(f, "parse failed"; e), - Checksum(ref e) => write_err!(f, "invalid checksum"; e), + Self::Parse(ref e) => write_err!(f, "parse failed"; e), + Self::Checksum(ref e) => write_err!(f, "invalid checksum"; e), } } } impl std::error::Error for CheckedHrpstringError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use CheckedHrpstringError::*; - match *self { - Parse(ref e) => Some(e), - Checksum(ref e) => Some(e), + Self::Parse(ref e) => Some(e), + Self::Checksum(ref e) => Some(e), } } } @@ -606,22 +598,18 @@ pub enum UncheckedHrpstringError { impl fmt::Display for UncheckedHrpstringError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use UncheckedHrpstringError::*; - match *self { - Char(ref e) => write_err!(f, "character error"; e), - Hrp(ref e) => write_err!(f, "invalid human-readable part"; e), + Self::Char(ref e) => write_err!(f, "character error"; e), + Self::Hrp(ref e) => write_err!(f, "invalid human-readable part"; e), } } } impl std::error::Error for UncheckedHrpstringError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use UncheckedHrpstringError::*; - match *self { - Char(ref e) => Some(e), - Hrp(ref e) => Some(e), + Self::Char(ref e) => Some(e), + Self::Hrp(ref e) => Some(e), } } } @@ -656,30 +644,26 @@ pub enum CharError { impl fmt::Display for CharError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use CharError::*; - match *self { - MissingSeparator => write!(f, "missing human-readable separator, \"{}\"", SEP), - NothingAfterSeparator => write!(f, "invalid data - no characters after the separator"), - InvalidChecksum => write!(f, "invalid checksum"), - InvalidChecksumLength => write!(f, "the checksum is not a valid length"), - InvalidChar(n) => write!(f, "invalid character (code={})", n), - MixedCase => write!(f, "mixed-case strings not allowed"), + Self::MissingSeparator => write!(f, "missing human-readable separator, \"{}\"", SEP), + Self::NothingAfterSeparator => write!(f, "invalid data - no characters after the separator"), + Self::InvalidChecksum => write!(f, "invalid checksum"), + Self::InvalidChecksumLength => write!(f, "the checksum is not a valid length"), + Self::InvalidChar(n) => write!(f, "invalid character (code={})", n), + Self::MixedCase => write!(f, "mixed-case strings not allowed"), } } } impl std::error::Error for CharError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use CharError::*; - match *self { - MissingSeparator - | NothingAfterSeparator - | InvalidChecksum - | InvalidChecksumLength - | InvalidChar(_) - | MixedCase => None, + Self::MissingSeparator + | Self::NothingAfterSeparator + | Self::InvalidChecksum + | Self::InvalidChecksumLength + | Self::InvalidChar(_) + | Self::MixedCase => None, } } } @@ -696,21 +680,17 @@ pub enum ChecksumError { impl fmt::Display for ChecksumError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use ChecksumError::*; - match *self { - InvalidChecksum => write!(f, "invalid checksum"), - InvalidChecksumLength => write!(f, "the checksum is not a valid length"), + Self::InvalidChecksum => write!(f, "invalid checksum"), + Self::InvalidChecksumLength => write!(f, "the checksum is not a valid length"), } } } impl std::error::Error for ChecksumError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use ChecksumError::*; - match *self { - InvalidChecksum | InvalidChecksumLength => None, + Self::InvalidChecksum | Self::InvalidChecksumLength => None, } } } @@ -727,21 +707,17 @@ pub enum PaddingError { impl fmt::Display for PaddingError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use PaddingError::*; - match *self { - TooMuch => write!(f, "the data payload has too many bits of padding"), - NonZero => write!(f, "the data payload is padded with non-zero bits"), + Self::TooMuch => write!(f, "the data payload has too many bits of padding"), + Self::NonZero => write!(f, "the data payload is padded with non-zero bits"), } } } impl std::error::Error for PaddingError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use PaddingError::*; - match *self { - TooMuch | NonZero => None, + Self::TooMuch | Self::NonZero => None, } } } @@ -752,32 +728,32 @@ mod tests { #[test] fn bip_173_invalid_parsing_fails() { - use UncheckedHrpstringError::*; + use UncheckedHrpstringError as E; let invalid: Vec<(&str, UncheckedHrpstringError)> = vec!( ("\u{20}1nwldj5", // TODO: Rust >= 1.59.0 use Hrp(hrp::Error::InvalidAsciiByte('\u{20}'.try_into().unwrap()))), - Hrp(hrp::Error::InvalidAsciiByte(32))), + E::Hrp(hrp::Error::InvalidAsciiByte(32))), ("\u{7F}1axkwrx", - Hrp(hrp::Error::InvalidAsciiByte(127))), + E::Hrp(hrp::Error::InvalidAsciiByte(127))), ("\u{80}1eym55h", - Hrp(hrp::Error::NonAsciiChar('\u{80}'))), + E::Hrp(hrp::Error::NonAsciiChar('\u{80}'))), ("an84characterslonghumanreadablepartthatcontainsthetheexcludedcharactersbioandnumber11d6pts4", - Hrp(hrp::Error::TooLong(84))), + E::Hrp(hrp::Error::TooLong(84))), ("pzry9x0s0muk", - Char(CharError::MissingSeparator)), + E::Char(CharError::MissingSeparator)), ("1pzry9x0s0muk", - Hrp(hrp::Error::Empty)), + E::Hrp(hrp::Error::Empty)), ("x1b4n0q5v", - Char(CharError::InvalidChar('b'))), + E::Char(CharError::InvalidChar('b'))), // "li1dgmt3" in separate test because error is a checksum error. ("de1lg7wt\u{ff}", - Char(CharError::InvalidChar('\u{ff}'))), + E::Char(CharError::InvalidChar('\u{ff}'))), // "A1G7SGD8" in separate test because error is a checksum error. ("10a06t8", - Hrp(hrp::Error::Empty)), + E::Hrp(hrp::Error::Empty)), ("1qzzfhee", - Hrp(hrp::Error::Empty)), + E::Hrp(hrp::Error::Empty)), ); for (s, want) in invalid { @@ -789,54 +765,54 @@ mod tests { /* #[test] fn bip_173_invalid_parsing_fails_invalid_checksum() { - use ChecksumError::*; + use ChecksumError as E; let err = UncheckedHrpstring::new("li1dgmt3") .expect("string parses correctly") .validate_checksum::() .unwrap_err(); - assert_eq!(err, InvalidChecksumLength); + assert_eq!(err, E::InvalidChecksumLength); let err = UncheckedHrpstring::new("A1G7SGD8") .expect("string parses correctly") .validate_checksum::() .unwrap_err(); - assert_eq!(err, InvalidChecksum); + assert_eq!(err, E::InvalidChecksum); } */ #[test] fn bip_350_invalid_parsing_fails() { - use UncheckedHrpstringError::*; + use UncheckedHrpstringError as E; let invalid: Vec<(&str, UncheckedHrpstringError)> = vec!( ("\u{20}1xj0phk", // TODO: Rust >= 1.59.0 use Hrp(hrp::Error::InvalidAsciiByte('\u{20}'.try_into().unwrap()))), - Hrp(hrp::Error::InvalidAsciiByte(32))), + E::Hrp(hrp::Error::InvalidAsciiByte(32))), ("\u{7F}1g6xzxy", - Hrp(hrp::Error::InvalidAsciiByte(127))), + E::Hrp(hrp::Error::InvalidAsciiByte(127))), ("\u{80}1g6xzxy", - Hrp(hrp::Error::NonAsciiChar('\u{80}'))), + E::Hrp(hrp::Error::NonAsciiChar('\u{80}'))), ("an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx", - Hrp(hrp::Error::TooLong(84))), + E::Hrp(hrp::Error::TooLong(84))), ("qyrz8wqd2c9m", - Char(CharError::MissingSeparator)), + E::Char(CharError::MissingSeparator)), ("1qyrz8wqd2c9m", - Hrp(hrp::Error::Empty)), + E::Hrp(hrp::Error::Empty)), ("y1b0jsk6g", - Char(CharError::InvalidChar('b'))), + E::Char(CharError::InvalidChar('b'))), ("lt1igcx5c0", - Char(CharError::InvalidChar('i'))), + E::Char(CharError::InvalidChar('i'))), // "in1muywd" in separate test because error is a checksum error. ("mm1crxm3i", - Char(CharError::InvalidChar('i'))), + E::Char(CharError::InvalidChar('i'))), ("au1s5cgom", - Char(CharError::InvalidChar('o'))), + E::Char(CharError::InvalidChar('o'))), // "M1VUXWEZ" in separate test because error is a checksum error. ("16plkw9", - Hrp(hrp::Error::Empty)), + E::Hrp(hrp::Error::Empty)), ("1p2gdwpf", - Hrp(hrp::Error::Empty)), + E::Hrp(hrp::Error::Empty)), ); diff --git a/src/blech32/mod.rs b/src/blech32/mod.rs index 69694dd3..c4c2d5e6 100644 --- a/src/blech32/mod.rs +++ b/src/blech32/mod.rs @@ -30,11 +30,11 @@ impl bech32::Checksum for Blech32 { type MidstateRepr = u64; const CHECKSUM_LENGTH: usize = 12; const GENERATOR_SH: [u64; 5] = [ - 0x7d52fba40bd886, - 0x5e8dbf1a03950c, - 0x1c3a3c74072a18, - 0x385d72fa0e5139, - 0x7093e5a608865b, + 0x7d_52fb_a40b_d886, + 0x5e_8dbf_1a03_950c, + 0x1c_3a3c_7407_2a18, + 0x38_5d72_fa0e_5139, + 0x70_93e5_a608_865b, ]; const TARGET_RESIDUE: u64 = 1; @@ -49,13 +49,13 @@ impl bech32::Checksum for Blech32m { type MidstateRepr = u64; const CHECKSUM_LENGTH: usize = 12; const GENERATOR_SH: [u64; 5] = [ - 0x7d52fba40bd886, - 0x5e8dbf1a03950c, - 0x1c3a3c74072a18, - 0x385d72fa0e5139, - 0x7093e5a608865b, + 0x7d_52fb_a40b_d886, + 0x5e_8dbf_1a03_950c, + 0x1c_3a3c_7407_2a18, + 0x38_5d72_fa0e_5139, + 0x70_93e5_a608_865b, ]; - const TARGET_RESIDUE: u64 = 0x455972a3350f7a1; + const TARGET_RESIDUE: u64 = 0x455_972a_3350_f7a1; const CODE_LENGTH: usize = 1024; } diff --git a/src/blind.rs b/src/blind.rs index 650fcd74..340e62c5 100644 --- a/src/blind.rs +++ b/src/blind.rs @@ -39,7 +39,7 @@ pub enum TxOutError { UnExpectedNullValue, /// Unexpected Null asset UnExpectedNullAsset, - /// Money should be between 0 and 21_000_000 + /// Money should be between 0 and `21_000_000` MoneyOutofRange, /// Zero value explicit txout with non-provably unspendable script NonUnspendableZeroValue, @@ -90,7 +90,7 @@ pub enum VerificationError { RangeProofError(usize, secp256k1_zkp::Error), /// Missing Range Proof RangeProofMissing(usize), - /// Verification of SurjectionProof failed + /// Verification of `SurjectionProof` failed SurjectionProofError(usize, secp256k1_zkp::Error), /// Surjection Proof verification error SurjectionProofVerificationError(usize), @@ -165,7 +165,7 @@ pub enum ConfidentialTxOutError { NoBlindingKeyInAddress, /// Error originated in `secp256k1_zkp`. Upstream(secp256k1_zkp::Error), - /// General TxOut errors + /// General `TxOut` errors TxOutError(usize, TxOutError), /// Expected Explicit Asset for blinding ExpectedExplicitAsset, @@ -264,7 +264,7 @@ impl TxOutSecrets { /// Gets the surjection inputs from [`TxOutSecrets`]. /// - /// Returns a tuple (assetid, blind_factor, generator) if the blinds are + /// Returns a tuple `(assetid, blind_factor, generator)` if the blinds are /// consistent with asset commitment /// Otherwise, returns an error pub fn surjection_inputs(&self, secp: &Secp256k1) -> (Generator, Tag, Tweak) { @@ -327,7 +327,7 @@ impl SurjectionInput { } /// Handy method to convert [`SurjectionInput`] into a surjection target - /// that can be used while creating a new [SurjectionProof]. + /// that can be used while creating a new [`SurjectionProof`]. /// /// Only errors when the input asset is Null. pub fn surjection_target( @@ -405,8 +405,8 @@ impl Value { /// /// # Returns: /// - /// A pair of blinded value, nonce and corresponding proof as ([`Value`], [`Nonce`], [`RangeProof`]) - /// The nonce here refers to public key corresponding to the input `ephemeral_sk` + /// * A pair of blinded value, nonce and corresponding proof as ([`Value`], [`Nonce`], [`RangeProof`]) + /// * The nonce here refers to public key corresponding to the input `ephemeral_sk` pub fn blind( self, secp: &Secp256k1, @@ -424,7 +424,8 @@ impl Value { Ok((value_commit, nonce, rangeproof)) } - /// Blinds with the given shared_secret(instead of computing it via ECDH) + /// Blinds with the given `shared_secret` (instead of computing it via ECDH). + /// /// This is useful while blinding assets as there is no counter party to provide /// the blinding key. pub fn blind_with_shared_secret( @@ -466,7 +467,7 @@ impl TxOut { pub const RANGEPROOF_EXP_SHIFT: i32 = 0; /// Rangeproof Minimum private bits pub const RANGEPROOF_MIN_PRIV_BITS: u8 = 52; - /// Maximum explicit amount in a bitcoin TxOut + /// Maximum explicit amount in a bitcoin `TxOut` pub const MAX_MONEY: u64 = 21_000_000 * 100_000_000; /// Creates a new confidential output that is **not** the last one in the transaction. @@ -474,7 +475,7 @@ impl TxOut { /// Inputs for issuances must be provided in the followed by inputs for input asset. /// /// For example, if the second input contains non-null issuance and re-issuance tokens, - /// the `spent_utxo_secrets` should be of the form [inp_1, inp_2, inp_2_issue, inp2_reissue,...] + /// the `spent_utxo_secrets` should be of the form [`inp_1`, `inp_2`, `inp_2_issue`, `inp2_reissue`,...] /// /// If the issuance or re-issuance is null, it should not be added to `spent_utxo_secrets` /// @@ -486,7 +487,7 @@ impl TxOut { rng: &mut R, secp: &Secp256k1, value: u64, - address: Address, + address: &Address, asset: AssetId, spent_utxo_secrets: &[S], ) -> Result<(Self, AssetBlindingFactor, ValueBlindingFactor, SecretKey), ConfidentialTxOutError> @@ -571,7 +572,7 @@ impl TxOut { Ok(txout) } - /// Convert a explicit TxOut into a Confidential TxOut. + /// Convert a explicit `TxOut` into a Confidential `TxOut`. /// The blinding key is provided by the blinder parameter. /// The initial value of nonce is ignored and is set to the ECDH pubkey /// sampled by the sender. @@ -598,7 +599,7 @@ impl TxOut { self.value .explicit() .ok_or(ConfidentialTxOutError::ExpectedExplicitValue)?, - Address::from_script(&self.script_pubkey, Some(blinder), &AddressParams::ELEMENTS) + &Address::from_script(&self.script_pubkey, Some(blinder), &AddressParams::ELEMENTS) .ok_or(ConfidentialTxOutError::InvalidAddress)?, self.asset .explicit() @@ -638,9 +639,8 @@ impl TxOut { // unspendable. if self.script_pubkey.is_provably_unspendable() { return Err(TxOutError::ZeroValueCommitment); - } else { - return Err(TxOutError::NonUnspendableZeroValue); } + return Err(TxOutError::NonUnspendableZeroValue); } let asset_comm = self.get_asset_gen(secp)?; Ok(PedersenCommitment::new_unblinded(secp, value, asset_comm)) @@ -653,7 +653,7 @@ impl TxOut { /// /// Inputs for issuances must be provided in the followed by inputs for input asset. /// For example, if the second input contains non-null issuance and re-issuance tokens, - /// the `spent_utxo_secrets` should be of the form [inp_1, inp_2, inp_2_issue, inp2_reissue,...] + /// the `spent_utxo_secrets` should be of the form [`inp_1`, `inp_2`, `inp_2_issue`, `inp2_reissue`,...] /// If the issuance or re-issuance is null, it should not be added to `spent_utxo_secrets` /// /// # Returns: @@ -693,7 +693,7 @@ impl TxOut { Ok((txout, out_abf, out_vbf, ephemeral_sk)) } - /// Similar to [TxOut::new_last_confidential], but allows specifying the asset blinding factor + /// Similar to [`TxOut::new_last_confidential`], but allows specifying the asset blinding factor /// and the ephemeral key. The value-blinding factor is computed adaptively #[allow(clippy::too_many_arguments)] pub fn with_secrets_last( @@ -714,12 +714,13 @@ impl TxOut { { let value_blind_inputs = spent_utxo_secrets .iter() - .map(|utxo_sec| utxo_sec.value_blind_inputs()) + .map(TxOutSecrets::value_blind_inputs) .collect::>(); let value_blind_outputs = output_secrets .iter() - .map(|e| e.value_blind_inputs()) + .copied() + .map(TxOutSecrets::value_blind_inputs) .collect::>(); let out_vbf = ValueBlindingFactor::last( @@ -892,7 +893,7 @@ impl TxIn { /// Blind issuances for this [`TxIn`]. Asset amount and token amount must be /// set in [`AssetIssuance`](crate::AssetIssuance) field for this input /// - /// Returns (issuance_blinding_factor, issue_blind_sec_key, token_blinding_factor, token_blind_sec_key) + /// Returns (`issuance_blinding_factor`, `issue_blind_sec_key`, `token_blinding_factor`, `token_blind_sec_key`) pub fn blind_issuances( &mut self, secp: &Secp256k1, @@ -937,9 +938,9 @@ impl Transaction { /// equation for Confidential transactions holds. /// i.e Sum of inputs = Sum of outputs + fees. /// And the corresponding surjection/rangeproofs are correct. - /// For checking of surjection proofs and amounts, spent_utxos parameter + /// For checking of surjection proofs and amounts, `spent_utxos` parameter /// should contain information about the prevouts. Note that the order of - /// spent_utxos should be consistent with transaction inputs. + /// `spent_utxos` should be consistent with transaction inputs. /// ## Examples /// /// ``` @@ -1001,19 +1002,19 @@ impl Transaction { (inp.asset_issuance.amount, asset_id), (inp.asset_issuance.inflation_keys, token_id), ]; - for (amt, asset) in arr.iter() { + for (amt, asset) in &arr { match amt { - Value::Null => continue, + Value::Null => {}, Value::Explicit(v) => { let gen = Generator::new_unblinded(secp, asset.into_tag()); domain.push(gen); let comm = PedersenCommitment::new_unblinded(secp, *v, gen); - in_commits.push(comm) + in_commits.push(comm); } Value::Confidential(comm) => { let gen = Generator::new_unblinded(secp, asset.into_tag()); domain.push(gen); - in_commits.push(*comm) + in_commits.push(*comm); } } } @@ -1138,7 +1139,7 @@ impl Transaction { rng, secp, out.value.explicit().unwrap(), - address, + &address, out.asset.explicit().unwrap(), spent_utxo_secrets, )?; @@ -1200,9 +1201,9 @@ pub enum BlindError { TooFewBlindingOutputs, /// All outputs must be explicit asset/amounts MustHaveAllExplicitTxOuts, - /// General TxOut errors + /// General `TxOut` errors ConfidentialTxOutError(ConfidentialTxOutError), - /// No Issuances to blind in this TxIn + /// No Issuances to blind in this `TxIn` NoIssuanceToBlind, /// Zero Value Blinding not allowed ZeroValueBlindingNotAllowed, @@ -1278,7 +1279,7 @@ pub trait BlindValueProofs: Sized { } impl BlindValueProofs for RangeProof { - /// Outputs a `[RangeProof]` that blinded value_commit + /// Outputs a [`RangeProof`] that blinded `value_commit` /// corresponds to explicit value fn blind_value_proof( rng: &mut R, @@ -1509,7 +1510,7 @@ mod tests { &mut thread_rng(), SECP256K1, value, - address, + &address, asset, &spent_utxo_secrets, ) diff --git a/src/block.rs b/src/block.rs index 0ab9c623..f16f790f 100644 --- a/src/block.rs +++ b/src/block.rs @@ -463,7 +463,7 @@ mod tests { block.block_hash().to_string(), "287ca47e8da47eb8c28d870663450bb026922eadb30a1b2f8293e6e9d1ca5322" ); - assert_eq!(block.header.version, 0x20000000); + assert_eq!(block.header.version, 0x2000_0000); assert_eq!(block.header.height, 2); assert_eq!(block.txdata.len(), 1); assert_eq!(block.size(), serialize(&block).len()); @@ -675,7 +675,7 @@ mod tests { block.block_hash().to_string(), "e935d06cf3a616eb4d551338598b84daa0e8592ed14673263597f6af4b4a6ea6" ); - assert_eq!(block.header.version, 0x20000000); + assert_eq!(block.header.version, 0x2000_0000); assert_eq!(block.header.height, 1); assert_eq!(block.txdata.len(), 3); assert_eq!(block.size(), serialize(&block).len()); @@ -706,7 +706,7 @@ mod tests { block.block_hash().to_string(), "bcc6eb2ab6c97b9b4590825b9136f100b22e090c0469818572b8b93926a79f28" ); - assert_eq!(block.header.version, 0x20000000); + assert_eq!(block.header.version, 0x2000_0000); if let ExtData::Proof { challenge, solution } = block.header.ext { assert_eq!(challenge.len(), 1 + 3 * 34 + 2); assert_eq!(solution.len(), 144); @@ -727,7 +727,7 @@ mod tests { } else { panic!("Current block dynafed params not compact"); } - if let dynafed::Params::Null { .. } = proposed { + if let dynafed::Params::Null = proposed { /* pass */ } else { panic!("Proposed block dynafed params not compact"); @@ -740,7 +740,7 @@ mod tests { block.block_hash().to_string(), "4961df970cf12d789383974e6ab439f780d956b5a50162ca9d281362e46c605a" ); - assert_eq!(block.header.version, 0x20000000); + assert_eq!(block.header.version, 0x2000_0000); // Full current and proposal let block: Block = hex_deserialize!("\ diff --git a/src/confidential.rs b/src/confidential.rs index ba6c8543..34f1a564 100644 --- a/src/confidential.rs +++ b/src/confidential.rs @@ -33,9 +33,10 @@ use crate::encode::{self, Decodable, Encodable}; use crate::issuance::AssetId; /// A CT commitment to an amount -#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq, PartialOrd, Ord)] pub enum Value { /// No value + #[default] Null, /// Value is explicitly encoded Explicit(u64), @@ -99,7 +100,7 @@ impl Value { } /// Returns the explicit inner value. - /// Returns [None] if [Value::is_explicit] returns false. + /// Returns [None] if [`Value::is_explicit`] returns false. pub fn explicit(&self) -> Option { match *self { Value::Explicit(i) => Some(i), @@ -108,7 +109,7 @@ impl Value { } /// Returns the confidential commitment in case of a confidential value. - /// Returns [None] if [Value::is_confidential] returns false. + /// Returns [None] if [`Value::is_confidential`] returns false. pub fn commitment(&self) -> Option { match *self { Value::Confidential(i) => Some(i), @@ -133,12 +134,6 @@ impl fmt::Display for Value { } } -impl Default for Value { - fn default() -> Self { - Value::Null - } -} - impl Encodable for Value { fn consensus_encode(&self, mut s: S) -> Result { match *self { @@ -252,9 +247,10 @@ impl<'de> Deserialize<'de> for Value { } /// A CT commitment to an asset -#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq, PartialOrd, Ord)] pub enum Asset { /// No value + #[default] Null, /// Asset entropy is explicitly encoded Explicit(AssetId), @@ -306,7 +302,7 @@ impl Asset { } /// Returns the explicit inner value. - /// Returns [None] if [Asset::is_explicit] returns false. + /// Returns [None] if [`Asset::is_explicit`] returns false. pub fn explicit(&self) -> Option { match *self { Asset::Explicit(i) => Some(i), @@ -315,7 +311,7 @@ impl Asset { } /// Returns the confidential commitment in case of a confidential value. - /// Returns [None] if [Asset::is_confidential] returns false. + /// Returns [None] if [`Asset::is_confidential`] returns false. pub fn commitment(&self) -> Option { match *self { Asset::Confidential(i) => Some(i), @@ -360,13 +356,6 @@ impl fmt::Display for Asset { } } -impl Default for Asset { - fn default() -> Self { - Asset::Null - } -} - - impl Encodable for Asset { fn consensus_encode(&self, mut s: S) -> Result { match *self { @@ -481,9 +470,10 @@ impl<'de> Deserialize<'de> for Asset { } /// A CT commitment to an output nonce (i.e. a public key) -#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq, PartialOrd, Ord)] pub enum Nonce { /// No value + #[default] Null, /// There should be no such thing as an "explicit nonce", but Elements will deserialize /// such a thing (and insists that its size be 32 bytes). So we stick a 32-byte type here @@ -504,7 +494,7 @@ impl Nonce { Self::with_ephemeral_sk(secp, ephemeral_sk, receiver_blinding_pk) } - /// Similar to [Nonce::new_confidential], but with a given `ephemeral_sk` + /// Similar to [`Nonce::new_confidential`], but with a given `ephemeral_sk` /// instead of sampling it from rng. pub fn with_ephemeral_sk( secp: &Secp256k1, @@ -579,7 +569,7 @@ impl Nonce { } /// Returns the explicit inner value. - /// Returns [None] if [Nonce::is_explicit] returns false. + /// Returns [None] if [`Nonce::is_explicit`] returns false. pub fn explicit(&self) -> Option<[u8; 32]> { match *self { Nonce::Explicit(i) => Some(i), @@ -588,7 +578,7 @@ impl Nonce { } /// Returns the confidential commitment in case of a confidential value. - /// Returns [None] if [Nonce::is_confidential] returns false. + /// Returns [None] if [`Nonce::is_confidential`] returns false. pub fn commitment(&self) -> Option { match *self { Nonce::Confidential(i) => Some(i), @@ -608,7 +598,7 @@ impl fmt::Display for Nonce { match *self { Nonce::Null => f.write_str("null"), Nonce::Explicit(n) => { - for b in n.iter() { + for b in &n { write!(f, "{:02x}", b)?; } Ok(()) @@ -618,12 +608,6 @@ impl fmt::Display for Nonce { } } -impl Default for Nonce { - fn default() -> Self { - Nonce::Null - } -} - impl Encodable for Nonce { fn consensus_encode(&self, mut s: S) -> Result { match *self { @@ -756,7 +740,7 @@ impl AssetBlindingFactor { self.0 } - /// Get a unblinded/zero AssetBlinding factor + /// Get a unblinded/zero `AssetBlinding` factor pub fn zero() -> Self { AssetBlindingFactor(ZERO_TWEAK) } @@ -857,13 +841,14 @@ impl<'de> Deserialize<'de> for AssetBlindingFactor { where E: ::serde::de::Error, { - if v.len() != 32 { - Err(E::invalid_length(v.len(), &stringify!($len))) - } else { - let mut ret = [0; 32]; - ret.copy_from_slice(v); - let inner = Tweak::from_inner(ret).map_err(E::custom)?; - Ok(AssetBlindingFactor(inner)) + use core::convert::TryFrom; + + match <[u8; 32]>::try_from(v) { + Ok(ret) => { + let inner = Tweak::from_inner(ret).map_err(E::custom)?; + Ok(AssetBlindingFactor(inner)) + } + Err(_) => Err(E::invalid_length(v.len(), &stringify!($len))), } } } @@ -923,7 +908,7 @@ impl ValueBlindingFactor { self.0 } - /// Get a unblinded/zero AssetBlinding factor + /// Get a unblinded/zero `AssetBlinding` factor pub fn zero() -> Self { ValueBlindingFactor(ZERO_TWEAK) } @@ -1060,13 +1045,14 @@ impl<'de> Deserialize<'de> for ValueBlindingFactor { where E: ::serde::de::Error, { - if v.len() != 32 { - Err(E::invalid_length(v.len(), &stringify!($len))) - } else { - let mut ret = [0; 32]; - ret.copy_from_slice(v); - let inner = Tweak::from_inner(ret).map_err(E::custom)?; - Ok(ValueBlindingFactor(inner)) + use core::convert::TryFrom; + + match <[u8; 32]>::try_from(v) { + Ok(ret) => { + let inner = Tweak::from_inner(ret).map_err(E::custom)?; + Ok(ValueBlindingFactor(inner)) + } + Err(_) => Err(E::invalid_length(v.len(), &stringify!($len))), } } } @@ -1182,7 +1168,7 @@ mod tests { &[ Token::Seq { len: Some(2) }, Token::U8(1), - Token::U64(63601271583539200), + Token::U64(63_601_271_583_539_200), Token::SeqEnd ] ); diff --git a/src/dynafed.rs b/src/dynafed.rs index 2c402825..bd78eab6 100644 --- a/src/dynafed.rs +++ b/src/dynafed.rs @@ -96,7 +96,7 @@ pub struct FullParams { } impl FullParams { - /// Construct a set of FullParams + /// Construct a set of `FullParams` pub fn new( signblockscript: Script, signblock_witness_limit: u32, @@ -131,7 +131,7 @@ impl FullParams { crate::fast_merkle_root::fast_merkle_root(&leaves[..]) } - /// Calculate the root of this [FullParams]. + /// Calculate the root of this [`FullParams`]. pub fn calculate_root(&self) -> sha256::Midstate { fn serialize_hash(obj: &E) -> sha256d::Hash { let mut engine = sha256d::Hash::engine(); @@ -162,7 +162,7 @@ impl FullParams { } } - /// Format for [fmt::Debug]. + /// Format for [`fmt::Debug`]. fn fmt_debug(&self, f: &mut fmt::Formatter, name: &'static str) -> fmt::Result { let mut s = f.debug_struct(name); s.field("signblockscript", &HexBytes(&self.signblockscript[..])); @@ -216,9 +216,10 @@ impl Decodable for FullParams { } /// Dynamic federations parameters, as encoded in a block header -#[derive(Clone, Eq, Hash, PartialEq, PartialOrd, Ord)] +#[derive(Clone, Default, Eq, Hash, PartialEq, PartialOrd, Ord)] pub enum Params { /// Null entry, used to signal "no vote" as a proposal + #[default] Null, /// Compact params where the fedpeg data and extension space /// are not included, and are assumed to be equal to the values @@ -252,7 +253,7 @@ impl fmt::Debug for Params { } impl Params { - /// Check whether this is [Params::Null]. + /// Check whether this is [`Params::Null`]. pub fn is_null(&self) -> bool { match *self { Params::Null => true, @@ -261,7 +262,7 @@ impl Params { } } - /// Check whether this is [Params::Compact]. + /// Check whether this is [`Params::Compact`]. pub fn is_compact(&self) -> bool { match *self { Params::Null => false, @@ -270,7 +271,7 @@ impl Params { } } - /// Check whether this is [Params::Full]. + /// Check whether this is [`Params::Full`]. pub fn is_full(&self) -> bool { match *self { Params::Null => false, @@ -279,7 +280,7 @@ impl Params { } } - /// Get the signblockscript. Is [None] for [Params::Null] params. + /// Get the signblockscript. Is [None] for [`Params::Null`] params. pub fn signblockscript(&self) -> Option<&Script> { match *self { Params::Null => None, @@ -288,7 +289,7 @@ impl Params { } } - /// Get the signblock_witness_limit. Is [None] for [Params::Null] params. + /// Get the `signblock_witness_limit`. Is [None] for [`Params::Null`] params. pub fn signblock_witness_limit(&self) -> Option { match *self { Params::Null => None, @@ -297,7 +298,7 @@ impl Params { } } - /// Get the fedpeg_program. Is [None] for non-[Params::Full] params. + /// Get the `fedpeg_program`. Is [None] for non-[`Params::Full`] params. pub fn fedpeg_program(&self) -> Option<&bitcoin::ScriptBuf> { match *self { Params::Null => None, @@ -306,7 +307,7 @@ impl Params { } } - /// Get the fedpegscript. Is [None] for non-[Params::Full] params. + /// Get the fedpegscript. Is [None] for non-[`Params::Full`] params. pub fn fedpegscript(&self) -> Option<&Vec> { match *self { Params::Null => None, @@ -315,7 +316,7 @@ impl Params { } } - /// Get the extension_space. Is [None] for non-[Params::Full] params. + /// Get the `extension_space`. Is [None] for non-[`Params::Full`] params. pub fn extension_space(&self) -> Option<&Vec>> { match *self { Params::Null => None, @@ -324,7 +325,7 @@ impl Params { } } - /// Get the elided_root. Is [None] for non-[Params::Compact] params. + /// Get the `elided_root`. Is [None] for non-[`Params::Compact`] params. pub fn elided_root(&self) -> Option<&sha256::Midstate> { match *self { Params::Null => None, @@ -398,12 +399,6 @@ impl Params { } } -impl Default for Params { - fn default() -> Params { - Params::Null - } -} - #[cfg(feature = "serde")] impl<'de> Deserialize<'de> for Params { fn deserialize>(d: D) -> Result { diff --git a/src/encode.rs b/src/encode.rs index 08735f10..6868cee2 100644 --- a/src/encode.rs +++ b/src/encode.rs @@ -59,7 +59,7 @@ pub enum Error { HexError(crate::hex::Error), /// Got a time-based locktime when expecting a height-based one, or vice-versa BadLockTime(crate::LockTime), - /// VarInt was encoded in a non-minimal way. + /// `VarInt` was encoded in a non-minimal way. NonMinimalVarInt, } @@ -76,7 +76,7 @@ impl fmt::Display for Error { "oversized vector allocation: requested {}, maximum {}", r, m ), - Error::ParseFailed(ref e) => write!(f, "parse failed: {}", e), + Error::ParseFailed(e) => write!(f, "parse failed: {}", e), Error::UnexpectedEOF => write!(f, "unexpected EOF"), Error::InvalidConfidentialPrefix(p) => { write!(f, "invalid confidential prefix: 0x{:02x}", p) @@ -260,7 +260,7 @@ impl VarInt { match self.0 { 0..=0xFC => 1, 0xFD..=0xFFFF => 3, - 0x10000..=0xFFFFFFFF => 5, + 0x10000..=0xFFFF_FFFF => 5, _ => 9, } } diff --git a/src/endian.rs b/src/endian.rs index 6a009281..fec6eed9 100644 --- a/src/endian.rs +++ b/src/endian.rs @@ -20,6 +20,6 @@ mod tests { #[test] fn endianness_test() { - assert_eq!(u32_to_array_le(0xdeadbeef), [0xef, 0xbe, 0xad, 0xde]); + assert_eq!(u32_to_array_le(0xdead_beef), [0xef, 0xbe, 0xad, 0xde]); } } diff --git a/src/error.rs b/src/error.rs index 0d56617f..6957ee8a 100644 --- a/src/error.rs +++ b/src/error.rs @@ -2,7 +2,7 @@ pub use crate::parse::ParseIntError; -/// Impls std::error::Error for the specified type with appropriate attributes, possibly returning +/// Impls `std::error::Error` for the specified type with appropriate attributes, possibly returning /// source. macro_rules! impl_std_error { // No source available diff --git a/src/ext.rs b/src/ext.rs index b7c1c543..d70e1556 100644 --- a/src/ext.rs +++ b/src/ext.rs @@ -100,7 +100,7 @@ impl WriteExt for W { } #[inline] fn emit_bool(&mut self, v: bool) -> Result<(), io::Error> { - self.write_all(&[v as u8]) + self.write_all(&[u8::from(v)]) } #[inline] fn emit_slice(&mut self, v: &[u8]) -> Result { @@ -119,7 +119,7 @@ impl WriteExt for W { self.emit_u16(i as u16)?; Ok(3) } - i @ 0x10000..=0xFFFFFFFF => { + i @ 0x10000..=0xFFFF_FFFF => { self.emit_u8(0xFE)?; self.emit_u32(i as u32)?; Ok(5) @@ -166,7 +166,7 @@ impl ReadExt for R { match self.read_u8()? { 0xFF => { let x = self.read_u64()?; - if x < 0x100000000 { + if x < 0x1_0000_0000 { Err(encode::Error::NonMinimalVarInt) } else { Ok(x) @@ -177,7 +177,7 @@ impl ReadExt for R { if x < 0x10000 { Err(encode::Error::NonMinimalVarInt) } else { - Ok(x as u64) + Ok(u64::from(x)) } } 0xFD => { @@ -185,10 +185,10 @@ impl ReadExt for R { if x < 0xFD { Err(encode::Error::NonMinimalVarInt) } else { - Ok(x as u64) + Ok(u64::from(x)) } } - n => Ok(n as u64), + n => Ok(u64::from(n)), } } } diff --git a/src/fast_merkle_root.rs b/src/fast_merkle_root.rs index 098bbde1..4d88ea81 100644 --- a/src/fast_merkle_root.rs +++ b/src/fast_merkle_root.rs @@ -29,7 +29,7 @@ fn sha256midstate(left: &[u8], right: &[u8]) -> sha256::Midstate { /// Note that the merkle root calculated with this method is not the same as the /// one computed by a normal SHA256(d) merkle root. pub fn fast_merkle_root(leaves: &[[u8; 32]]) -> sha256::Midstate { - let mut result_hash = Default::default(); + let mut result_hash = sha256::Midstate::default(); // Implementation based on ComputeFastMerkleRoot method in Elements Core. if leaves.is_empty() { return result_hash; diff --git a/src/hash_types.rs b/src/hash_types.rs index 8220dd7f..6231c34b 100644 --- a/src/hash_types.rs +++ b/src/hash_types.rs @@ -15,7 +15,7 @@ //! File defines types for hashes used throughout the library. //! //! These types are needed in order -//! to avoid mixing data of the same hash format (like SHA256d) but of different meaning +//! to avoid mixing data of the same hash format (like `SHA256d`) but of different meaning //! (transaction id, block hash etc). use crate::hashes::{hash160, hash_newtype, sha256, sha256d, Hash}; diff --git a/src/internal_macros.rs b/src/internal_macros.rs index 1936c6c2..aa4c0337 100644 --- a/src/internal_macros.rs +++ b/src/internal_macros.rs @@ -211,7 +211,7 @@ macro_rules! serde_string_impl { }; } -/// A combination of serde_struct_impl and serde_string_impl where string is +/// A combination of `serde_struct_impl` and `serde_string_impl` where string is /// used for human-readable serialization and struct is used for /// non-human-readable serialization. macro_rules! serde_struct_human_string_impl { diff --git a/src/issuance.rs b/src/issuance.rs index de478e7b..d6387617 100644 --- a/src/issuance.rs +++ b/src/issuance.rs @@ -75,17 +75,17 @@ impl AssetId { 0x3d, 0x1c, 0x04, 0xed, 0xe9, 0x79, 0x02, 0x6f, ])); - /// Create an [AssetId] from its inner type. + /// Create an [`AssetId`] from its inner type. pub const fn from_inner(midstate: sha256::Midstate) -> AssetId { AssetId(midstate) } - /// Convert the [AssetId] into its inner type. + /// Convert the [`AssetId`] into its inner type. pub fn into_inner(self) -> sha256::Midstate { self.0 } - /// Copies a byte slice into an AssetId object + /// Copies a byte slice into an `AssetId` object pub fn from_slice(sl: &[u8]) -> Result { sha256::Midstate::from_slice(sl).map(AssetId) } @@ -244,12 +244,10 @@ impl<'de> ::serde::Deserialize<'de> for AssetId { where E: ::serde::de::Error, { - if v.len() != 32 { - Err(E::invalid_length(v.len(), &stringify!($len))) - } else { - let mut ret = [0; 32]; - ret.copy_from_slice(v); - Ok(AssetId(sha256::Midstate::from_byte_array(ret))) + use core::convert::TryFrom; + match <[u8; 32]>::try_from(v) { + Ok(ret) => Ok(AssetId(sha256::Midstate::from_byte_array(ret))), + Err(_) => Err(E::invalid_length(v.len(), &stringify!($len))), } } } diff --git a/src/locktime.rs b/src/locktime.rs index 5ffddf8c..e93f10b6 100644 --- a/src/locktime.rs +++ b/src/locktime.rs @@ -11,7 +11,7 @@ // If not, see . // -//! Provides type [`LockTime`] that implements the logic around nLockTime/OP_CHECKLOCKTIMEVERIFY. +//! Provides type [`LockTime`] that implements the logic around `nLockTime/OP_CHECKLOCKTIMEVERIFY`. //! //! There are two types of lock time: lock-by-blockheight and lock-by-blocktime, distinguished by //! whether `LockTime < LOCKTIME_THRESHOLD`. @@ -45,7 +45,7 @@ pub const LOCK_TIME_THRESHOLD: u32 = 500_000_000; /// A lock time value, representing either a block height or a UNIX timestamp (seconds since epoch). /// /// Used for transaction lock time (`nLockTime` in Bitcoin Core and [`crate::Transaction::lock_time`] -/// in this library) and also for the argument to opcode 'OP_CHECKLOCKTIMEVERIFY`. +/// in this library) and also for the argument to opcode `OP_CHECKLOCKTIMEVERIFY`. /// /// ### Relevant BIPs /// @@ -54,13 +54,13 @@ pub const LOCK_TIME_THRESHOLD: u32 = 500_000_000; /// /// # Examples /// ``` -/// # use elements::{LockTime, LockTime::*}; +/// # use elements::LockTime; /// # let n = LockTime::from_consensus(100); // n OP_CHECKLOCKTIMEVERIFY /// # let lock_time = LockTime::from_consensus(100); // nLockTime /// // To compare lock times there are various `is_satisfied_*` methods, you may also use: /// let is_satisfied = match (n, lock_time) { -/// (Blocks(n), Blocks(lock_time)) => n <= lock_time, -/// (Seconds(n), Seconds(lock_time)) => n <= lock_time, +/// (LockTime::Blocks(n), LockTime::Blocks(lock_time)) => n <= lock_time, +/// (LockTime::Seconds(n), LockTime::Seconds(lock_time)) => n <= lock_time, /// _ => panic!("handle invalid comparison error"), /// }; /// ``` @@ -100,7 +100,7 @@ impl LockTime { /// transaction with nLocktime==0 is able to be included immediately in any block. pub const ZERO: LockTime = LockTime::Blocks(Height(0)); - /// Constructs a `LockTime` from an nLockTime value or the argument to OP_CHEKCLOCKTIMEVERIFY. + /// Constructs a `LockTime` from an nLockTime value or the argument to `OP_CHEKCLOCKTIMEVERIFY`. /// /// # Examples /// @@ -197,11 +197,9 @@ impl LockTime { /// ```` #[inline] pub fn is_satisfied_by(&self, height: Height, time: Time) -> bool { - use LockTime::*; - match *self { - Blocks(n) => n <= height, - Seconds(n) => n <= time, + LockTime::Blocks(n) => n <= height, + LockTime::Seconds(n) => n <= time, } } @@ -216,13 +214,13 @@ impl LockTime { /// # Examples /// /// ```rust - /// # use elements::{LockTime, LockTime::*}; + /// # use elements::LockTime; /// # let n = LockTime::from_consensus(100); // n OP_CHECKLOCKTIMEVERIFY /// # let lock_time = LockTime::from_consensus(100); // nLockTime /// /// let is_satisfied = match (n, lock_time) { - /// (Blocks(n), Blocks(lock_time)) => n <= lock_time, - /// (Seconds(n), Seconds(lock_time)) => n <= lock_time, + /// (LockTime::Blocks(n), LockTime::Blocks(lock_time)) => n <= lock_time, + /// (LockTime::Seconds(n), LockTime::Seconds(lock_time)) => n <= lock_time, /// _ => panic!("invalid comparison"), /// }; /// @@ -254,11 +252,9 @@ impl From