diff --git a/Cargo.toml b/Cargo.toml index db18ff4d..5298527d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,3 @@ [workspace] -members = ["bitcoin"] +members = ["bitcoin", "internals"] exclude = ["embedded", "fuzz"] diff --git a/bitcoin/Cargo.toml b/bitcoin/Cargo.toml index 0a371932..e8717845 100644 --- a/bitcoin/Cargo.toml +++ b/bitcoin/Cargo.toml @@ -25,7 +25,7 @@ secp-recovery = ["secp256k1/recovery"] # The no-std feature doesn't disable std - you need to turn off the std feature for that by disabling default. # Instead no-std enables additional features required for this crate to be usable without std. # As a result, both can be enabled without conflict. -std = ["secp256k1/std", "bitcoin_hashes/std", "bech32/std"] +std = ["secp256k1/std", "bitcoin_hashes/std", "bech32/std", "bitcoin-internals/std"] no-std = ["hashbrown", "core2/alloc", "bitcoin_hashes/alloc", "secp256k1/alloc"] [package.metadata.docs.rs] @@ -33,6 +33,7 @@ features = [ "std", "secp-recovery", "base64", "rand", "serde", "bitcoinconsensu rustdoc-args = ["--cfg", "docsrs"] [dependencies] +bitcoin-internals = { path = "../internals" } bech32 = { version = "0.9.0", default-features = false } bitcoin_hashes = { version = "0.11.0", default-features = false } secp256k1 = { version = "0.24.0", default-features = false, features = ["bitcoin_hashes"] } diff --git a/bitcoin/src/address.rs b/bitcoin/src/address.rs index 60aaaa80..5534e263 100644 --- a/bitcoin/src/address.rs +++ b/bitcoin/src/address.rs @@ -27,6 +27,7 @@ use core::fmt; use core::str::FromStr; use bech32; +use bitcoin_internals::write_err; use secp256k1::{Secp256k1, Verification, XOnlyPublicKey}; use crate::blockdata::constants::{ @@ -38,7 +39,7 @@ use crate::blockdata::{opcodes, script}; use crate::error::ParseIntError; use crate::hash_types::{PubkeyHash, ScriptHash}; use crate::hashes::{sha256, Hash, HashEngine}; -use crate::internal_macros::{serde_string_impl, write_err}; +use crate::internal_macros::serde_string_impl; use crate::network::constants::Network; use crate::prelude::*; use crate::util::base58; diff --git a/bitcoin/src/bip158.rs b/bitcoin/src/bip158.rs index 25fa0d8a..7692d5a2 100644 --- a/bitcoin/src/bip158.rs +++ b/bitcoin/src/bip158.rs @@ -42,6 +42,8 @@ use core::cmp::{self, Ordering}; use core::fmt::{self, Display, Formatter}; +use bitcoin_internals::write_err; + use crate::blockdata::block::Block; use crate::blockdata::script::Script; use crate::blockdata::transaction::OutPoint; @@ -49,7 +51,6 @@ use crate::consensus::encode::VarInt; use crate::consensus::{Decodable, Encodable}; use crate::hash_types::{BlockHash, FilterHash, FilterHeader}; use crate::hashes::{siphash24, Hash}; -use crate::internal_macros::write_err; use crate::io; use crate::prelude::*; use crate::util::endian; @@ -273,7 +274,8 @@ impl GcsFilterReader { let reader = &mut decoder; // map hashes to [0, n_elements << grp] let nm = n_elements.0 * self.m; - let mut mapped = query.map(|e| map_to_range(self.filter.hash(e.borrow()), nm)).collect::>(); + let mut mapped = + query.map(|e| map_to_range(self.filter.hash(e.borrow()), nm)).collect::>(); // sort mapped.sort_unstable(); if mapped.is_empty() { @@ -317,7 +319,8 @@ impl GcsFilterReader { let reader = &mut decoder; // map hashes to [0, n_elements << grp] let nm = n_elements.0 * self.m; - let mut mapped = query.map(|e| map_to_range(self.filter.hash(e.borrow()), nm)).collect::>(); + let mut mapped = + query.map(|e| map_to_range(self.filter.hash(e.borrow()), nm)).collect::>(); // sort mapped.sort_unstable(); mapped.dedup(); diff --git a/bitcoin/src/blockdata/locktime/absolute.rs b/bitcoin/src/blockdata/locktime/absolute.rs index 0bc4c441..8543a808 100644 --- a/bitcoin/src/blockdata/locktime/absolute.rs +++ b/bitcoin/src/blockdata/locktime/absolute.rs @@ -12,11 +12,12 @@ use core::cmp::{PartialOrd, Ordering}; use core::convert::TryFrom; use core::str::FromStr; +use bitcoin_internals::write_err; + use crate::consensus::encode::{self, Decodable, Encodable}; use crate::error::ParseIntError; use crate::io::{self, Read, Write}; use crate::prelude::*; -use crate::internal_macros::write_err; use crate::parse::{self, impl_parse_str_through_int}; /// The Threshold for deciding whether a lock time value is a height or a time (see [Bitcoin Core]). diff --git a/bitcoin/src/blockdata/script.rs b/bitcoin/src/blockdata/script.rs index 4ac3e71a..11be7899 100644 --- a/bitcoin/src/blockdata/script.rs +++ b/bitcoin/src/blockdata/script.rs @@ -20,7 +20,7 @@ use core::{fmt, default::Default}; use core::ops::Index; use crate::internal_macros::debug_from_display; #[cfg(feature = "bitcoinconsensus")] -use crate::internal_macros::write_err; +use bitcoin_internals::write_err; #[cfg(feature = "serde")] use serde; diff --git a/bitcoin/src/blockdata/transaction.rs b/bitcoin/src/blockdata/transaction.rs index 7a0dd151..3b499df7 100644 --- a/bitcoin/src/blockdata/transaction.rs +++ b/bitcoin/src/blockdata/transaction.rs @@ -18,6 +18,8 @@ use crate::io; use core::{fmt, str, default::Default}; use core::convert::TryFrom; +use bitcoin_internals::write_err; + use crate::hashes::{self, Hash, sha256d}; use crate::hashes::hex::FromHex; @@ -30,7 +32,7 @@ use crate::blockdata::locktime::relative; use crate::consensus::{encode, Decodable, Encodable}; use crate::hash_types::{Sighash, Txid, Wtxid}; use crate::VarInt; -use crate::internal_macros::{impl_consensus_encoding, serde_struct_human_string_impl, write_err}; +use crate::internal_macros::{impl_consensus_encoding, serde_struct_human_string_impl}; use crate::parse::impl_parse_str_through_int; #[cfg(doc)] diff --git a/bitcoin/src/consensus/encode.rs b/bitcoin/src/consensus/encode.rs index e2997225..e1afd10a 100644 --- a/bitcoin/src/consensus/encode.rs +++ b/bitcoin/src/consensus/encode.rs @@ -20,9 +20,10 @@ use crate::prelude::*; use core::{fmt, mem, u32, convert::From}; +use bitcoin_internals::write_err; + use crate::hashes::{sha256d, Hash, sha256}; use crate::hash_types::{BlockHash, FilterHash, TxMerkleNode, FilterHeader}; -use crate::internal_macros::write_err; use crate::io::{self, Cursor, Read}; use crate::util::endian; diff --git a/bitcoin/src/internal_macros.rs b/bitcoin/src/internal_macros.rs index 2e8835ce..bc196c6c 100644 --- a/bitcoin/src/internal_macros.rs +++ b/bitcoin/src/internal_macros.rs @@ -626,26 +626,6 @@ macro_rules! user_enum { } pub(crate) use user_enum; -/// Formats error. If `std` feature is OFF appends error source (delimited by `: `). We do this -/// because `e.source()` is only available in std builds, without this macro the error source is -/// lost for no-std builds. -macro_rules! write_err { - ($writer:expr, $string:literal $(, $args:expr)*; $source:expr) => { - { - #[cfg(feature = "std")] - { - let _ = &$source; // Prevents clippy warnings. - write!($writer, $string $(, $args)*) - } - #[cfg(not(feature = "std"))] - { - write!($writer, concat!($string, ": {}") $(, $args)*, $source) - } - } - } -} -pub(crate) use write_err; - /// Asserts a boolean expression at compile time. macro_rules! const_assert { ($x:expr) => {{ diff --git a/bitcoin/src/parse.rs b/bitcoin/src/parse.rs index 3b352d15..fd69cbf2 100644 --- a/bitcoin/src/parse.rs +++ b/bitcoin/src/parse.rs @@ -2,8 +2,9 @@ use core::convert::TryFrom; use core::fmt; use core::str::FromStr; +use bitcoin_internals::write_err; + use crate::error::impl_std_error; -use crate::internal_macros::write_err; use crate::prelude::*; /// Error with rich context returned when a string can't be parsed as an integer. diff --git a/bitcoin/src/util/base58.rs b/bitcoin/src/util/base58.rs index d548f116..7fcc78a8 100644 --- a/bitcoin/src/util/base58.rs +++ b/bitcoin/src/util/base58.rs @@ -11,11 +11,11 @@ use crate::prelude::*; use core::{fmt, str, iter, slice}; +use bitcoin_internals::write_err; use crate::hashes::{sha256d, Hash, hex}; use secp256k1; use crate::util::{endian, key}; -use crate::internal_macros::write_err; /// An error that might occur during base58 decoding #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)] diff --git a/bitcoin/src/util/bip32.rs b/bitcoin/src/util/bip32.rs index 9f18916d..a6d1a17c 100644 --- a/bitcoin/src/util/bip32.rs +++ b/bitcoin/src/util/bip32.rs @@ -14,6 +14,7 @@ use core::{fmt, str::FromStr, default::Default}; use core::ops::Index; #[cfg(feature = "serde")] use serde; +use bitcoin_internals::write_err; use crate::hash_types::XpubIdentifier; use crate::hashes::{sha512, Hash, HashEngine, Hmac, HmacEngine, hex}; use secp256k1::{self, Secp256k1, XOnlyPublicKey}; @@ -21,7 +22,7 @@ use secp256k1::{self, Secp256k1, XOnlyPublicKey}; use crate::network::constants::Network; use crate::util::{base58, endian, key}; use crate::util::key::{PublicKey, PrivateKey, KeyPair}; -use crate::internal_macros::{impl_array_newtype, impl_bytes_newtype, serde_string_impl, write_err}; +use crate::internal_macros::{impl_array_newtype, impl_bytes_newtype, serde_string_impl}; /// A chain code #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/bitcoin/src/util/ecdsa.rs b/bitcoin/src/util/ecdsa.rs index 50116723..682ab298 100644 --- a/bitcoin/src/util/ecdsa.rs +++ b/bitcoin/src/util/ecdsa.rs @@ -8,11 +8,11 @@ use core::str::FromStr; use core::{fmt, iter}; +use bitcoin_internals::write_err; use secp256k1; use crate::prelude::*; use crate::hashes::hex::{self, FromHex}; -use crate::internal_macros::write_err; use crate::util::sighash::{EcdsaSighashType, NonStandardSighashType}; /// An ECDSA signature with the corresponding hash type. diff --git a/bitcoin/src/util/key.rs b/bitcoin/src/util/key.rs index ffc1c2e5..c53d648f 100644 --- a/bitcoin/src/util/key.rs +++ b/bitcoin/src/util/key.rs @@ -11,6 +11,7 @@ use crate::prelude::*; use core::{ops, str::FromStr}; use core::fmt::{self, Write}; +use bitcoin_internals::write_err; pub use secp256k1::{self, Secp256k1, XOnlyPublicKey, KeyPair}; use crate::io; @@ -18,7 +19,6 @@ use crate::network::constants::Network; use crate::hashes::{Hash, hash160, hex, hex::FromHex}; use crate::hash_types::{PubkeyHash, WPubkeyHash}; use crate::util::base58; -use crate::internal_macros::write_err; /// A key-related error. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] diff --git a/bitcoin/src/util/misc.rs b/bitcoin/src/util/misc.rs index dea34063..fc1807ca 100644 --- a/bitcoin/src/util/misc.rs +++ b/bitcoin/src/util/misc.rs @@ -27,13 +27,13 @@ mod message_signing { use core::fmt; + use bitcoin_internals::write_err; use crate::hashes::sha256d; use secp256k1; use secp256k1::ecdsa::{RecoveryId, RecoverableSignature}; use crate::util::key::PublicKey; use crate::address::{Address, AddressType}; - use crate::internal_macros::write_err; /// An error used for dealing with Bitcoin Signed Messages. #[cfg_attr(docsrs, doc(cfg(feature = "secp-recovery")))] diff --git a/bitcoin/src/util/mod.rs b/bitcoin/src/util/mod.rs index 52f61ecd..72d66095 100644 --- a/bitcoin/src/util/mod.rs +++ b/bitcoin/src/util/mod.rs @@ -28,8 +28,9 @@ use crate::prelude::*; use crate::io; use core::fmt; +use bitcoin_internals::write_err; + use crate::consensus::encode; -use crate::internal_macros::write_err; /// A trait which allows numbers to act as fixed-size bit arrays pub trait BitArray { diff --git a/bitcoin/src/util/psbt/error.rs b/bitcoin/src/util/psbt/error.rs index 7965e0e6..4424a809 100644 --- a/bitcoin/src/util/psbt/error.rs +++ b/bitcoin/src/util/psbt/error.rs @@ -4,13 +4,14 @@ use crate::prelude::*; use core::fmt; +use bitcoin_internals::write_err; + use crate::blockdata::transaction::Transaction; use crate::consensus::encode; use crate::util::psbt::raw; use crate::hashes; use crate::util::bip32::ExtendedPubKey; -use crate::internal_macros::write_err; /// Enum for marking psbt hash error. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] diff --git a/bitcoin/src/util/psbt/mod.rs b/bitcoin/src/util/psbt/mod.rs index 6e88bd39..99b328ad 100644 --- a/bitcoin/src/util/psbt/mod.rs +++ b/bitcoin/src/util/psbt/mod.rs @@ -207,7 +207,7 @@ mod display_from_str { use core::str::FromStr; use crate::consensus::encode::{Error, self}; use base64::display::Base64Display; - use crate::internal_macros::write_err; + use bitcoin_internals::write_err; /// Error encountered during PSBT decoding from Base64 string. #[derive(Debug)] diff --git a/bitcoin/src/util/schnorr.rs b/bitcoin/src/util/schnorr.rs index 81729e17..7036b6a2 100644 --- a/bitcoin/src/util/schnorr.rs +++ b/bitcoin/src/util/schnorr.rs @@ -9,12 +9,13 @@ use core::fmt; +use bitcoin_internals::write_err; + use crate::prelude::*; use secp256k1::{self, Secp256k1, Verification, constants}; use crate::util::taproot::{TapBranchHash, TapTweakHash}; use crate::SchnorrSighashType; -use crate::internal_macros::write_err; /// Deprecated re-export of [`secp256k1::XOnlyPublicKey`] #[deprecated(since = "0.28.0", note = "Please use `util::key::XOnlyPublicKey` instead")] diff --git a/bitcoin/src/util/taproot.rs b/bitcoin/src/util/taproot.rs index 7e7f9190..7e37e2e3 100644 --- a/bitcoin/src/util/taproot.rs +++ b/bitcoin/src/util/taproot.rs @@ -7,6 +7,7 @@ use crate::prelude::*; use crate::io; +use bitcoin_internals::write_err; use secp256k1::{self, Secp256k1, Scalar}; use core::convert::TryFrom; @@ -17,7 +18,6 @@ use crate::hashes::{sha256, sha256t_hash_newtype, Hash, HashEngine}; use crate::schnorr::{TweakedPublicKey, UntweakedPublicKey, TapTweak}; use crate::util::key::XOnlyPublicKey; use crate::Script; -use crate::internal_macros::write_err; use crate::consensus::Encodable; /// The SHA-256 midstate value for the TapLeaf hash. diff --git a/internals/Cargo.toml b/internals/Cargo.toml new file mode 100644 index 00000000..f23271f6 --- /dev/null +++ b/internals/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "bitcoin-internals" +version = "0.1.0" +authors = ["Andrew Poelstra ", "The Rust Bitcoin developers"] +license = "CC0-1.0" +repository = "https://github.com/rust-bitcoin/rust-bitcoin/" +documentation = "https://docs.rs/bitcoin-internals" +description = "Internal types and macros used by rust-bitcoin ecosystem" +categories = ["cryptography::cryptocurrencies"] +keywords = ["internal"] +readme = "README.md" +edition = "2018" + +# Please don't forget to add relevant features to docs.rs below. +[features] +default = [] +std = [] + +[package.metadata.docs.rs] +features = ["std"] +rustdoc-args = ["--cfg", "docsrs"] + +[dependencies] + +[dev-dependencies] diff --git a/internals/README.md b/internals/README.md new file mode 100644 index 00000000..79aa2980 --- /dev/null +++ b/internals/README.md @@ -0,0 +1,7 @@ +Rust Bitcoin Internals +====================== + +This crate is only meant to be used internally by crates in the +[rust-bitcoin](https://github.com/rust-bitcoin) ecosystem. + +This crate will never be stabilized, depend on it at your own risk. diff --git a/internals/src/error.rs b/internals/src/error.rs new file mode 100644 index 00000000..2f213377 --- /dev/null +++ b/internals/src/error.rs @@ -0,0 +1,29 @@ +// Written by the Rust Bitcoin developers. +// SPDX-License-Identifier: CC0-1.0 + +//! # Error +//! +//! Error handling macros and helpers. +//! + +/// Formats error. +/// +/// If `std` feature is OFF appends error source (delimited by `: `). We do this because +/// `e.source()` is only available in std builds, without this macro the error source is lost for +/// no-std builds. +#[macro_export] +macro_rules! write_err { + ($writer:expr, $string:literal $(, $args:expr)*; $source:expr) => { + { + #[cfg(feature = "std")] + { + let _ = &$source; // Prevents clippy warnings. + write!($writer, $string $(, $args)*) + } + #[cfg(not(feature = "std"))] + { + write!($writer, concat!($string, ": {}") $(, $args)*, $source) + } + } + } +} diff --git a/internals/src/lib.rs b/internals/src/lib.rs new file mode 100644 index 00000000..bad0d8d2 --- /dev/null +++ b/internals/src/lib.rs @@ -0,0 +1,24 @@ +// Written by the Rust Bitcoin developers. +// SPDX-License-Identifier: CC0-1.0 + +//! # Rust Bitcoin Internal +//! +//! This crate is only meant to be used internally by crates in the +//! [rust-bitcoin](https://github.com/rust-bitcoin) ecosystem. +//! + +#![cfg_attr(all(not(feature = "std"), not(test)), no_std)] +// Experimental features we need. +#![cfg_attr(docsrs, feature(doc_cfg))] +// Coding conventions +#![forbid(unsafe_code)] +#![deny(non_upper_case_globals)] +#![deny(non_camel_case_types)] +#![deny(non_snake_case)] +#![deny(unused_mut)] +#![deny(dead_code)] +#![deny(unused_imports)] +#![deny(missing_docs)] +#![deny(unused_must_use)] + +pub mod error;