consensus: Improve rustdocs

Do an audit of the `consensus` module and clean up rustdocs.
This commit is contained in:
Tobin C. Harding 2022-10-31 12:38:13 +11:00
parent c553299ace
commit e1e5974065
1 changed files with 51 additions and 48 deletions

View File

@ -35,33 +35,33 @@ use crate::blockdata::transaction::{TxOut, Transaction, TxIn};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use crate::network::{message_blockdata::Inventory, address::{Address, AddrV2Message}}; use crate::network::{message_blockdata::Inventory, address::{Address, AddrV2Message}};
/// Encoding error /// Encoding error.
#[derive(Debug)] #[derive(Debug)]
#[non_exhaustive] #[non_exhaustive]
pub enum Error { pub enum Error {
/// And I/O error /// And I/O error.
Io(io::Error), Io(io::Error),
/// PSBT-related error /// PSBT-related error.
Psbt(psbt::Error), Psbt(psbt::Error),
/// Tried to allocate an oversized vector /// Tried to allocate an oversized vector.
OversizedVectorAllocation { OversizedVectorAllocation {
/// The capacity requested /// The capacity requested.
requested: usize, requested: usize,
/// The maximum capacity /// The maximum capacity.
max: usize, max: usize,
}, },
/// Checksum was invalid /// Checksum was invalid.
InvalidChecksum { InvalidChecksum {
/// The expected checksum /// The expected checksum.
expected: [u8; 4], expected: [u8; 4],
/// The invalid checksum /// The invalid checksum.
actual: [u8; 4], actual: [u8; 4],
}, },
/// VarInt was encoded in a non-minimal way /// VarInt was encoded in a non-minimal way.
NonMinimalVarInt, NonMinimalVarInt,
/// Parsing error /// Parsing error.
ParseFailed(&'static str), ParseFailed(&'static str),
/// Unsupported Segwit flag /// Unsupported Segwit flag.
UnsupportedSegwitFlag(u8), UnsupportedSegwitFlag(u8),
} }
@ -114,7 +114,7 @@ impl From<psbt::Error> for Error {
} }
} }
/// Encode an object into a vector /// Encodes an object into a vector.
pub fn serialize<T: Encodable + ?Sized>(data: &T) -> Vec<u8> { pub fn serialize<T: Encodable + ?Sized>(data: &T) -> Vec<u8> {
let mut encoder = Vec::new(); let mut encoder = Vec::new();
let len = data.consensus_encode(&mut encoder).expect("in-memory writers don't error"); let len = data.consensus_encode(&mut encoder).expect("in-memory writers don't error");
@ -122,12 +122,12 @@ pub fn serialize<T: Encodable + ?Sized>(data: &T) -> Vec<u8> {
encoder encoder
} }
/// Encode an object into a hex-encoded string /// Encodes an object into a hex-encoded string.
pub fn serialize_hex<T: Encodable + ?Sized>(data: &T) -> String { pub fn serialize_hex<T: Encodable + ?Sized>(data: &T) -> String {
serialize(data)[..].to_hex() serialize(data)[..].to_hex()
} }
/// Deserialize an object from a vector, will error if said deserialization /// Deserializes an object from a vector, will error if said deserialization
/// doesn't consume the entire vector. /// doesn't consume the entire vector.
pub fn deserialize<T: Decodable>(data: &[u8]) -> Result<T, Error> { pub fn deserialize<T: Decodable>(data: &[u8]) -> Result<T, Error> {
let (rv, consumed) = deserialize_partial(data)?; let (rv, consumed) = deserialize_partial(data)?;
@ -140,7 +140,7 @@ pub fn deserialize<T: Decodable>(data: &[u8]) -> Result<T, Error> {
} }
} }
/// Deserialize an object from a vector, but will not report an error if said deserialization /// Deserializes an object from a vector, but will not report an error if said deserialization
/// doesn't consume the entire vector. /// doesn't consume the entire vector.
pub fn deserialize_partial<T: Decodable>(data: &[u8]) -> Result<(T, usize), Error> { pub fn deserialize_partial<T: Decodable>(data: &[u8]) -> Result<(T, usize), Error> {
let mut decoder = Cursor::new(data); let mut decoder = Cursor::new(data);
@ -151,57 +151,57 @@ pub fn deserialize_partial<T: Decodable>(data: &[u8]) -> Result<(T, usize), Erro
} }
/// Extensions of `Write` to encode data as per Bitcoin consensus /// Extensions of `Write` to encode data as per Bitcoin consensus.
pub trait WriteExt : io::Write { pub trait WriteExt : io::Write {
/// Output a 64-bit uint /// Outputs a 64-bit unsigned integer.
fn emit_u64(&mut self, v: u64) -> Result<(), io::Error>; fn emit_u64(&mut self, v: u64) -> Result<(), io::Error>;
/// Output a 32-bit uint /// Outputs a 32-bit unsigned integer.
fn emit_u32(&mut self, v: u32) -> Result<(), io::Error>; fn emit_u32(&mut self, v: u32) -> Result<(), io::Error>;
/// Output a 16-bit uint /// Outputs a 16-bit unsigned integer.
fn emit_u16(&mut self, v: u16) -> Result<(), io::Error>; fn emit_u16(&mut self, v: u16) -> Result<(), io::Error>;
/// Output a 8-bit uint /// Outputs a 8-bit unsigned integer.
fn emit_u8(&mut self, v: u8) -> Result<(), io::Error>; fn emit_u8(&mut self, v: u8) -> Result<(), io::Error>;
/// Output a 64-bit int /// Outputs a 64-bit signed integer.
fn emit_i64(&mut self, v: i64) -> Result<(), io::Error>; fn emit_i64(&mut self, v: i64) -> Result<(), io::Error>;
/// Output a 32-bit int /// Outputs a 32-bit signed integer.
fn emit_i32(&mut self, v: i32) -> Result<(), io::Error>; fn emit_i32(&mut self, v: i32) -> Result<(), io::Error>;
/// Output a 16-bit int /// Outputs a 16-bit signed integer.
fn emit_i16(&mut self, v: i16) -> Result<(), io::Error>; fn emit_i16(&mut self, v: i16) -> Result<(), io::Error>;
/// Output a 8-bit int /// Outputs a 8-bit signed integer.
fn emit_i8(&mut self, v: i8) -> Result<(), io::Error>; fn emit_i8(&mut self, v: i8) -> Result<(), io::Error>;
/// Output a boolean /// Outputs a boolean.
fn emit_bool(&mut self, v: bool) -> Result<(), io::Error>; fn emit_bool(&mut self, v: bool) -> Result<(), io::Error>;
/// Output a byte slice /// Outputs a byte slice.
fn emit_slice(&mut self, v: &[u8]) -> Result<(), io::Error>; fn emit_slice(&mut self, v: &[u8]) -> Result<(), io::Error>;
} }
/// Extensions of `Read` to decode data as per Bitcoin consensus /// Extensions of `Read` to decode data as per Bitcoin consensus.
pub trait ReadExt : io::Read { pub trait ReadExt : io::Read {
/// Read a 64-bit uint /// Reads a 64-bit unsigned integer.
fn read_u64(&mut self) -> Result<u64, Error>; fn read_u64(&mut self) -> Result<u64, Error>;
/// Read a 32-bit uint /// Reads a 32-bit unsigned integer.
fn read_u32(&mut self) -> Result<u32, Error>; fn read_u32(&mut self) -> Result<u32, Error>;
/// Read a 16-bit uint /// Reads a 16-bit unsigned integer.
fn read_u16(&mut self) -> Result<u16, Error>; fn read_u16(&mut self) -> Result<u16, Error>;
/// Read a 8-bit uint /// Reads a 8-bit unsigned integer.
fn read_u8(&mut self) -> Result<u8, Error>; fn read_u8(&mut self) -> Result<u8, Error>;
/// Read a 64-bit int /// Reads a 64-bit signed integer.
fn read_i64(&mut self) -> Result<i64, Error>; fn read_i64(&mut self) -> Result<i64, Error>;
/// Read a 32-bit int /// Reads a 32-bit signed integer.
fn read_i32(&mut self) -> Result<i32, Error>; fn read_i32(&mut self) -> Result<i32, Error>;
/// Read a 16-bit int /// Reads a 16-bit signed integer.
fn read_i16(&mut self) -> Result<i16, Error>; fn read_i16(&mut self) -> Result<i16, Error>;
/// Read a 8-bit int /// Reads a 8-bit signed integer.
fn read_i8(&mut self) -> Result<i8, Error>; fn read_i8(&mut self) -> Result<i8, Error>;
/// Read a boolean /// Reads a boolean.
fn read_bool(&mut self) -> Result<bool, Error>; fn read_bool(&mut self) -> Result<bool, Error>;
/// Read a byte slice /// Reads a byte slice.
fn read_slice(&mut self, slice: &mut [u8]) -> Result<(), Error>; fn read_slice(&mut self, slice: &mut [u8]) -> Result<(), Error>;
} }
@ -281,19 +281,21 @@ impl<R: Read + ?Sized> ReadExt for R {
} }
} }
/// Maximum size, in bytes, of a vector we are allowed to decode /// Maximum size, in bytes, of a vector we are allowed to decode.
pub const MAX_VEC_SIZE: usize = 4_000_000; pub const MAX_VEC_SIZE: usize = 4_000_000;
/// Data which can be encoded in a consensus-consistent way /// Data which can be encoded in a consensus-consistent way.
pub trait Encodable { pub trait Encodable {
/// Encode an object with a well-defined format. /// Encodes an object with a well-defined format.
/// Returns the number of bytes written on success.
/// ///
/// The only errors returned are errors propagated from the writer. /// # Returns
///
/// The number of bytes written on success. The only errors returned are errors propagated from
/// the writer.
fn consensus_encode<W: io::Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error>; fn consensus_encode<W: io::Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error>;
} }
/// Data which can be encoded in a consensus-consistent way /// Data which can be encoded in a consensus-consistent way.
pub trait Decodable: Sized { pub trait Decodable: Sized {
/// Decode `Self` from a size-limited reader. /// Decode `Self` from a size-limited reader.
/// ///
@ -345,11 +347,11 @@ pub trait Decodable: Sized {
} }
} }
/// A variable-length unsigned integer /// A variable-length unsigned integer.
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug)] #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug)]
pub struct VarInt(pub u64); pub struct VarInt(pub u64);
/// Data which must be preceded by a 4-byte checksum /// Data which must be preceded by a 4-byte checksum.
#[derive(PartialEq, Eq, Clone, Debug)] #[derive(PartialEq, Eq, Clone, Debug)]
pub struct CheckedData(pub Vec<u8>); pub struct CheckedData(pub Vec<u8>);
@ -384,6 +386,7 @@ impl_int_encodable!(i64, read_i64, emit_i64);
#[allow(clippy::len_without_is_empty)] // VarInt has on concept of 'is_empty'. #[allow(clippy::len_without_is_empty)] // VarInt has on concept of 'is_empty'.
impl VarInt { impl VarInt {
/// Gets the length of this VarInt when encoded. /// Gets the length of this VarInt when encoded.
///
/// Returns 1 for 0..=0xFC, 3 for 0xFD..=(2^16-1), 5 for 0x10000..=(2^32-1), /// Returns 1 for 0..=0xFC, 3 for 0xFD..=(2^16-1), 5 for 0x10000..=(2^32-1),
/// and 9 otherwise. /// and 9 otherwise.
#[inline] #[inline]
@ -624,7 +627,7 @@ struct ReadBytesFromFiniteReaderOpts {
chunk_size: usize, chunk_size: usize,
} }
/// Read `opts.len` bytes from reader, where `opts.len` could potentially be malicious /// Read `opts.len` bytes from reader, where `opts.len` could potentially be malicious.
/// ///
/// This function relies on reader being bound in amount of data /// This function relies on reader being bound in amount of data
/// it returns for OOM protection. See [`Decodable::consensus_decode_from_finite_reader`]. /// it returns for OOM protection. See [`Decodable::consensus_decode_from_finite_reader`].
@ -677,7 +680,7 @@ impl Decodable for Box<[u8]> {
} }
/// Do a double-SHA256 on some data and return the first 4 bytes /// Does a double-SHA256 on `data` and returns the first 4 bytes.
fn sha2_checksum(data: &[u8]) -> [u8; 4] { fn sha2_checksum(data: &[u8]) -> [u8; 4] {
let checksum = <sha256d::Hash as Hash>::hash(data); let checksum = <sha256d::Hash as Hash>::hash(data);
[checksum[0], checksum[1], checksum[2], checksum[3]] [checksum[0], checksum[1], checksum[2], checksum[3]]