Merge rust-bitcoin/rust-bitcoin#1223: Remove the endian module

2674327c93 Remove the endian module (Tobin C. Harding)

Pull request description:

  Now we have MSRV of 1.41.1 we can use the `from_le_bytes` and `to_be_bytes` methods implemented on standard integer types, these became available in Rust 1.32.

  Remove the `endian` module replacing its logic with calls to methods on the respective stdlib integer types.

ACKs for top commit:
  Kixunil:
    ACK 2674327c93
  apoelstra:
    ACK 2674327c93

Tree-SHA512: 7cdaf278c9d162cb0080bb6b9ea80ab55f881bfcd389f8b968f8cfaeebb0d27d3b5b46e9677a376bc6b7d4068cf094f50560ed4ae7bc817c50da688f70a7af25
This commit is contained in:
Andrew Poelstra 2022-10-28 18:55:55 +00:00
commit bbf89dd5a4
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
9 changed files with 51 additions and 159 deletions

View File

@ -5,7 +5,7 @@
//! Implementation of compact blocks data structure and algorithms.
//!
use core::convert::TryFrom;
use core::convert::{TryFrom, TryInto};
use core::{convert, fmt, mem};
#[cfg(feature = "std")]
use std::error;
@ -16,7 +16,6 @@ use crate::consensus::encode::{self, Decodable, Encodable, VarInt};
use crate::hashes::{sha256, siphash24, Hash};
use crate::internal_macros::{impl_bytes_newtype, impl_consensus_encoding};
use crate::prelude::*;
use crate::util::endian;
use crate::{io, Block, BlockHash, BlockHeader, Transaction};
/// A BIP-152 error
@ -112,7 +111,7 @@ impl ShortId {
// 2. Running SipHash-2-4 with the input being the transaction ID and the keys (k0/k1)
// set to the first two little-endian 64-bit integers from the above hash, respectively.
(endian::slice_to_u64_le(&h[0..8]), endian::slice_to_u64_le(&h[8..16]))
(u64::from_le_bytes(h[0..8].try_into().expect("8 byte slice")), u64::from_le_bytes(h[8..16].try_into().expect("8 byte slice")))
}
/// Calculate the short ID with the given (w)txid and using the provided SipHash keys.

View File

@ -40,6 +40,7 @@
//!
use core::cmp::{self, Ordering};
use core::convert::TryInto;
use core::fmt::{self, Display, Formatter};
use bitcoin_internals::write_err;
@ -53,7 +54,6 @@ use crate::hash_types::{BlockHash, FilterHash, FilterHeader};
use crate::hashes::{siphash24, Hash};
use crate::io;
use crate::prelude::*;
use crate::util::endian;
/// Golomb encoding parameter as in BIP-158, see also https://gist.github.com/sipa/576d5f09c3b86c3b1b75598d799fc845
const P: u8 = 19;
@ -170,8 +170,8 @@ impl<'a, W: io::Write> BlockFilterWriter<'a, W> {
/// Creates a new [`BlockFilterWriter`] from `block`.
pub fn new(writer: &'a mut W, block: &'a Block) -> BlockFilterWriter<'a, W> {
let block_hash_as_int = block.block_hash().into_inner();
let k0 = endian::slice_to_u64_le(&block_hash_as_int[0..8]);
let k1 = endian::slice_to_u64_le(&block_hash_as_int[8..16]);
let k0 = u64::from_le_bytes(block_hash_as_int[0..8].try_into().expect("8 byte slice"));
let k1 = u64::from_le_bytes(block_hash_as_int[8..16].try_into().expect("8 byte slice"));
let writer = GcsFilterWriter::new(writer, k0, k1, M, P);
BlockFilterWriter { block, writer }
}
@ -224,8 +224,8 @@ impl BlockFilterReader {
/// Creates a new [`BlockFilterReader`] from `block_hash`.
pub fn new(block_hash: &BlockHash) -> BlockFilterReader {
let block_hash_as_int = block_hash.into_inner();
let k0 = endian::slice_to_u64_le(&block_hash_as_int[0..8]);
let k1 = endian::slice_to_u64_le(&block_hash_as_int[8..16]);
let k0 = u64::from_le_bytes(block_hash_as_int[0..8].try_into().expect("8 byte slice"));
let k1 = u64::from_le_bytes(block_hash_as_int[8..16].try_into().expect("8 byte slice"));
BlockFilterReader { reader: GcsFilterReader::new(k0, k1, M, P) }
}

View File

@ -7,6 +7,7 @@
//! at <https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki>.
//!
use core::convert::TryInto;
use core::default::Default;
use core::fmt;
use core::ops::Index;
@ -24,7 +25,7 @@ use crate::io::Write;
use crate::network::constants::Network;
use crate::prelude::*;
use crate::util::key::{KeyPair, PrivateKey, PublicKey};
use crate::util::{base58, endian, key};
use crate::util::{base58, key};
/// A chain code
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
@ -574,7 +575,7 @@ impl ExtendedPrivKey {
}
}
hmac_engine.input(&endian::u32_to_array_be(u32::from(i)));
hmac_engine.input(&u32::from(i).to_be_bytes());
let hmac_result: Hmac<sha512::Hash> = Hmac::from_engine(hmac_engine);
let sk = secp256k1::SecretKey::from_slice(&hmac_result[..32])
.expect("statistically impossible to hit");
@ -611,7 +612,7 @@ impl ExtendedPrivKey {
network,
depth: data[4],
parent_fingerprint: Fingerprint::from(&data[5..9]),
child_number: endian::slice_to_u32_be(&data[9..13]).into(),
child_number: u32::from_be_bytes(data[9..13].try_into().expect("4 byte slice")).into(),
chain_code: ChainCode::from(&data[13..45]),
private_key: secp256k1::SecretKey::from_slice(&data[46..78])?,
})
@ -628,7 +629,7 @@ impl ExtendedPrivKey {
);
ret[4] = self.depth as u8;
ret[5..9].copy_from_slice(&self.parent_fingerprint[..]);
ret[9..13].copy_from_slice(&endian::u32_to_array_be(u32::from(self.child_number)));
ret[9..13].copy_from_slice(&u32::from(self.child_number).to_be_bytes());
ret[13..45].copy_from_slice(&self.chain_code[..]);
ret[45] = 0;
ret[46..78].copy_from_slice(&self.private_key[..]);
@ -695,7 +696,7 @@ impl ExtendedPubKey {
let mut hmac_engine: HmacEngine<sha512::Hash> =
HmacEngine::new(&self.chain_code[..]);
hmac_engine.input(&self.public_key.serialize()[..]);
hmac_engine.input(&endian::u32_to_array_be(n));
hmac_engine.input(&n.to_be_bytes());
let hmac_result: Hmac<sha512::Hash> = Hmac::from_engine(hmac_engine);
@ -743,7 +744,7 @@ impl ExtendedPubKey {
},
depth: data[4],
parent_fingerprint: Fingerprint::from(&data[5..9]),
child_number: endian::slice_to_u32_be(&data[9..13]).into(),
child_number: u32::from_be_bytes(data[9..13].try_into().expect("4 byte slice")).into(),
chain_code: ChainCode::from(&data[13..45]),
public_key: secp256k1::PublicKey::from_slice(&data[45..78])?,
})
@ -760,7 +761,7 @@ impl ExtendedPubKey {
);
ret[4] = self.depth as u8;
ret[5..9].copy_from_slice(&self.parent_fingerprint[..]);
ret[9..13].copy_from_slice(&endian::u32_to_array_be(u32::from(self.child_number)));
ret[9..13].copy_from_slice(&u32::from(self.child_number).to_be_bytes());
ret[13..45].copy_from_slice(&self.chain_code[..]);
ret[45..78].copy_from_slice(&self.public_key.serialize()[..]);
ret

View File

@ -26,7 +26,6 @@ use crate::hashes::{sha256d, Hash, sha256};
use crate::hash_types::{BlockHash, FilterHash, TxMerkleNode, FilterHeader};
use crate::io::{self, Cursor, Read};
use crate::util::endian;
use crate::util::psbt;
use crate::bip152::{ShortId, PrefilledTransaction};
use crate::util::taproot::TapLeafHash;
@ -207,33 +206,32 @@ pub trait ReadExt : io::Read {
}
macro_rules! encoder_fn {
($name:ident, $val_type:ty, $writefn:ident) => {
($name:ident, $val_type:ty) => {
#[inline]
fn $name(&mut self, v: $val_type) -> Result<(), io::Error> {
self.write_all(&endian::$writefn(v))
self.write_all(&v.to_le_bytes())
}
}
}
macro_rules! decoder_fn {
($name:ident, $val_type:ty, $readfn:ident, $byte_len: expr) => {
($name:ident, $val_type:ty, $byte_len: expr) => {
#[inline]
fn $name(&mut self) -> Result<$val_type, Error> {
bitcoin_internals::const_assert!(core::mem::size_of::<$val_type>() == $byte_len);
let mut val = [0; $byte_len];
self.read_exact(&mut val[..]).map_err(Error::Io)?;
Ok(endian::$readfn(&val))
Ok(<$val_type>::from_le_bytes(val))
}
}
}
impl<W: io::Write + ?Sized> WriteExt for W {
encoder_fn!(emit_u64, u64, u64_to_array_le);
encoder_fn!(emit_u32, u32, u32_to_array_le);
encoder_fn!(emit_u16, u16, u16_to_array_le);
encoder_fn!(emit_i64, i64, i64_to_array_le);
encoder_fn!(emit_i32, i32, i32_to_array_le);
encoder_fn!(emit_i16, i16, i16_to_array_le);
encoder_fn!(emit_u64, u64);
encoder_fn!(emit_u32, u32);
encoder_fn!(emit_u16, u16);
encoder_fn!(emit_i64, i64);
encoder_fn!(emit_i32, i32);
encoder_fn!(emit_i16, i16);
#[inline]
fn emit_i8(&mut self, v: i8) -> Result<(), io::Error> {
@ -254,12 +252,12 @@ impl<W: io::Write + ?Sized> WriteExt for W {
}
impl<R: Read + ?Sized> ReadExt for R {
decoder_fn!(read_u64, u64, slice_to_u64_le, 8);
decoder_fn!(read_u32, u32, slice_to_u32_le, 4);
decoder_fn!(read_u16, u16, slice_to_u16_le, 2);
decoder_fn!(read_i64, i64, slice_to_i64_le, 8);
decoder_fn!(read_i32, i32, slice_to_i32_le, 4);
decoder_fn!(read_i16, i16, slice_to_i16_le, 2);
decoder_fn!(read_u64, u64, 8);
decoder_fn!(read_u32, u32, 4);
decoder_fn!(read_u16, u16, 2);
decoder_fn!(read_i64, i64, 8);
decoder_fn!(read_i32, i32, 4);
decoder_fn!(read_i16, i16, 2);
#[inline]
fn read_u8(&mut self) -> Result<u8, Error> {
@ -831,7 +829,6 @@ mod tests {
use super::{deserialize, serialize, Error, CheckedData, VarInt};
use super::{Transaction, BlockHash, FilterHash, TxMerkleNode, TxOut, TxIn};
use crate::consensus::{Encodable, deserialize_partial, Decodable};
use crate::util::endian::{u64_to_array_le, u32_to_array_le, u16_to_array_le};
use secp256k1::rand::{thread_rng, Rng};
#[cfg(feature = "std")]
use crate::network::{Address, message_blockdata::Inventory};
@ -893,9 +890,9 @@ mod tests {
assert_eq!(serialize(&VarInt(0xFFF)), vec![0xFDu8, 0xFF, 0xF]);
assert_eq!(serialize(&VarInt(0xF0F0F0F)), vec![0xFEu8, 0xF, 0xF, 0xF, 0xF]);
assert_eq!(serialize(&VarInt(0xF0F0F0F0F0E0)), vec![0xFFu8, 0xE0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0, 0]);
assert_eq!(test_varint_encode(0xFF, &u64_to_array_le(0x100000000)).unwrap(), VarInt(0x100000000));
assert_eq!(test_varint_encode(0xFE, &u64_to_array_le(0x10000)).unwrap(), VarInt(0x10000));
assert_eq!(test_varint_encode(0xFD, &u64_to_array_le(0xFD)).unwrap(), VarInt(0xFD));
assert_eq!(test_varint_encode(0xFF, &0x100000000_u64.to_le_bytes()).unwrap(), VarInt(0x100000000));
assert_eq!(test_varint_encode(0xFE, &0x10000_u64.to_le_bytes()).unwrap(), VarInt(0x10000));
assert_eq!(test_varint_encode(0xFD, &0xFD_u64.to_le_bytes()).unwrap(), VarInt(0xFD));
// Test that length calc is working correctly
test_varint_len(VarInt(0), 1);
@ -924,11 +921,11 @@ mod tests {
#[test]
fn deserialize_nonminimal_vec() {
// Check the edges for variant int
assert_eq!(discriminant(&test_varint_encode(0xFF, &u64_to_array_le(0x100000000-1)).unwrap_err()),
assert_eq!(discriminant(&test_varint_encode(0xFF, &(0x100000000_u64-1).to_le_bytes()).unwrap_err()),
discriminant(&Error::NonMinimalVarInt));
assert_eq!(discriminant(&test_varint_encode(0xFE, &u32_to_array_le(0x10000-1)).unwrap_err()),
assert_eq!(discriminant(&test_varint_encode(0xFE, &(0x10000_u64-1).to_le_bytes()).unwrap_err()),
discriminant(&Error::NonMinimalVarInt));
assert_eq!(discriminant(&test_varint_encode(0xFD, &u16_to_array_le(0xFD-1)).unwrap_err()),
assert_eq!(discriminant(&test_varint_encode(0xFD, &(0xFD_u64-1).to_le_bytes()).unwrap_err()),
discriminant(&Error::NonMinimalVarInt));
assert_eq!(discriminant(&deserialize::<Vec<u8>>(&[0xfd, 0x00, 0x00]).unwrap_err()),

View File

@ -17,7 +17,6 @@ use crate::blockdata::transaction::EncodeSigningDataResult;
use crate::blockdata::witness::Witness;
use crate::consensus::{encode, Encodable};
use crate::error::impl_std_error;
use crate::util::endian;
use crate::hashes::{sha256, sha256d, Hash};
use crate::prelude::*;
use crate::util::taproot::{TapLeafHash, TAPROOT_ANNEX_PREFIX, TapSighashHash, LeafVersion};
@ -879,8 +878,7 @@ impl<R: Deref<Target = Transaction>> SighashCache<R> {
};
// hash the result
tx.consensus_encode(&mut writer)?;
let sighash_arr = endian::u32_to_array_le(sighash_type);
sighash_arr.consensus_encode(&mut writer)?;
sighash_type.to_le_bytes().consensus_encode(&mut writer)?;
Ok(())
}

View File

@ -10,12 +10,13 @@
use crate::prelude::*;
use core::{fmt, str, iter, slice};
use core::convert::TryInto;
use bitcoin_internals::write_err;
use crate::hashes::{sha256d, Hash, hex};
use secp256k1;
use crate::util::{endian, key};
use crate::util::key;
/// An error that might occur during base58 decoding
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
@ -171,14 +172,19 @@ pub fn from_check(data: &str) -> Result<Vec<u8>, Error> {
if ret.len() < 4 {
return Err(Error::TooShort(ret.len()));
}
let ck_start = ret.len() - 4;
let expected = endian::slice_to_u32_le(&sha256d::Hash::hash(&ret[..ck_start])[..4]);
let actual = endian::slice_to_u32_le(&ret[ck_start..(ck_start + 4)]);
let check_start = ret.len() - 4;
let hash_check = sha256d::Hash::hash(&ret[..check_start])[..4].try_into().expect("4 byte slice");
let data_check = ret[check_start..].try_into().expect("4 byte slice");
let expected = u32::from_le_bytes(hash_check);
let actual = u32::from_le_bytes(data_check);
if expected != actual {
return Err(Error::BadChecksum(expected, actual));
}
ret.truncate(ck_start);
ret.truncate(check_start);
Ok(ret)
}

View File

@ -1,106 +0,0 @@
// SPDX-License-Identifier: CC0-1.0
macro_rules! define_slice_to_be {
($name: ident, $type: ty) => {
#[inline]
pub fn $name(slice: &[u8]) -> $type {
assert_eq!(slice.len(), core::mem::size_of::<$type>());
let mut res = 0;
for i in 0..::core::mem::size_of::<$type>() {
res |= (slice[i] as $type) << (::core::mem::size_of::<$type>() - i - 1)*8;
}
res
}
}
}
macro_rules! define_slice_to_le {
($name: ident, $type: ty) => {
#[inline]
pub fn $name(slice: &[u8]) -> $type {
assert_eq!(slice.len(), core::mem::size_of::<$type>());
let mut res = 0;
for i in 0..::core::mem::size_of::<$type>() {
res |= (slice[i] as $type) << i*8;
}
res
}
}
}
macro_rules! define_be_to_array {
($name: ident, $type: ty, $byte_len: expr) => {
#[inline]
pub fn $name(val: $type) -> [u8; $byte_len] {
bitcoin_internals::const_assert!(core::mem::size_of::<$type>() == $byte_len);
let mut res = [0; $byte_len];
for i in 0..$byte_len {
res[i] = ((val >> ($byte_len - i - 1)*8) & 0xff) as u8;
}
res
}
}
}
macro_rules! define_le_to_array {
($name: ident, $type: ty, $byte_len: expr) => {
#[inline]
pub fn $name(val: $type) -> [u8; $byte_len] {
bitcoin_internals::const_assert!(core::mem::size_of::<$type>() == $byte_len);
let mut res = [0; $byte_len];
for i in 0..$byte_len {
res[i] = ((val >> i*8) & 0xff) as u8;
}
res
}
}
}
define_slice_to_be!(slice_to_u32_be, u32);
define_be_to_array!(u32_to_array_be, u32, 4);
define_slice_to_le!(slice_to_u16_le, u16);
define_slice_to_le!(slice_to_u32_le, u32);
define_slice_to_le!(slice_to_u64_le, u64);
define_le_to_array!(u16_to_array_le, u16, 2);
define_le_to_array!(u32_to_array_le, u32, 4);
define_le_to_array!(u64_to_array_le, u64, 8);
#[inline]
pub fn i16_to_array_le(val: i16) -> [u8; 2] {
u16_to_array_le(val as u16)
}
#[inline]
pub fn slice_to_i16_le(slice: &[u8]) -> i16 {
slice_to_u16_le(slice) as i16
}
#[inline]
pub fn slice_to_i32_le(slice: &[u8]) -> i32 {
slice_to_u32_le(slice) as i32
}
#[inline]
pub fn i32_to_array_le(val: i32) -> [u8; 4] {
u32_to_array_le(val as u32)
}
#[inline]
pub fn slice_to_i64_le(slice: &[u8]) -> i64 {
slice_to_u64_le(slice) as i64
}
#[inline]
pub fn i64_to_array_le(val: i64) -> [u8; 8] {
u64_to_array_le(val as u64)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn endianness_test() {
assert_eq!(slice_to_u32_be(&[0xde, 0xad, 0xbe, 0xef]), 0xdeadbeef);
assert_eq!(u32_to_array_be(0xdeadbeef), [0xde, 0xad, 0xbe, 0xef]);
assert_eq!(slice_to_u16_le(&[0xad, 0xde]), 0xdead);
assert_eq!(slice_to_u32_le(&[0xef, 0xbe, 0xad, 0xde]), 0xdeadbeef);
assert_eq!(slice_to_u64_le(&[0xef, 0xbe, 0xad, 0xde, 0xfe, 0xca, 0xad, 0x1b]), 0x1badcafedeadbeef);
assert_eq!(u16_to_array_le(0xdead), [0xad, 0xde]);
assert_eq!(u32_to_array_le(0xdeadbeef), [0xef, 0xbe, 0xad, 0xde]);
assert_eq!(u64_to_array_le(0x1badcafedeadbeef), [0xef, 0xbe, 0xad, 0xde, 0xfe, 0xca, 0xad, 0x1b]);
}
}

View File

@ -16,8 +16,6 @@ pub mod merkleblock;
pub mod psbt;
pub mod taproot;
pub(crate) mod endian;
use crate::prelude::*;
use crate::io;
use core::fmt;

View File

@ -12,7 +12,6 @@ use crate::consensus::encode::MAX_VEC_SIZE;
use crate::util::psbt::map::Map;
use crate::util::psbt::{raw, PartiallySignedTransaction};
use crate::util::psbt::Error;
use crate::util::endian::u32_to_array_le;
use crate::util::bip32::{ExtendedPubKey, Fingerprint, DerivationPath, ChildNumber};
/// Type: Unsigned Transaction PSBT_GLOBAL_UNSIGNED_TX = 0x00
@ -54,7 +53,7 @@ impl Map for PartiallySignedTransaction {
value: {
let mut ret = Vec::with_capacity(4 + derivation.len() * 4);
ret.extend(fingerprint.as_bytes());
derivation.into_iter().for_each(|n| ret.extend(&u32_to_array_le((*n).into())));
derivation.into_iter().for_each(|n| ret.extend(&u32::from(*n).to_le_bytes()));
ret
}
});
@ -67,7 +66,7 @@ impl Map for PartiallySignedTransaction {
type_value: PSBT_GLOBAL_VERSION,
key: vec![],
},
value: u32_to_array_le(self.version).to_vec()
value: self.version.to_le_bytes().to_vec()
});
}