Merge rust-bitcoin/rust-bitcoin#2024: Add VarInt from implementations by way of macro
0419fa278b
Add VarInt from implementations by way of macro (Tobin C. Harding) Pull request description: Throughout the codebase we cast values to `u64` when constructing a `VarInt`. We can make the code marginally cleaner by adding `From<T>` impls for all unsigned integer types less than or equal to 64 bits. Also allows us to (possibly unnecessarily) comment the cast in a single place. ACKs for top commit: sanket1729: utACK0419fa278b
apoelstra: ACK0419fa278b
Tree-SHA512: 0cbcc7e9ec6a1a102693cb13685c348672fb13b098cbecd0a36bed0331165adb008f149f87f7b0c64f131974cfe513adbc12f508bc4853906adb2a65c0c647ee
This commit is contained in:
commit
407dec0bce
|
@ -74,7 +74,7 @@ impl convert::AsRef<Transaction> for PrefilledTransaction {
|
||||||
impl Encodable for PrefilledTransaction {
|
impl Encodable for PrefilledTransaction {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode<S: io::Write + ?Sized>(&self, mut s: &mut S) -> Result<usize, io::Error> {
|
fn consensus_encode<S: io::Write + ?Sized>(&self, mut s: &mut S) -> Result<usize, io::Error> {
|
||||||
Ok(VarInt(self.idx as u64).consensus_encode(&mut s)? + self.tx.consensus_encode(&mut s)?)
|
Ok(VarInt::from(self.idx).consensus_encode(&mut s)? + self.tx.consensus_encode(&mut s)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -391,7 +391,7 @@ impl<'a, W: io::Write> GcsFilterWriter<'a, W> {
|
||||||
mapped.sort_unstable();
|
mapped.sort_unstable();
|
||||||
|
|
||||||
// write number of elements as varint
|
// write number of elements as varint
|
||||||
let mut wrote = VarInt(mapped.len() as u64).consensus_encode(&mut self.writer)?;
|
let mut wrote = VarInt::from(mapped.len()).consensus_encode(&mut self.writer)?;
|
||||||
|
|
||||||
// write out deltas of sorted values into a Golonb-Rice coded bit stream
|
// write out deltas of sorted values into a Golonb-Rice coded bit stream
|
||||||
let mut writer = BitStreamWriter::new(self.writer);
|
let mut writer = BitStreamWriter::new(self.writer);
|
||||||
|
|
|
@ -276,7 +276,7 @@ impl Block {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// base_size == size of header + size of encoded transaction count.
|
/// base_size == size of header + size of encoded transaction count.
|
||||||
fn base_size(&self) -> usize { 80 + VarInt(self.txdata.len() as u64).len() }
|
fn base_size(&self) -> usize { 80 + VarInt::from(self.txdata.len()).len() }
|
||||||
|
|
||||||
/// Returns the size of the block.
|
/// Returns the size of the block.
|
||||||
///
|
///
|
||||||
|
|
|
@ -227,7 +227,7 @@ impl TxIn {
|
||||||
// Size in vbytes:
|
// Size in vbytes:
|
||||||
// previous_output (36) + script_sig varint len + script_sig push + sequence (4)
|
// previous_output (36) + script_sig varint len + script_sig push + sequence (4)
|
||||||
Weight::from_non_witness_data_size(
|
Weight::from_non_witness_data_size(
|
||||||
(36 + VarInt(script_sig_size as u64).len() + script_sig_size + 4) as u64,
|
(36 + VarInt::from(script_sig_size).len() + script_sig_size + 4) as u64,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,9 +501,7 @@ impl TxOut {
|
||||||
let script_len = self.script_pubkey.len();
|
let script_len = self.script_pubkey.len();
|
||||||
// In vbytes:
|
// In vbytes:
|
||||||
// value (8) + script varint len + script push
|
// value (8) + script varint len + script push
|
||||||
Weight::from_non_witness_data_size(
|
Weight::from_non_witness_data_size((8 + VarInt::from(script_len).len() + script_len) as u64)
|
||||||
(8 + VarInt(script_len as u64).len() + script_len) as u64,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a `TxOut` with given script and the smallest possible `value` that is **not** dust
|
/// Creates a `TxOut` with given script and the smallest possible `value` that is **not** dust
|
||||||
|
|
|
@ -213,7 +213,7 @@ fn resize_if_needed(vec: &mut Vec<u8>, required_len: usize) {
|
||||||
|
|
||||||
impl Encodable for Witness {
|
impl Encodable for Witness {
|
||||||
fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
|
fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
|
||||||
let len = VarInt(self.witness_elements as u64);
|
let len = VarInt::from(self.witness_elements);
|
||||||
len.consensus_encode(w)?;
|
len.consensus_encode(w)?;
|
||||||
let content_with_indices_len = self.content.len();
|
let content_with_indices_len = self.content.len();
|
||||||
let indices_size = self.witness_elements * 4;
|
let indices_size = self.witness_elements * 4;
|
||||||
|
@ -233,14 +233,14 @@ impl Witness {
|
||||||
let index_size = witness_elements * 4;
|
let index_size = witness_elements * 4;
|
||||||
let content_size = slice
|
let content_size = slice
|
||||||
.iter()
|
.iter()
|
||||||
.map(|elem| elem.as_ref().len() + VarInt(elem.as_ref().len() as u64).len())
|
.map(|elem| elem.as_ref().len() + VarInt::from(elem.as_ref().len()).len())
|
||||||
.sum();
|
.sum();
|
||||||
|
|
||||||
let mut content = vec![0u8; content_size + index_size];
|
let mut content = vec![0u8; content_size + index_size];
|
||||||
let mut cursor = 0usize;
|
let mut cursor = 0usize;
|
||||||
for (i, elem) in slice.iter().enumerate() {
|
for (i, elem) in slice.iter().enumerate() {
|
||||||
encode_cursor(&mut content, content_size, i, cursor);
|
encode_cursor(&mut content, content_size, i, cursor);
|
||||||
let elem_len_varint = VarInt(elem.as_ref().len() as u64);
|
let elem_len_varint = VarInt::from(elem.as_ref().len());
|
||||||
elem_len_varint
|
elem_len_varint
|
||||||
.consensus_encode(&mut &mut content[cursor..cursor + elem_len_varint.len()])
|
.consensus_encode(&mut &mut content[cursor..cursor + elem_len_varint.len()])
|
||||||
.expect("writers on vec don't errors, space granted by content_size");
|
.expect("writers on vec don't errors, space granted by content_size");
|
||||||
|
@ -268,8 +268,8 @@ impl Witness {
|
||||||
|
|
||||||
/// 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().map(|el| VarInt(el.len() as u64).len() + el.len()).sum::<usize>()
|
self.iter().map(|el| VarInt::from(el.len()).len() + el.len()).sum::<usize>()
|
||||||
+ VarInt(self.witness_elements as u64).len()
|
+ VarInt::from(self.witness_elements).len()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear the witness.
|
/// Clear the witness.
|
||||||
|
@ -288,7 +288,7 @@ impl Witness {
|
||||||
fn push_slice(&mut self, new_element: &[u8]) {
|
fn push_slice(&mut self, new_element: &[u8]) {
|
||||||
self.witness_elements += 1;
|
self.witness_elements += 1;
|
||||||
let previous_content_end = self.indices_start;
|
let previous_content_end = self.indices_start;
|
||||||
let element_len_varint = VarInt(new_element.len() as u64);
|
let element_len_varint = VarInt::from(new_element.len());
|
||||||
let current_content_len = self.content.len();
|
let current_content_len = self.content.len();
|
||||||
let new_item_total_len = element_len_varint.len() + new_element.len();
|
let new_item_total_len = element_len_varint.len() + new_element.len();
|
||||||
self.content.resize(current_content_len + new_item_total_len + 4, 0);
|
self.content.resize(current_content_len + new_item_total_len + 4, 0);
|
||||||
|
|
|
@ -399,6 +399,21 @@ impl VarInt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Implements `From<T> for VarInt`.
|
||||||
|
///
|
||||||
|
/// `VarInt`s are consensus encoded as `u64`s so we store them as such. Casting from any integer size smaller than or equal to `u64` is always safe and the cast value is correctly handled by `consensus_encode`.
|
||||||
|
macro_rules! impl_var_int_from {
|
||||||
|
($($ty:tt),*) => {
|
||||||
|
$(
|
||||||
|
/// Creates a `VarInt` from a `usize` by casting the to a `u64`.
|
||||||
|
impl From<$ty> for VarInt {
|
||||||
|
fn from(x: $ty) -> Self { VarInt(x as u64) }
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl_var_int_from!(u8, u16, u32, u64, usize);
|
||||||
|
|
||||||
impl Encodable for VarInt {
|
impl Encodable for VarInt {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
|
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
|
||||||
|
@ -436,7 +451,7 @@ impl Decodable for VarInt {
|
||||||
if x < 0x100000000 {
|
if x < 0x100000000 {
|
||||||
Err(self::Error::NonMinimalVarInt)
|
Err(self::Error::NonMinimalVarInt)
|
||||||
} else {
|
} else {
|
||||||
Ok(VarInt(x))
|
Ok(VarInt::from(x))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0xFE => {
|
0xFE => {
|
||||||
|
@ -444,7 +459,7 @@ impl Decodable for VarInt {
|
||||||
if x < 0x10000 {
|
if x < 0x10000 {
|
||||||
Err(self::Error::NonMinimalVarInt)
|
Err(self::Error::NonMinimalVarInt)
|
||||||
} else {
|
} else {
|
||||||
Ok(VarInt(x as u64))
|
Ok(VarInt::from(x))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0xFD => {
|
0xFD => {
|
||||||
|
@ -452,10 +467,10 @@ impl Decodable for VarInt {
|
||||||
if x < 0xFD {
|
if x < 0xFD {
|
||||||
Err(self::Error::NonMinimalVarInt)
|
Err(self::Error::NonMinimalVarInt)
|
||||||
} else {
|
} else {
|
||||||
Ok(VarInt(x as u64))
|
Ok(VarInt::from(x))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
n => Ok(VarInt(n as u64)),
|
n => Ok(VarInt::from(n)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -436,7 +436,7 @@ impl Encodable for PartialMerkleTree {
|
||||||
ret += self.hashes.consensus_encode(w)?;
|
ret += self.hashes.consensus_encode(w)?;
|
||||||
|
|
||||||
let nb_bytes_for_bits = (self.bits.len() + 7) / 8;
|
let nb_bytes_for_bits = (self.bits.len() + 7) / 8;
|
||||||
ret += encode::VarInt(nb_bytes_for_bits as u64).consensus_encode(w)?;
|
ret += encode::VarInt::from(nb_bytes_for_bits).consensus_encode(w)?;
|
||||||
for chunk in self.bits.chunks(8) {
|
for chunk in self.bits.chunks(8) {
|
||||||
let mut byte = 0u8;
|
let mut byte = 0u8;
|
||||||
for (i, bit) in chunk.iter().enumerate() {
|
for (i, bit) in chunk.iter().enumerate() {
|
||||||
|
|
|
@ -148,7 +148,7 @@ impl Encodable for AddrV2 {
|
||||||
bytes: &[u8],
|
bytes: &[u8],
|
||||||
) -> Result<usize, io::Error> {
|
) -> Result<usize, io::Error> {
|
||||||
let len = network.consensus_encode(w)?
|
let len = network.consensus_encode(w)?
|
||||||
+ VarInt(bytes.len() as u64).consensus_encode(w)?
|
+ VarInt::from(bytes.len()).consensus_encode(w)?
|
||||||
+ bytes.len();
|
+ bytes.len();
|
||||||
w.emit_slice(bytes)?;
|
w.emit_slice(bytes)?;
|
||||||
Ok(len)
|
Ok(len)
|
||||||
|
|
|
@ -335,7 +335,7 @@ impl<'a> Encodable for HeaderSerializationWrapper<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
|
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
|
||||||
let mut len = 0;
|
let mut len = 0;
|
||||||
len += VarInt(self.0.len() as u64).consensus_encode(w)?;
|
len += VarInt::from(self.0.len()).consensus_encode(w)?;
|
||||||
for header in self.0.iter() {
|
for header in self.0.iter() {
|
||||||
len += header.consensus_encode(w)?;
|
len += header.consensus_encode(w)?;
|
||||||
len += 0u8.consensus_encode(w)?;
|
len += 0u8.consensus_encode(w)?;
|
||||||
|
|
|
@ -104,7 +104,7 @@ impl Key {
|
||||||
impl Serialize for Key {
|
impl Serialize for Key {
|
||||||
fn serialize(&self) -> Vec<u8> {
|
fn serialize(&self) -> Vec<u8> {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
VarInt((self.key.len() + 1) as u64)
|
VarInt::from(self.key.len() + 1)
|
||||||
.consensus_encode(&mut buf)
|
.consensus_encode(&mut buf)
|
||||||
.expect("in-memory writers don't error");
|
.expect("in-memory writers don't error");
|
||||||
|
|
||||||
|
|
|
@ -342,7 +342,7 @@ impl Serialize for TapTree {
|
||||||
let capacity = self
|
let capacity = self
|
||||||
.script_leaves()
|
.script_leaves()
|
||||||
.map(|l| {
|
.map(|l| {
|
||||||
l.script().len() + VarInt(l.script().len() as u64).len() // script version
|
l.script().len() + VarInt::from(l.script().len()).len() // script version
|
||||||
+ 1 // merkle branch
|
+ 1 // merkle branch
|
||||||
+ 1 // leaf version
|
+ 1 // leaf version
|
||||||
})
|
})
|
||||||
|
|
|
@ -198,7 +198,7 @@ mod message_signing {
|
||||||
pub fn signed_msg_hash(msg: &str) -> sha256d::Hash {
|
pub fn signed_msg_hash(msg: &str) -> sha256d::Hash {
|
||||||
let mut engine = sha256d::Hash::engine();
|
let mut engine = sha256d::Hash::engine();
|
||||||
engine.input(BITCOIN_SIGNED_MSG_PREFIX);
|
engine.input(BITCOIN_SIGNED_MSG_PREFIX);
|
||||||
let msg_len = encode::VarInt(msg.len() as u64);
|
let msg_len = encode::VarInt::from(msg.len());
|
||||||
msg_len.consensus_encode(&mut engine).expect("engines don't error");
|
msg_len.consensus_encode(&mut engine).expect("engines don't error");
|
||||||
engine.input(msg.as_bytes());
|
engine.input(msg.as_bytes());
|
||||||
sha256d::Hash::from_engine(engine)
|
sha256d::Hash::from_engine(engine)
|
||||||
|
|
Loading…
Reference in New Issue