|
16 | 16 | //! |
17 | 17 |
|
18 | 18 | use std::io::Cursor; |
19 | | -use std::{error, fmt, io, mem}; |
| 19 | +use std::{any, error, fmt, io, mem}; |
20 | 20 |
|
21 | 21 | use bitcoin::ScriptBuf; |
22 | 22 | use secp256k1_zkp::{self, RangeProof, SurjectionProof, Tweak}; |
23 | 23 |
|
24 | 24 | use crate::hashes::{sha256, Hash}; |
25 | 25 | use crate::pset; |
26 | | -use crate::transaction::{Transaction, TxIn, TxOut}; |
27 | 26 |
|
28 | 27 | pub use bitcoin::{self, consensus::encode::MAX_VEC_SIZE}; |
29 | 28 |
|
@@ -314,47 +313,84 @@ impl Decodable for bitcoin::hashes::sha256d::Hash { |
314 | 313 | } |
315 | 314 |
|
316 | 315 | // Vectors |
317 | | -macro_rules! impl_vec { |
318 | | - ($type: ty) => { |
319 | | - impl Encodable for Vec<$type> { |
320 | | - #[inline] |
321 | | - fn consensus_encode<S: io::Write>(&self, mut s: S) -> Result<usize, Error> { |
322 | | - let mut len = 0; |
323 | | - len += VarInt(self.len() as u64).consensus_encode(&mut s)?; |
324 | | - for c in self.iter() { |
325 | | - len += c.consensus_encode(&mut s)?; |
326 | | - } |
327 | | - Ok(len) |
| 316 | +impl<T: Encodable + any::Any> Encodable for [T] { |
| 317 | + #[inline] |
| 318 | + fn consensus_encode<S: io::Write>(&self, mut s: S) -> Result<usize, Error> { |
| 319 | + if any::TypeId::of::<T>() == any::TypeId::of::<u8>() { |
| 320 | + // SAFETY: checked that T is exactly u8, so &self, of type, &[T], is exactly &[u8] |
| 321 | + let u8_slice = unsafe { |
| 322 | + std::slice::from_raw_parts(self.as_ptr().cast::<u8>(), self.len()) |
| 323 | + }; |
| 324 | + consensus_encode_with_size(u8_slice, s) |
| 325 | + } else { |
| 326 | + let mut len = 0; |
| 327 | + len += VarInt(self.len() as u64).consensus_encode(&mut s)?; |
| 328 | + for c in self { |
| 329 | + len += c.consensus_encode(&mut s)?; |
328 | 330 | } |
| 331 | + Ok(len) |
329 | 332 | } |
| 333 | + } |
| 334 | +} |
330 | 335 |
|
331 | | - impl Decodable for Vec<$type> { |
332 | | - #[inline] |
333 | | - fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, Error> { |
334 | | - let len = VarInt::consensus_decode(&mut d)?.0; |
335 | | - let byte_size = (len as usize) |
336 | | - .checked_mul(mem::size_of::<$type>()) |
337 | | - .ok_or(self::Error::ParseFailed("Invalid length"))?; |
338 | | - if byte_size > MAX_VEC_SIZE { |
339 | | - return Err(self::Error::OversizedVectorAllocation { |
340 | | - requested: byte_size, |
341 | | - max: MAX_VEC_SIZE, |
342 | | - }); |
343 | | - } |
344 | | - let mut ret = Vec::with_capacity(len as usize); |
345 | | - for _ in 0..len { |
346 | | - ret.push(Decodable::consensus_decode(&mut d)?); |
347 | | - } |
348 | | - Ok(ret) |
| 336 | +impl<T: Encodable + any::Any> Encodable for Vec<T> { |
| 337 | + #[inline] |
| 338 | + fn consensus_encode<S: io::Write>(&self, s: S) -> Result<usize, Error> { |
| 339 | + self[..].consensus_encode(s) |
| 340 | + } |
| 341 | +} |
| 342 | + |
| 343 | +impl<T: Encodable + any::Any> Encodable for Box<[T]> { |
| 344 | + #[inline] |
| 345 | + fn consensus_encode<S: io::Write>(&self, s: S) -> Result<usize, Error> { |
| 346 | + self[..].consensus_encode(s) |
| 347 | + } |
| 348 | +} |
| 349 | + |
| 350 | +impl<T: Decodable + any::Any> Decodable for Vec<T> { |
| 351 | + #[inline] |
| 352 | + fn consensus_decode<D: crate::ReadExt>(mut d: D) -> Result<Self, Error> { |
| 353 | + if any::TypeId::of::<T>() == any::TypeId::of::<u8>() { |
| 354 | + let s = VarInt::consensus_decode(&mut d)?.0 as usize; |
| 355 | + if s > MAX_VEC_SIZE { |
| 356 | + return Err(self::Error::OversizedVectorAllocation { |
| 357 | + requested: s, |
| 358 | + max: MAX_VEC_SIZE, |
| 359 | + }); |
| 360 | + } |
| 361 | + let mut v = vec![0; s]; |
| 362 | + d.read_slice(&mut v)?; |
| 363 | + // SAFETY: checked that T is exactly u8, so v, of type, Vec<u8>, is exactly Vec<T> |
| 364 | + unsafe { |
| 365 | + Ok(std::mem::transmute::<Vec<u8>, Vec<T>>(v)) |
| 366 | + } |
| 367 | + } else { |
| 368 | + let len = VarInt::consensus_decode(&mut d)?.0; |
| 369 | + let byte_size = (len as usize) |
| 370 | + .checked_mul(mem::size_of::<T>()) |
| 371 | + .ok_or(self::Error::ParseFailed("Invalid length"))?; |
| 372 | + if byte_size > MAX_VEC_SIZE { |
| 373 | + return Err(self::Error::OversizedVectorAllocation { |
| 374 | + requested: byte_size, |
| 375 | + max: MAX_VEC_SIZE, |
| 376 | + }); |
349 | 377 | } |
| 378 | + let mut ret = Vec::with_capacity(len as usize); |
| 379 | + for _ in 0..len { |
| 380 | + ret.push(Decodable::consensus_decode(&mut d)?); |
| 381 | + } |
| 382 | + Ok(ret) |
350 | 383 | } |
351 | | - }; |
| 384 | + } |
| 385 | +} |
| 386 | + |
| 387 | +impl<T: Decodable + any::Any> Decodable for Box<[T]> { |
| 388 | + #[inline] |
| 389 | + fn consensus_decode<D: io::Read>(d: D) -> Result<Self, Error> { |
| 390 | + let v = Vec::<T>::consensus_decode(d)?; |
| 391 | + Ok(v.into()) |
| 392 | + } |
352 | 393 | } |
353 | | -impl_vec!(TxIn); |
354 | | -impl_vec!(TxOut); |
355 | | -impl_vec!(Transaction); |
356 | | -impl_vec!(TapLeafHash); |
357 | | -impl_vec!(Vec<u8>); // Vec<Vec<u8>> |
358 | 394 |
|
359 | 395 | macro_rules! impl_array { |
360 | 396 | ( $size:literal ) => { |
@@ -383,38 +419,6 @@ impl_array!(4); |
383 | 419 | impl_array!(32); |
384 | 420 | impl_array!(33); |
385 | 421 |
|
386 | | -impl Encodable for Box<[u8]> { |
387 | | - fn consensus_encode<W: io::Write>(&self, mut w: W) -> Result<usize, Error> { |
388 | | - consensus_encode_with_size(&self[..], &mut w) |
389 | | - } |
390 | | -} |
391 | | -impl Decodable for Box<[u8]> { |
392 | | - fn consensus_decode<D: io::Read>(d: D) -> Result<Self, Error> { |
393 | | - let v = Vec::<u8>::consensus_decode(d)?; |
394 | | - Ok(v.into()) |
395 | | - } |
396 | | -} |
397 | | - |
398 | | -impl Encodable for Vec<u8> { |
399 | | - fn consensus_encode<W: io::Write>(&self, mut w: W) -> Result<usize, Error> { |
400 | | - consensus_encode_with_size(&self[..], &mut w) |
401 | | - } |
402 | | -} |
403 | | -impl Decodable for Vec<u8> { |
404 | | - fn consensus_decode<D: crate::ReadExt>(mut d: D) -> Result<Self, Error> { |
405 | | - let s = VarInt::consensus_decode(&mut d)?.0 as usize; |
406 | | - if s > MAX_VEC_SIZE { |
407 | | - return Err(self::Error::OversizedVectorAllocation { |
408 | | - requested: s, |
409 | | - max: MAX_VEC_SIZE, |
410 | | - }); |
411 | | - } |
412 | | - let mut v = vec![0; s]; |
413 | | - d.read_slice(&mut v)?; |
414 | | - Ok(v) |
415 | | - } |
416 | | -} |
417 | | - |
418 | 422 | macro_rules! impl_box_option { |
419 | 423 | ($type: ty) => { |
420 | 424 | impl Encodable for Option<Box<$type>> { |
|
0 commit comments