|
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