blockdata: Improve rustdocs

Do an audit of the `blockdata` module and clean up rustdocs.
This commit is contained in:
Tobin C. Harding 2022-10-31 12:23:10 +11:00
parent fb708ca74b
commit 31740710ee
5 changed files with 77 additions and 63 deletions

View File

@ -96,7 +96,7 @@ impl Header {
} }
} }
/// Bitcoin block version number /// Bitcoin block version number.
/// ///
/// Originally used as a protocol version, but repurposed for soft-fork signaling. /// Originally used as a protocol version, but repurposed for soft-fork signaling.
/// ///
@ -146,7 +146,7 @@ impl Version {
self.0 self.0
} }
/// Check whether the version number is signalling a soft fork at the given bit. /// Checks whether the version number is signalling a soft fork at the given bit.
/// ///
/// A block is signalling for a soft fork under BIP-9 if the first 3 bits are `001` and /// A block is signalling for a soft fork under BIP-9 if the first 3 bits are `001` and
/// the version bit for the specific soft fork is toggled on. /// the version bit for the specific soft fork is toggled on.
@ -213,7 +213,7 @@ impl Block {
self.header.block_hash() self.header.block_hash()
} }
/// check if merkle root of header matches merkle root of the transaction list /// Checks if merkle root of header matches merkle root of the transaction list.
pub fn check_merkle_root(&self) -> bool { pub fn check_merkle_root(&self) -> bool {
match self.compute_merkle_root() { match self.compute_merkle_root() {
Some(merkle_root) => self.header.merkle_root == merkle_root, Some(merkle_root) => self.header.merkle_root == merkle_root,

View File

@ -26,21 +26,21 @@ use crate::network::constants::Network;
use crate::pow::CompactTarget; use crate::pow::CompactTarget;
use crate::internal_macros::impl_bytes_newtype; use crate::internal_macros::impl_bytes_newtype;
/// How many satoshis are in "one bitcoin" /// How many satoshis are in "one bitcoin".
pub const COIN_VALUE: u64 = 100_000_000; pub const COIN_VALUE: u64 = 100_000_000;
/// How many seconds between blocks we expect on average /// How many seconds between blocks we expect on average.
pub const TARGET_BLOCK_SPACING: u32 = 600; pub const TARGET_BLOCK_SPACING: u32 = 600;
/// How many blocks between diffchanges /// How many blocks between diffchanges.
pub const DIFFCHANGE_INTERVAL: u32 = 2016; pub const DIFFCHANGE_INTERVAL: u32 = 2016;
/// How much time on average should occur between diffchanges /// How much time on average should occur between diffchanges.
pub const DIFFCHANGE_TIMESPAN: u32 = 14 * 24 * 3600; pub const DIFFCHANGE_TIMESPAN: u32 = 14 * 24 * 3600;
/// The maximum allowed weight for a block, see BIP 141 (network rule) /// The maximum allowed weight for a block, see BIP 141 (network rule).
pub const MAX_BLOCK_WEIGHT: u32 = 4_000_000; pub const MAX_BLOCK_WEIGHT: u32 = 4_000_000;
/// The minimum transaction weight for a valid serialized transaction /// The minimum transaction weight for a valid serialized transaction.
pub const MIN_TRANSACTION_WEIGHT: u32 = 4 * 60; pub const MIN_TRANSACTION_WEIGHT: u32 = 4 * 60;
/// The factor that non-witness serialization data is multiplied by during weight calculation /// The factor that non-witness serialization data is multiplied by during weight calculation.
pub const WITNESS_SCALE_FACTOR: usize = 4; pub const WITNESS_SCALE_FACTOR: usize = 4;
/// The maximum allowed number of signature check operations in a block /// The maximum allowed number of signature check operations in a block.
pub const MAX_BLOCK_SIGOPS_COST: i64 = 80_000; pub const MAX_BLOCK_SIGOPS_COST: i64 = 80_000;
/// Mainnet (bitcoin) pubkey address prefix. /// Mainnet (bitcoin) pubkey address prefix.
pub const PUBKEY_ADDRESS_PREFIX_MAIN: u8 = 0; // 0x00 pub const PUBKEY_ADDRESS_PREFIX_MAIN: u8 = 0; // 0x00
@ -62,7 +62,7 @@ pub const MAX_SCRIPTNUM_VALUE: u32 = 0x80000000; // 2^31
/// if you are doing anything remotely sane with monetary values). /// if you are doing anything remotely sane with monetary values).
pub const MAX_MONEY: u64 = 21_000_000 * COIN_VALUE; pub const MAX_MONEY: u64 = 21_000_000 * COIN_VALUE;
/// Constructs and returns the coinbase (and only) transaction of the Bitcoin genesis block /// Constructs and returns the coinbase (and only) transaction of the Bitcoin genesis block.
fn bitcoin_genesis_tx() -> Transaction { fn bitcoin_genesis_tx() -> Transaction {
// Base // Base
let mut ret = Transaction { let mut ret = Transaction {
@ -101,7 +101,7 @@ fn bitcoin_genesis_tx() -> Transaction {
ret ret
} }
/// Constructs and returns the genesis block /// Constructs and returns the genesis block.
pub fn genesis_block(network: Network) -> Block { pub fn genesis_block(network: Network) -> Block {
let txdata = vec![bitcoin_genesis_tx()]; let txdata = vec![bitcoin_genesis_tx()];
let hash: sha256d::Hash = txdata[0].txid().into(); let hash: sha256d::Hash = txdata[0].txid().into();

View File

@ -156,17 +156,17 @@ pub enum Error {
/// Something did a non-minimal push; for more information see /// Something did a non-minimal push; for more information see
/// `https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#Push_operators` /// `https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#Push_operators`
NonMinimalPush, NonMinimalPush,
/// Some opcode expected a parameter, but it was missing or truncated /// Some opcode expected a parameter but it was missing or truncated.
EarlyEndOfScript, EarlyEndOfScript,
/// Tried to read an array off the stack as a number when it was more than 4 bytes /// Tried to read an array off the stack as a number when it was more than 4 bytes.
NumericOverflow, NumericOverflow,
/// Error validating the script with bitcoinconsensus library /// Error validating the script with bitcoinconsensus library.
#[cfg(feature = "bitcoinconsensus")] #[cfg(feature = "bitcoinconsensus")]
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))] #[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))]
BitcoinConsensus(bitcoinconsensus::Error), BitcoinConsensus(bitcoinconsensus::Error),
/// Can not find the spent output /// Can not find the spent output.
UnknownSpentOutput(OutPoint), UnknownSpentOutput(OutPoint),
/// Can not serialize the spending transaction /// Can not serialize the spending transaction.
Serialization Serialization
} }
@ -266,7 +266,8 @@ impl From<bitcoinconsensus::Error> for Error {
} }
} }
/// Helper to encode an integer in script(minimal CScriptNum) format. /// Encodes an integer in script(minimal CScriptNum) format.
///
/// Writes bytes into the buffer and returns the number of bytes written. /// Writes bytes into the buffer and returns the number of bytes written.
pub fn write_scriptint(out: &mut [u8; 8], n: i64) -> usize { pub fn write_scriptint(out: &mut [u8; 8], n: i64) -> usize {
let mut len = 0; let mut len = 0;
@ -297,7 +298,8 @@ pub fn write_scriptint(out: &mut [u8; 8], n: i64) -> usize {
len len
} }
/// Helper to decode an integer in script(minimal CScriptNum) format /// Decodes an integer in script(minimal CScriptNum) format.
///
/// Notice that this fails on overflow: the result is the same as in /// Notice that this fails on overflow: the result is the same as in
/// bitcoind, that only 4-byte signed-magnitude values may be read as /// bitcoind, that only 4-byte signed-magnitude values may be read as
/// numbers. They can be added or subtracted (and a long time ago, /// numbers. They can be added or subtracted (and a long time ago,
@ -343,6 +345,8 @@ pub fn read_scriptint(v: &[u8]) -> Result<i64, Error> {
Ok(ret) Ok(ret)
} }
/// Decodes a boolean.
///
/// This is like "`read_scriptint` then map 0 to false and everything /// This is like "`read_scriptint` then map 0 to false and everything
/// else as true", except that the overflow rules don't apply. /// else as true", except that the overflow rules don't apply.
#[inline] #[inline]
@ -353,7 +357,7 @@ pub fn read_scriptbool(v: &[u8]) -> bool {
} }
} }
/// Read a script-encoded unsigned integer /// Decodes a script-encoded unsigned integer.
/// ///
/// ## Errors /// ## Errors
/// ///
@ -395,7 +399,7 @@ impl Script {
/// Creates a new empty script. /// Creates a new empty script.
pub fn new() -> Script { Script(vec![].into_boxed_slice()) } pub fn new() -> Script { Script(vec![].into_boxed_slice()) }
/// Creates a new script builder /// Creates a new script builder.
pub fn builder() -> Builder { pub fn builder() -> Builder {
Builder::new() Builder::new()
} }
@ -863,15 +867,16 @@ pub struct Instructions<'a> {
} }
impl<'a> Instructions<'a> { impl<'a> Instructions<'a> {
/// Set the iterator to end so that it won't iterate any longer /// Sets the iterator to end so that it won't iterate any longer.
fn kill(&mut self) { fn kill(&mut self) {
let len = self.data.len(); let len = self.data.len();
self.data.nth(len.max(1) - 1); self.data.nth(len.max(1) - 1);
} }
/// takes `len` bytes long slice from iterator and returns it advancing iterator /// Takes a `len` bytes long slice from iterator and returns it, advancing the iterator.
/// if the iterator is not long enough [`Error::EarlyEndOfScript`] is returned and the iterator is killed ///
/// to avoid returning an infinite stream of errors. /// If the iterator is not long enough [`Error::EarlyEndOfScript`] is returned and the iterator
/// is killed to avoid returning an infinite stream of errors.
fn take_slice_or_kill(&mut self, len: usize) -> Result<&'a [u8], Error> { fn take_slice_or_kill(&mut self, len: usize) -> Result<&'a [u8], Error> {
if self.data.len() >= len { if self.data.len() >= len {
let slice = &self.data.as_slice()[..len]; let slice = &self.data.as_slice()[..len];
@ -968,9 +973,10 @@ impl Builder {
/// Checks whether the script is the empty script. /// Checks whether the script is the empty script.
pub fn is_empty(&self) -> bool { self.0.is_empty() } pub fn is_empty(&self) -> bool { self.0.is_empty() }
/// Adds instructions to push an integer onto the stack. Integers are /// Adds instructions to push an integer onto the stack.
/// encoded as little-endian signed-magnitude numbers, but there are ///
/// dedicated opcodes to push some small integers. /// Integers are encoded as little-endian signed-magnitude numbers, but there are dedicated
/// opcodes to push some small integers.
pub fn push_int(self, data: i64) -> Builder { pub fn push_int(self, data: i64) -> Builder {
// We can special-case -1, 1-16 // We can special-case -1, 1-16
if data == -1 || (1..=16).contains(&data) { if data == -1 || (1..=16).contains(&data) {

View File

@ -146,6 +146,7 @@ impl std::error::Error for ParseOutPointError {
} }
/// Parses a string-encoded transaction index (vout). /// Parses a string-encoded transaction index (vout).
///
/// Does not permit leading zeroes or non-digit characters. /// Does not permit leading zeroes or non-digit characters.
fn parse_vout(s: &str) -> Result<u32, ParseOutPointError> { fn parse_vout(s: &str) -> Result<u32, ParseOutPointError> {
if s.len() > 1 { if s.len() > 1 {
@ -319,13 +320,13 @@ impl Sequence {
self.is_relative_lock_time() & (self.0 & Sequence::LOCK_TYPE_MASK > 0) self.is_relative_lock_time() & (self.0 & Sequence::LOCK_TYPE_MASK > 0)
} }
/// Create a relative lock-time using block height. /// Creates a relative lock-time using block height.
#[inline] #[inline]
pub fn from_height(height: u16) -> Self { pub fn from_height(height: u16) -> Self {
Sequence(u32::from(height)) Sequence(u32::from(height))
} }
/// Create a relative lock-time using time intervals where each interval is equivalent /// Creates a relative lock-time using time intervals where each interval is equivalent
/// to 512 seconds. /// to 512 seconds.
/// ///
/// Encoding finer granularity of time for relative lock-times is not supported in Bitcoin /// Encoding finer granularity of time for relative lock-times is not supported in Bitcoin
@ -334,7 +335,7 @@ impl Sequence {
Sequence(u32::from(intervals) | Sequence::LOCK_TYPE_MASK) Sequence(u32::from(intervals) | Sequence::LOCK_TYPE_MASK)
} }
/// Create a relative lock-time from seconds, converting the seconds into 512 second /// Creates a relative lock-time from seconds, converting the seconds into 512 second
/// interval with floor division. /// interval with floor division.
/// ///
/// Will return an error if the input cannot be encoded in 16 bits. /// Will return an error if the input cannot be encoded in 16 bits.
@ -347,7 +348,7 @@ impl Sequence {
} }
} }
/// Create a relative lock-time from seconds, converting the seconds into 512 second /// Creates a relative lock-time from seconds, converting the seconds into 512 second
/// interval with ceiling division. /// interval with ceiling division.
/// ///
/// Will return an error if the input cannot be encoded in 16 bits. /// Will return an error if the input cannot be encoded in 16 bits.
@ -366,7 +367,7 @@ impl Sequence {
!self.is_final() !self.is_final()
} }
/// Create a sequence from a u32 value. /// Creates a sequence from a u32 value.
#[inline] #[inline]
pub fn from_consensus(n: u32) -> Self { pub fn from_consensus(n: u32) -> Self {
Sequence(n) Sequence(n)
@ -590,6 +591,7 @@ pub struct Transaction {
impl Transaction { impl Transaction {
/// Computes a "normalized TXID" which does not include any signatures. /// Computes a "normalized TXID" which does not include any signatures.
///
/// This gives a way to identify a transaction that is "the same" as /// This gives a way to identify a transaction that is "the same" as
/// another in the sense of having same inputs and outputs. /// another in the sense of having same inputs and outputs.
pub fn ntxid(&self) -> sha256d::Hash { pub fn ntxid(&self) -> sha256d::Hash {
@ -602,9 +604,10 @@ impl Transaction {
cloned_tx.txid().into() cloned_tx.txid().into()
} }
/// Computes the txid. For non-segwit transactions this will be identical /// Computes the txid.
/// to the output of `wtxid()`, but for segwit transactions, ///
/// this will give the correct txid (not including witnesses) while `wtxid` /// For non-segwit transactions this will be identical to the output of `wtxid()`, but for
/// segwit transactions, this will give the correct txid (not including witnesses) while `wtxid`
/// will also hash witnesses. /// will also hash witnesses.
pub fn txid(&self) -> Txid { pub fn txid(&self) -> Txid {
let mut enc = Txid::engine(); let mut enc = Txid::engine();
@ -615,9 +618,10 @@ impl Transaction {
Txid::from_engine(enc) Txid::from_engine(enc)
} }
/// Computes SegWit-version of the transaction id (wtxid). For transaction with the witness /// Computes SegWit-version of the transaction id (wtxid).
/// data this hash includes witness, for pre-witness transaction it is equal to the normal ///
/// value returned by txid() function. /// For transaction with the witness data this hash includes witness, for pre-witness
/// transaction it is equal to the normal value returned by txid() function.
pub fn wtxid(&self) -> Wtxid { pub fn wtxid(&self) -> Wtxid {
let mut enc = Wtxid::engine(); let mut enc = Wtxid::engine();
self.consensus_encode(&mut enc).expect("engines don't error"); self.consensus_encode(&mut enc).expect("engines don't error");
@ -642,7 +646,7 @@ impl Transaction {
/// have the information to determine. /// have the information to determine.
/// - Does NOT handle the sighash single bug (see "Return type" section) /// - Does NOT handle the sighash single bug (see "Return type" section)
/// ///
/// # Return type /// # Returns
/// ///
/// This function can't handle the SIGHASH_SINGLE bug internally, so it returns [`EncodeSigningDataResult`] /// This function can't handle the SIGHASH_SINGLE bug internally, so it returns [`EncodeSigningDataResult`]
/// that must be handled by the caller (see [`EncodeSigningDataResult::is_sighash_single_bug`]). /// that must be handled by the caller (see [`EncodeSigningDataResult::is_sighash_single_bug`]).
@ -826,6 +830,7 @@ impl Transaction {
} }
/// Verify that this transaction is able to spend its inputs. /// Verify that this transaction is able to spend its inputs.
///
/// The `spent` closure should not return the same [`TxOut`] twice! /// The `spent` closure should not return the same [`TxOut`] twice!
#[cfg(feature="bitcoinconsensus")] #[cfg(feature="bitcoinconsensus")]
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))] #[cfg_attr(docsrs, doc(cfg(feature = "bitcoinconsensus")))]
@ -846,14 +851,15 @@ impl Transaction {
Ok(()) Ok(())
} }
/// Is this a coin base transaction? /// Checks if this is a coin base transaction.
pub fn is_coin_base(&self) -> bool { pub fn is_coin_base(&self) -> bool {
self.input.len() == 1 && self.input[0].previous_output.is_null() self.input.len() == 1 && self.input[0].previous_output.is_null()
} }
/// Returns `true` if the transaction itself opted in to be BIP-125-replaceable (RBF). This /// Returns `true` if the transaction itself opted in to be BIP-125-replaceable (RBF).
/// **does not** cover the case where a transaction becomes replaceable due to ancestors being ///
/// RBF. /// This **does not** cover the case where a transaction becomes replaceable due to ancestors
/// being RBF.
pub fn is_explicitly_rbf(&self) -> bool { pub fn is_explicitly_rbf(&self) -> bool {
self.input.iter().any(|input| input.sequence.is_rbf()) self.input.iter().any(|input| input.sequence.is_rbf())
} }

View File

@ -18,7 +18,7 @@ use crate::prelude::*;
use crate::VarInt; use crate::VarInt;
use crate::taproot::TAPROOT_ANNEX_PREFIX; use crate::taproot::TAPROOT_ANNEX_PREFIX;
/// The Witness is the data used to unlock bitcoins since the [segwit upgrade](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki) /// The Witness is the data used to unlock bitcoin since the [segwit upgrade].
/// ///
/// Can be logically seen as an array of bytestrings, i.e. `Vec<Vec<u8>>`, and it is serialized on the wire /// Can be logically seen as an array of bytestrings, i.e. `Vec<Vec<u8>>`, and it is serialized on the wire
/// in that format. You can convert between this type and `Vec<Vec<u8>>` by using [`Witness::from_slice`] /// in that format. You can convert between this type and `Vec<Vec<u8>>` by using [`Witness::from_slice`]
@ -27,23 +27,25 @@ use crate::taproot::TAPROOT_ANNEX_PREFIX;
/// For serialization and deserialization performance it is stored internally as a single `Vec`, /// For serialization and deserialization performance it is stored internally as a single `Vec`,
/// saving some allocations. /// saving some allocations.
/// ///
/// [segwit upgrade]: <https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki>
#[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] #[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub struct Witness { pub struct Witness {
/// Contains the witness `Vec<Vec<u8>>` serialization without the initial varint indicating the /// Contains the witness `Vec<Vec<u8>>` serialization without the initial varint indicating the
/// number of elements (which is stored in `witness_elements`) /// number of elements (which is stored in `witness_elements`).
content: Vec<u8>, content: Vec<u8>,
/// Number of elements in the witness. /// The number of elements in the witness.
/// It is stored separately (instead of as VarInt in the initial part of content) so that method ///
/// like [`Witness::push`] doesn't have case requiring to shift the entire array /// Stored separately (instead of as a VarInt in the initial part of content) so that methods
/// like [`Witness::push`] don't have to shift the entire array.
witness_elements: usize, witness_elements: usize,
/// This is the valid index pointing to the beginning of the index area. This area is 4 * stack_size bytes /// This is the valid index pointing to the beginning of the index area. This area is 4 *
/// at the end of the content vector which stores the indices of each item. /// stack_size bytes at the end of the content vector which stores the indices of each item.
indices_start: usize, indices_start: usize,
} }
/// Support structure to allow efficient and convenient iteration over the Witness elements /// Support structure to allow efficient and convenient iteration over the Witness elements.
pub struct Iter<'a> { pub struct Iter<'a> {
inner: &'a [u8], inner: &'a [u8],
indices_start: usize, indices_start: usize,
@ -162,7 +164,7 @@ impl Encodable for Witness {
} }
impl Witness { impl Witness {
/// Create a new empty [`Witness`] /// Creates a new empty [`Witness`].
pub fn new() -> Self { pub fn new() -> Self {
Witness::default() Witness::default()
} }
@ -202,17 +204,17 @@ impl Witness {
} }
} }
/// Convenience method to create an array of byte-arrays from this witness /// Convenience method to create an array of byte-arrays from this witness.
pub fn to_vec(&self) -> Vec<Vec<u8>> { pub fn to_vec(&self) -> Vec<Vec<u8>> {
self.iter().map(|s| s.to_vec()).collect() self.iter().map(|s| s.to_vec()).collect()
} }
/// Returns `true` if the witness contains no element /// Returns `true` if the witness contains no element.
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.witness_elements == 0 self.witness_elements == 0
} }
/// Returns a struct implementing [`Iterator`] /// Returns a struct implementing [`Iterator`].
pub fn iter(&self) -> Iter { pub fn iter(&self) -> Iter {
Iter { Iter {
inner: self.content.as_slice(), inner: self.content.as_slice(),
@ -221,12 +223,12 @@ impl Witness {
} }
} }
/// Returns the number of elements this witness holds /// Returns the number of elements this witness holds.
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.witness_elements self.witness_elements
} }
/// Returns the bytes required when this Witness is consensus encoded /// Returns the bytes required when this Witness is consensus encoded.
pub fn serialized_len(&self) -> usize { pub fn serialized_len(&self) -> usize {
self.iter() self.iter()
.map(|el| VarInt(el.len() as u64).len() + el.len()) .map(|el| VarInt(el.len() as u64).len() + el.len())
@ -234,14 +236,14 @@ impl Witness {
+ VarInt(self.witness_elements as u64).len() + VarInt(self.witness_elements as u64).len()
} }
/// Clear the witness /// Clear the witness.
pub fn clear(&mut self) { pub fn clear(&mut self) {
self.content.clear(); self.content.clear();
self.witness_elements = 0; self.witness_elements = 0;
self.indices_start = 0; self.indices_start = 0;
} }
/// Push a new element on the witness, requires an allocation /// Push a new element on the witness, requires an allocation.
pub fn push<T: AsRef<[u8]>>(&mut self, new_element: T) { pub fn push<T: AsRef<[u8]>>(&mut self, new_element: T) {
self.push_slice(new_element.as_ref()); self.push_slice(new_element.as_ref());
} }
@ -284,7 +286,7 @@ impl Witness {
Some(&self.content[start..start + varint.0 as usize]) Some(&self.content[start..start + varint.0 as usize])
} }
/// Return the last element in the witness, if any /// Returns the last element in the witness, if any.
pub fn last(&self) -> Option<&[u8]> { pub fn last(&self) -> Option<&[u8]> {
if self.witness_elements == 0 { if self.witness_elements == 0 {
None None
@ -293,7 +295,7 @@ impl Witness {
} }
} }
/// Return the second-to-last element in the witness, if any /// Returns the second-to-last element in the witness, if any.
pub fn second_to_last(&self) -> Option<&[u8]> { pub fn second_to_last(&self) -> Option<&[u8]> {
if self.witness_elements <= 1 { if self.witness_elements <= 1 {
None None