1use std::io::{self, Cursor, Read, Write};
23
24use amplify::confinement::{Confined, MediumBlob, SmallBlob, TinyBlob, U32};
25use amplify::{confinement, ByteArray, Bytes32, IoError, Wrapper};
26
27use crate::{
28 Annex, Block, BlockHash, BlockHeader, BlockMerkleRoot, ControlBlock, InternalPk,
29 InvalidLeafVer, LeafVer, LockTime, Outpoint, Parity, RedeemScript, Sats, ScriptBytes,
30 ScriptPubkey, SeqNo, SigScript, Sighash, TapBranchHash, TapLeafHash, TapMerklePath, TapScript,
31 Tx, TxIn, TxOut, TxVer, Txid, Vout, Witness, WitnessScript, LIB_NAME_BITCOIN,
32 TAPROOT_ANNEX_PREFIX,
33};
34
35pub type VarIntArray<T, const MIN_LEN: usize = 0> = Confined<Vec<T>, MIN_LEN, U32>;
41
42pub type VarIntBytes<const MIN_LEN: usize = 0> = Confined<Vec<u8>, MIN_LEN, U32>;
43
44#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default)]
46#[derive(StrictType, StrictEncode, StrictDecode)]
47#[strict_type(lib = LIB_NAME_BITCOIN)]
48pub struct VarInt(pub u64);
49
50#[allow(clippy::len_without_is_empty)] impl VarInt {
52 pub const fn new(u: u64) -> Self { VarInt(u) }
53
54 pub fn with(u: impl Into<usize>) -> Self { VarInt(u.into() as u64) }
55
56 #[inline]
61 pub const fn len(&self) -> usize {
62 match self.0 {
63 0..=0xFC => 1,
64 0xFD..=0xFFFF => 3,
65 0x10000..=0xFFFFFFFF => 5,
66 _ => 9,
67 }
68 }
69
70 pub const fn to_u64(&self) -> u64 { self.0 }
71 pub const fn into_u64(self) -> u64 { self.0 }
72 pub fn to_usize(&self) -> usize {
73 usize::try_from(self.0).expect("transaction too large for a non-64 bit platform")
74 }
75 pub fn into_usize(self) -> usize { self.to_usize() }
76}
77
78impl<U: Into<u64> + Copy> PartialEq<U> for VarInt {
79 fn eq(&self, other: &U) -> bool { self.0.eq(&(*other).into()) }
80}
81
82pub trait LenVarInt {
83 fn len_var_int(&self) -> VarInt;
84}
85
86impl<T, const MIN_LEN: usize> LenVarInt for VarIntArray<T, MIN_LEN> {
87 fn len_var_int(&self) -> VarInt { VarInt::with(self.len()) }
88}
89
90#[derive(Wrapper, WrapperMut, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Default, Debug, From)]
91#[derive(StrictType, StrictEncode, StrictDecode)]
92#[strict_type(lib = LIB_NAME_BITCOIN)]
93#[wrapper(Deref, Index, RangeOps, BorrowSlice, Hex)]
94#[wrapper_mut(DerefMut, IndexMut, RangeMut, BorrowSliceMut)]
95pub struct ByteStr(VarIntBytes);
96
97impl AsRef<[u8]> for ByteStr {
98 fn as_ref(&self) -> &[u8] { self.0.as_slice() }
99}
100
101impl From<Vec<u8>> for ByteStr {
102 fn from(value: Vec<u8>) -> Self {
103 Self(Confined::try_from(value).expect("byte string size exceeds 4GB"))
104 }
105}
106
107impl From<TinyBlob> for ByteStr {
108 fn from(vec: TinyBlob) -> Self { ByteStr(Confined::from_checked(vec.release())) }
109}
110
111impl From<SmallBlob> for ByteStr {
112 fn from(vec: SmallBlob) -> Self { ByteStr(Confined::from_checked(vec.release())) }
113}
114
115impl From<MediumBlob> for ByteStr {
116 fn from(vec: MediumBlob) -> Self { ByteStr(Confined::from_checked(vec.release())) }
117}
118
119impl ByteStr {
120 pub fn len_var_int(&self) -> VarInt { VarInt(self.len() as u64) }
121
122 pub fn into_vec(self) -> Vec<u8> { self.0.release() }
123}
124
125#[cfg(feature = "serde")]
126mod _serde {
127 use amplify::hex::{FromHex, ToHex};
128 use serde::de::Error;
129 use serde::{Deserialize, Deserializer, Serialize, Serializer};
130
131 use super::*;
132
133 impl Serialize for ByteStr {
134 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
135 where S: Serializer {
136 if serializer.is_human_readable() {
137 serializer.serialize_str(&self.to_hex())
138 } else {
139 serializer.serialize_bytes(self.as_slice())
140 }
141 }
142 }
143
144 impl<'de> Deserialize<'de> for ByteStr {
145 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
146 where D: Deserializer<'de> {
147 if deserializer.is_human_readable() {
148 String::deserialize(deserializer).and_then(|string| {
149 Self::from_hex(&string).map_err(|_| D::Error::custom("wrong hex data"))
150 })
151 } else {
152 let bytes = Vec::<u8>::deserialize(deserializer)?;
153 Ok(Self::from(bytes))
154 }
155 }
156 }
157}
158
159#[derive(Clone, PartialEq, Eq, Debug, Display, Error, From)]
160#[display(inner)]
161pub enum ConsensusDecodeError {
162 #[from]
163 #[from(io::Error)]
164 Io(IoError),
165
166 #[display(inner)]
167 #[from]
168 #[from(InvalidLeafVer)]
169 #[from(confinement::Error)]
170 Data(ConsensusDataError),
171}
172
173#[derive(Copy, Clone, PartialEq, Eq, Debug, Display, Error, From)]
174#[display(doc_comments)]
175pub enum ConsensusDataError {
176 DataNotConsumed,
178
179 NonMinimalVarInt,
181
182 InvalidXonlyPubkey(Bytes32),
184
185 LongTapMerklePath,
188
189 InvalidTapMerklePath,
191
192 #[from]
193 #[display(inner)]
194 InvalidLeafVer(InvalidLeafVer),
195
196 WrongAnnexFirstByte(u8),
198
199 #[from]
200 #[display(inner)]
201 Confined(confinement::Error),
202
203 UnsupportedSegwitFlag(u8),
205}
206
207pub trait ConsensusEncode {
208 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError>;
209 fn consensus_serialize(&self) -> Vec<u8> {
210 let mut buf = Vec::new();
211 self.consensus_encode(&mut buf).expect("in-memory writing can't fail");
212 buf
213 }
214}
215
216pub trait ConsensusDecode
217where Self: Sized
218{
219 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError>;
220 fn consensus_deserialize(bytes: impl AsRef<[u8]>) -> Result<Self, ConsensusDecodeError> {
221 let mut cursor = Cursor::new(bytes.as_ref());
222 let me = Self::consensus_decode(&mut cursor)?;
223 if cursor.position() as usize != bytes.as_ref().len() {
224 return Err(ConsensusDataError::DataNotConsumed.into());
225 }
226 Ok(me)
227 }
228}
229
230impl ConsensusEncode for BlockHeader {
231 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
232 let mut counter = self.version.consensus_encode(writer)?;
233 counter += self.prev_block_hash.consensus_encode(writer)?;
234 counter += self.merkle_root.consensus_encode(writer)?;
235 counter += self.time.consensus_encode(writer)?;
236 counter += self.bits.consensus_encode(writer)?;
237 counter += self.nonce.consensus_encode(writer)?;
238 Ok(counter)
239 }
240}
241
242impl ConsensusDecode for BlockHeader {
243 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
244 let version = i32::consensus_decode(reader)?;
245 let prev_block_hash = BlockHash::consensus_decode(reader)?;
246 let merkle_root = BlockMerkleRoot::consensus_decode(reader)?;
247 let time = u32::consensus_decode(reader)?;
248 let bits = u32::consensus_decode(reader)?;
249 let nonce = u32::consensus_decode(reader)?;
250 Ok(BlockHeader {
251 version,
252 prev_block_hash,
253 merkle_root,
254 time,
255 bits,
256 nonce,
257 })
258 }
259}
260
261impl ConsensusEncode for Block {
262 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
263 let mut counter = self.header.consensus_encode(writer)?;
264 counter += self.transactions.consensus_encode(writer)?;
265 Ok(counter)
266 }
267}
268
269impl ConsensusDecode for Block {
270 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
271 let header = BlockHeader::consensus_decode(reader)?;
272 let transactions = VarIntArray::<Tx>::consensus_decode(reader)?;
273 Ok(Block {
274 header,
275 transactions,
276 })
277 }
278}
279
280impl ConsensusEncode for BlockHash {
281 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
282 writer.write_all(&self.to_byte_array())?;
283 Ok(32)
284 }
285}
286
287impl ConsensusDecode for BlockHash {
288 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
289 <[u8; 32]>::consensus_decode(reader).map(Self::from)
290 }
291}
292
293impl ConsensusEncode for BlockMerkleRoot {
294 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
295 writer.write_all(&self.to_byte_array())?;
296 Ok(32)
297 }
298}
299
300impl ConsensusDecode for BlockMerkleRoot {
301 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
302 <[u8; 32]>::consensus_decode(reader).map(Self::from)
303 }
304}
305
306impl ConsensusEncode for Tx {
307 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
308 let mut counter = self.version.consensus_encode(writer)?;
309 if self.is_segwit() && !self.inputs.is_empty() {
310 0x00_u8.consensus_encode(writer)?;
311 0x01_u8.consensus_encode(writer)?;
312 counter += 2;
313 }
314 counter += self.inputs.consensus_encode(writer)?;
315 counter += self.outputs.consensus_encode(writer)?;
316 if self.is_segwit() {
317 for input in self.inputs() {
318 counter += input.witness.consensus_encode(writer)?;
319 }
320 }
321 counter += self.lock_time.consensus_encode(writer)?;
322 Ok(counter)
323 }
324}
325
326impl ConsensusDecode for Tx {
327 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
328 let version = TxVer::consensus_decode(reader)?;
329 let prefix = VarInt::consensus_decode(reader)?;
330
331 let segwit = prefix == 0u8;
332 let mut inputs = if segwit {
333 let flag = u8::consensus_decode(reader)?;
335 if flag != 0x01 {
336 Err(ConsensusDataError::UnsupportedSegwitFlag(flag))?
337 }
338 VarIntArray::<TxIn>::consensus_decode(reader)?
339 } else {
340 let mut inputs = Vec::with_capacity(prefix.to_usize());
342 for _ in 0..prefix.to_u64() {
343 inputs.push(TxIn::consensus_decode(reader)?);
344 }
345 VarIntArray::try_from(inputs)?
346 };
347
348 let outputs = VarIntArray::consensus_decode(reader)?;
349 if segwit {
350 for input in &mut inputs {
351 input.witness = Witness::consensus_decode(reader)?;
352 }
353 }
354 let lock_time = LockTime::consensus_decode(reader)?;
355
356 Ok(Tx {
357 version,
358 inputs,
359 outputs,
360 lock_time,
361 })
362 }
363}
364
365impl ConsensusEncode for TxVer {
366 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
367 self.to_consensus_i32().consensus_encode(writer)
368 }
369}
370
371impl ConsensusDecode for TxVer {
372 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
373 i32::consensus_decode(reader).map(Self::from_consensus_i32)
374 }
375}
376
377impl ConsensusEncode for TxIn {
378 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
379 let mut counter = self.prev_output.consensus_encode(writer)?;
380 counter += self.sig_script.consensus_encode(writer)?;
381 counter += self.sequence.consensus_encode(writer)?;
382 Ok(counter)
383 }
384}
385
386impl ConsensusDecode for TxIn {
387 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
388 let prev_output = Outpoint::consensus_decode(reader)?;
389 let sig_script = SigScript::consensus_decode(reader)?;
390 let sequence = SeqNo::consensus_decode(reader)?;
391 Ok(TxIn {
392 prev_output,
393 sig_script,
394 sequence,
395 witness: none!(),
396 })
397 }
398}
399
400impl ConsensusEncode for TxOut {
401 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
402 let mut counter = self.value.consensus_encode(writer)?;
403 counter += self.script_pubkey.consensus_encode(writer)?;
404 Ok(counter)
405 }
406}
407
408impl ConsensusDecode for TxOut {
409 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
410 let value = Sats::consensus_decode(reader)?;
411 let script_pubkey = ScriptPubkey::consensus_decode(reader)?;
412 Ok(TxOut {
413 value,
414 script_pubkey,
415 })
416 }
417}
418
419impl ConsensusEncode for Outpoint {
420 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
421 let mut counter = self.txid.consensus_encode(writer)?;
422 counter += self.vout.consensus_encode(writer)?;
423 Ok(counter)
424 }
425}
426
427impl ConsensusDecode for Outpoint {
428 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
429 let txid = Txid::consensus_decode(reader)?;
430 let vout = Vout::consensus_decode(reader)?;
431 Ok(Outpoint { txid, vout })
432 }
433}
434
435impl ConsensusEncode for Txid {
436 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
437 writer.write_all(&self.to_byte_array())?;
438 Ok(32)
439 }
440}
441
442impl ConsensusDecode for Txid {
443 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
444 <[u8; 32]>::consensus_decode(reader).map(Self::from)
445 }
446}
447
448impl ConsensusEncode for Vout {
449 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
450 self.into_u32().consensus_encode(writer)
451 }
452}
453
454impl ConsensusDecode for Vout {
455 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
456 u32::consensus_decode(reader).map(Self::from)
457 }
458}
459
460impl ConsensusEncode for SeqNo {
461 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
462 self.to_consensus_u32().consensus_encode(writer)
463 }
464}
465
466impl ConsensusDecode for SeqNo {
467 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
468 u32::consensus_decode(reader).map(Self::from_consensus_u32)
469 }
470}
471
472impl ConsensusEncode for LockTime {
473 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
474 self.to_consensus_u32().consensus_encode(writer)
475 }
476}
477
478impl ConsensusDecode for LockTime {
479 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
480 u32::consensus_decode(reader).map(Self::from_consensus_u32)
481 }
482}
483
484impl ConsensusEncode for ScriptBytes {
485 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
486 self.as_var_int_bytes().consensus_encode(writer)
487 }
488}
489
490impl ConsensusDecode for ScriptBytes {
491 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
492 VarIntArray::consensus_decode(reader).map(Self::from_inner)
493 }
494}
495
496impl ConsensusEncode for ScriptPubkey {
497 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
498 self.as_script_bytes().consensus_encode(writer)
499 }
500}
501
502impl ConsensusDecode for ScriptPubkey {
503 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
504 ScriptBytes::consensus_decode(reader).map(Self::from_inner)
505 }
506}
507
508impl ConsensusEncode for WitnessScript {
509 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
510 self.as_script_bytes().consensus_encode(writer)
511 }
512}
513
514impl ConsensusDecode for WitnessScript {
515 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
516 ScriptBytes::consensus_decode(reader).map(Self::from_inner)
517 }
518}
519
520impl ConsensusEncode for RedeemScript {
521 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
522 self.as_script_bytes().consensus_encode(writer)
523 }
524}
525
526impl ConsensusDecode for RedeemScript {
527 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
528 ScriptBytes::consensus_decode(reader).map(Self::from_inner)
529 }
530}
531
532impl ConsensusEncode for TapScript {
533 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
534 self.as_script_bytes().consensus_encode(writer)
535 }
536}
537
538impl ConsensusDecode for TapScript {
539 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
540 ScriptBytes::consensus_decode(reader).map(Self::from_inner)
541 }
542}
543
544impl ConsensusEncode for SigScript {
545 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
546 self.as_script_bytes().consensus_encode(writer)
547 }
548}
549
550impl ConsensusDecode for SigScript {
551 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
552 ScriptBytes::consensus_decode(reader).map(Self::from_inner)
553 }
554}
555
556impl ConsensusEncode for Annex {
557 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
558 self.as_var_int_bytes().consensus_encode(writer)
559 }
560}
561
562impl ConsensusDecode for Annex {
563 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
564 let bytes = VarIntBytes::<1>::consensus_decode(reader)?;
565 if bytes[0] != TAPROOT_ANNEX_PREFIX {
566 return Err(ConsensusDataError::WrongAnnexFirstByte(bytes[0]).into());
567 }
568 Ok(Self::from(bytes))
569 }
570}
571
572impl ConsensusEncode for Witness {
573 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
574 self.as_var_int_array().consensus_encode(writer)
575 }
576}
577
578impl ConsensusDecode for Witness {
579 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
580 VarIntArray::consensus_decode(reader).map(Self::from_inner)
581 }
582}
583
584impl ConsensusEncode for InternalPk {
585 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
586 writer.write_all(&self.to_byte_array())?;
587 Ok(32)
588 }
589}
590
591impl ConsensusEncode for TapBranchHash {
592 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
593 writer.write_all(&self.to_byte_array())?;
594 Ok(32)
595 }
596}
597
598impl ConsensusDecode for TapBranchHash {
599 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
600 let mut buf = [0u8; 32];
601 reader.read_exact(&mut buf)?;
602 Ok(TapBranchHash::from_byte_array(buf))
603 }
604}
605
606impl ConsensusDecode for InternalPk {
607 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
608 let mut buf = [0u8; 32];
609 reader.read_exact(&mut buf)?;
610 InternalPk::from_byte_array(buf)
611 .map_err(|_| ConsensusDataError::InvalidXonlyPubkey(buf.into()).into())
612 }
613}
614
615impl ConsensusEncode for ControlBlock {
616 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
617 let mut counter = 1;
618
619 let first_byte =
620 self.leaf_version.to_consensus_u8() & self.output_key_parity.to_consensus_u8();
621 first_byte.consensus_encode(writer)?;
622
623 counter += self.internal_pk.consensus_encode(writer)?;
624 for step in &self.merkle_branch {
625 counter += step.consensus_encode(writer)?;
626 }
627
628 Ok(counter)
629 }
630}
631
632impl ConsensusDecode for ControlBlock {
633 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
634 let first_byte = u8::consensus_decode(reader)?;
635 let leaf_version = LeafVer::from_consensus_u8(first_byte & 0xFE)?;
636 let output_key_parity = Parity::from_consensus_u8(first_byte & 0x01).expect("binary value");
637
638 let internal_key = InternalPk::consensus_decode(reader)?;
639
640 let mut buf = vec![];
641 reader.read_to_end(&mut buf)?;
642 let mut iter = buf.chunks_exact(32);
643 let merkle_branch = iter.by_ref().map(TapBranchHash::from_slice_checked);
644 let merkle_branch = TapMerklePath::try_from_iter(merkle_branch)
645 .map_err(|_| ConsensusDataError::LongTapMerklePath)?;
646 if !iter.remainder().is_empty() {
647 return Err(ConsensusDataError::InvalidTapMerklePath.into());
648 }
649
650 Ok(ControlBlock {
651 leaf_version,
652 output_key_parity,
653 internal_pk: internal_key,
654 merkle_branch,
655 })
656 }
657}
658
659impl ConsensusEncode for Sats {
660 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
661 self.0.consensus_encode(writer)
662 }
663}
664
665impl ConsensusDecode for Sats {
666 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
667 u64::consensus_decode(reader).map(Self)
668 }
669}
670
671impl ConsensusEncode for Sighash {
672 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
673 self.to_byte_array().consensus_encode(writer)
674 }
675}
676
677impl ConsensusEncode for TapLeafHash {
678 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
679 self.to_byte_array().consensus_encode(writer)
680 }
681}
682
683impl ConsensusEncode for VarInt {
684 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
685 match self.0 {
686 0..=0xFC => {
687 (self.0 as u8).consensus_encode(writer)?;
688 Ok(1)
689 }
690 0xFD..=0xFFFF => {
691 0xFDu8.consensus_encode(writer)?;
692 (self.0 as u16).consensus_encode(writer)?;
693 Ok(3)
694 }
695 0x10000..=0xFFFFFFFF => {
696 0xFEu8.consensus_encode(writer)?;
697 (self.0 as u32).consensus_encode(writer)?;
698 Ok(5)
699 }
700 _ => {
701 0xFFu8.consensus_encode(writer)?;
702 self.0.consensus_encode(writer)?;
703 Ok(9)
704 }
705 }
706 }
707}
708
709impl ConsensusDecode for VarInt {
710 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
711 let n = u8::consensus_decode(reader)?;
712 match n {
713 0xFF => {
714 let x = u64::consensus_decode(reader)?;
715 if x < 0x100000000 {
716 Err(ConsensusDataError::NonMinimalVarInt)?
717 } else {
718 Ok(VarInt::new(x))
719 }
720 }
721 0xFE => {
722 let x = u32::consensus_decode(reader)?;
723 if x < 0x10000 {
724 Err(ConsensusDataError::NonMinimalVarInt)?
725 } else {
726 Ok(VarInt::new(x as u64))
727 }
728 }
729 0xFD => {
730 let x = u16::consensus_decode(reader)?;
731 if x < 0xFD {
732 Err(ConsensusDataError::NonMinimalVarInt)?
733 } else {
734 Ok(VarInt::with(x))
735 }
736 }
737 n => Ok(VarInt::with(n)),
738 }
739 }
740}
741
742impl ConsensusEncode for ByteStr {
743 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
744 self.0.consensus_encode(writer)
745 }
746}
747
748impl ConsensusDecode for ByteStr {
749 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
750 VarIntArray::consensus_decode(reader).map(Self::from_inner)
751 }
752}
753
754impl<T: ConsensusEncode, const MIN_LEN: usize> ConsensusEncode for VarIntArray<T, MIN_LEN> {
755 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
756 let mut counter = self.len_var_int().consensus_encode(writer)?;
757 for item in self {
758 counter += item.consensus_encode(writer)?;
759 }
760 Ok(counter)
761 }
762}
763
764impl<T: ConsensusDecode, const MIN_LEN: usize> ConsensusDecode for VarIntArray<T, MIN_LEN> {
765 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
766 let len = VarInt::consensus_decode(reader)?;
767 let mut arr = Vec::new();
768 for _ in 0..len.0 {
769 arr.push(T::consensus_decode(reader)?);
770 }
771 VarIntArray::<T, MIN_LEN>::try_from(arr).map_err(ConsensusDecodeError::from)
772 }
773}
774
775impl ConsensusEncode for u8 {
776 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
777 writer.write_all(&[*self])?;
778 Ok(1)
779 }
780}
781
782impl ConsensusDecode for u8 {
783 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
784 let mut buf = [0u8; (Self::BITS / 8) as usize];
785 reader.read_exact(&mut buf)?;
786 Ok(Self::from_le_bytes(buf))
787 }
788}
789
790impl ConsensusEncode for u16 {
791 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
792 writer.write_all(&self.to_le_bytes())?;
793 Ok(2)
794 }
795}
796
797impl ConsensusDecode for u16 {
798 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
799 let mut buf = [0u8; (Self::BITS / 8) as usize];
800 reader.read_exact(&mut buf)?;
801 Ok(Self::from_le_bytes(buf))
802 }
803}
804
805impl ConsensusEncode for u32 {
806 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
807 writer.write_all(&self.to_le_bytes())?;
808 Ok(4)
809 }
810}
811
812impl ConsensusDecode for u32 {
813 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
814 let mut buf = [0u8; (Self::BITS / 8) as usize];
815 reader.read_exact(&mut buf)?;
816 Ok(Self::from_le_bytes(buf))
817 }
818}
819
820impl ConsensusEncode for i32 {
821 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
822 writer.write_all(&self.to_le_bytes())?;
823 Ok(4)
824 }
825}
826
827impl ConsensusDecode for i32 {
828 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
829 let mut buf = [0u8; (Self::BITS / 8) as usize];
830 reader.read_exact(&mut buf)?;
831 Ok(Self::from_le_bytes(buf))
832 }
833}
834
835impl ConsensusEncode for u64 {
836 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
837 writer.write_all(&self.to_le_bytes())?;
838 Ok(8)
839 }
840}
841
842impl ConsensusDecode for u64 {
843 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
844 let mut buf = [0u8; (Self::BITS / 8) as usize];
845 reader.read_exact(&mut buf)?;
846 Ok(Self::from_le_bytes(buf))
847 }
848}
849
850impl ConsensusEncode for Bytes32 {
851 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
852 writer.write_all(&self.to_byte_array())?;
853 Ok(8)
854 }
855}
856
857impl ConsensusEncode for [u8; 32] {
858 fn consensus_encode(&self, writer: &mut impl Write) -> Result<usize, IoError> {
859 writer.write_all(self)?;
860 Ok(8)
861 }
862}
863
864impl ConsensusDecode for [u8; 32] {
865 fn consensus_decode(reader: &mut impl Read) -> Result<Self, ConsensusDecodeError> {
866 let mut buf = [0u8; 32];
867 reader.read_exact(&mut buf)?;
868 Ok(buf)
869 }
870}
871
872#[cfg(test)]
873mod tests {
874 use super::*;
875
876 fn serialize(t: &impl ConsensusEncode) -> Vec<u8> {
877 let mut vec = Vec::new();
878 t.consensus_encode(&mut vec).unwrap();
879 vec
880 }
881
882 fn deserialize<T: ConsensusDecode>(d: impl AsRef<[u8]>) -> Result<T, ConsensusDecodeError> {
883 T::consensus_deserialize(d)
884 }
885
886 fn deserialize_partial<T: ConsensusDecode>(
887 d: impl AsRef<[u8]>,
888 ) -> Result<T, ConsensusDataError> {
889 let mut cursor = Cursor::new(d.as_ref());
890 T::consensus_decode(&mut cursor).map_err(|err| match err {
891 ConsensusDecodeError::Data(e) => e,
892 ConsensusDecodeError::Io(_) => unreachable!(),
893 })
894 }
895
896 #[test]
897 fn serialize_int_test() {
898 assert_eq!(serialize(&1u8), vec![1u8]);
900 assert_eq!(serialize(&0u8), vec![0u8]);
901 assert_eq!(serialize(&255u8), vec![255u8]);
902 assert_eq!(serialize(&1u16), vec![1u8, 0]);
904 assert_eq!(serialize(&256u16), vec![0u8, 1]);
905 assert_eq!(serialize(&5000u16), vec![136u8, 19]);
906 assert_eq!(serialize(&1u32), vec![1u8, 0, 0, 0]);
908 assert_eq!(serialize(&256u32), vec![0u8, 1, 0, 0]);
909 assert_eq!(serialize(&5000u32), vec![136u8, 19, 0, 0]);
910 assert_eq!(serialize(&500000u32), vec![32u8, 161, 7, 0]);
911 assert_eq!(serialize(&168430090u32), vec![10u8, 10, 10, 10]);
912 assert_eq!(serialize(&-1i32), vec![255u8, 255, 255, 255]);
914 assert_eq!(serialize(&-256i32), vec![0u8, 255, 255, 255]);
915 assert_eq!(serialize(&-5000i32), vec![120u8, 236, 255, 255]);
916 assert_eq!(serialize(&-500000i32), vec![224u8, 94, 248, 255]);
917 assert_eq!(serialize(&-168430090i32), vec![246u8, 245, 245, 245]);
918 assert_eq!(serialize(&1i32), vec![1u8, 0, 0, 0]);
919 assert_eq!(serialize(&256i32), vec![0u8, 1, 0, 0]);
920 assert_eq!(serialize(&5000i32), vec![136u8, 19, 0, 0]);
921 assert_eq!(serialize(&500000i32), vec![32u8, 161, 7, 0]);
922 assert_eq!(serialize(&168430090i32), vec![10u8, 10, 10, 10]);
923 assert_eq!(serialize(&1u64), vec![1u8, 0, 0, 0, 0, 0, 0, 0]);
925 assert_eq!(serialize(&256u64), vec![0u8, 1, 0, 0, 0, 0, 0, 0]);
926 assert_eq!(serialize(&5000u64), vec![136u8, 19, 0, 0, 0, 0, 0, 0]);
927 assert_eq!(serialize(&500000u64), vec![32u8, 161, 7, 0, 0, 0, 0, 0]);
928 assert_eq!(serialize(&723401728380766730u64), vec![10u8, 10, 10, 10, 10, 10, 10, 10]);
929 }
930
931 #[test]
932 fn serialize_varint_test() {
933 assert_eq!(serialize(&VarInt(10)), vec![10u8]);
934 assert_eq!(serialize(&VarInt(0xFC)), vec![0xFCu8]);
935 assert_eq!(serialize(&VarInt(0xFD)), vec![0xFDu8, 0xFD, 0]);
936 assert_eq!(serialize(&VarInt(0xFFF)), vec![0xFDu8, 0xFF, 0xF]);
937 assert_eq!(serialize(&VarInt(0xF0F0F0F)), vec![0xFEu8, 0xF, 0xF, 0xF, 0xF]);
938 assert_eq!(serialize(&VarInt(0xF0F0F0F0F0E0)), vec![
939 0xFFu8, 0xE0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0, 0
940 ]);
941 assert_eq!(
942 test_varint_encode(0xFF, &0x100000000_u64.to_le_bytes()).unwrap(),
943 VarInt(0x100000000)
944 );
945 assert_eq!(test_varint_encode(0xFE, &0x10000_u64.to_le_bytes()).unwrap(), VarInt(0x10000));
946 assert_eq!(test_varint_encode(0xFD, &0xFD_u64.to_le_bytes()).unwrap(), VarInt(0xFD));
947
948 test_varint_len(VarInt(0), 1);
950 test_varint_len(VarInt(0xFC), 1);
951 test_varint_len(VarInt(0xFD), 3);
952 test_varint_len(VarInt(0xFFFF), 3);
953 test_varint_len(VarInt(0x10000), 5);
954 test_varint_len(VarInt(0xFFFFFFFF), 5);
955 test_varint_len(VarInt(0xFFFFFFFF + 1), 9);
956 test_varint_len(VarInt(u64::MAX), 9);
957 }
958
959 fn test_varint_len(varint: VarInt, expected: usize) {
960 let mut encoder = vec![];
961 assert_eq!(varint.consensus_encode(&mut encoder).unwrap(), expected);
962 assert_eq!(varint.len(), expected);
963 }
964
965 fn test_varint_encode(n: u8, x: &[u8]) -> Result<VarInt, ConsensusDataError> {
966 let mut input = [0u8; 9];
967 input[0] = n;
968 input[1..x.len() + 1].copy_from_slice(x);
969 deserialize_partial::<VarInt>(&input)
970 }
971
972 #[test]
973 fn deserialize_nonminimal_vec() {
974 assert_eq!(
976 test_varint_encode(0xFF, &(0x100000000_u64 - 1).to_le_bytes()).unwrap_err(),
977 ConsensusDataError::NonMinimalVarInt
978 );
979 assert_eq!(
980 test_varint_encode(0xFE, &(0x10000_u64 - 1).to_le_bytes()).unwrap_err(),
981 ConsensusDataError::NonMinimalVarInt
982 );
983 assert_eq!(
984 test_varint_encode(0xFD, &(0xFD_u64 - 1).to_le_bytes()).unwrap_err(),
985 ConsensusDataError::NonMinimalVarInt
986 );
987
988 assert_eq!(
989 deserialize::<VarIntArray<u8>>(&[0xfd, 0x00, 0x00]).unwrap_err(),
990 ConsensusDataError::NonMinimalVarInt.into()
991 );
992 assert_eq!(
993 deserialize::<VarIntArray<u8>>(&[0xfd, 0xfc, 0x00]).unwrap_err(),
994 ConsensusDataError::NonMinimalVarInt.into()
995 );
996 assert_eq!(
997 deserialize::<VarIntArray<u8>>(&[0xfd, 0xfc, 0x00]).unwrap_err(),
998 ConsensusDataError::NonMinimalVarInt.into()
999 );
1000 assert_eq!(
1001 deserialize::<VarIntArray<u8>>(&[0xfe, 0xff, 0x00, 0x00, 0x00]).unwrap_err(),
1002 ConsensusDataError::NonMinimalVarInt.into()
1003 );
1004 assert_eq!(
1005 deserialize::<VarIntArray<u8>>(&[0xfe, 0xff, 0xff, 0x00, 0x00]).unwrap_err(),
1006 ConsensusDataError::NonMinimalVarInt.into()
1007 );
1008 assert_eq!(
1009 deserialize::<VarIntArray<u8>>(&[0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
1010 .unwrap_err(),
1011 ConsensusDataError::NonMinimalVarInt.into()
1012 );
1013 assert_eq!(
1014 deserialize::<VarIntArray<u8>>(&[0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00])
1015 .unwrap_err(),
1016 ConsensusDataError::NonMinimalVarInt.into()
1017 );
1018
1019 let mut vec_256 = vec![0; 259];
1020 vec_256[0] = 0xfd;
1021 vec_256[1] = 0x00;
1022 vec_256[2] = 0x01;
1023 assert!(deserialize::<VarIntArray<u8>>(&vec_256).is_ok());
1024
1025 let mut vec_253 = vec![0; 256];
1026 vec_253[0] = 0xfd;
1027 vec_253[1] = 0xfd;
1028 vec_253[2] = 0x00;
1029 assert!(deserialize::<VarIntArray<u8>>(&vec_253).is_ok());
1030 }
1031
1032 #[test]
1033 fn deserialize_int_test() {
1034 assert_eq!(deserialize([58u8]).ok(), Some(58u8));
1036
1037 assert_eq!(deserialize([0x01u8, 0x02]).ok(), Some(0x0201u16));
1039 assert_eq!(deserialize([0xABu8, 0xCD]).ok(), Some(0xCDABu16));
1040 assert_eq!(deserialize([0xA0u8, 0x0D]).ok(), Some(0xDA0u16));
1041 let failure16: Result<u16, _> = deserialize([1u8]);
1042 assert!(failure16.is_err());
1043
1044 assert_eq!(deserialize([0xABu8, 0xCD, 0, 0]).ok(), Some(0xCDABu32));
1046 assert_eq!(deserialize([0xA0u8, 0x0D, 0xAB, 0xCD]).ok(), Some(0xCDAB0DA0u32));
1047
1048 let failure32: Result<u32, _> = deserialize([1u8, 2, 3]);
1049 assert!(failure32.is_err());
1050
1051 assert_eq!(deserialize([0xABu8, 0xCD, 0, 0]).ok(), Some(0xCDABi32));
1053 assert_eq!(deserialize([0xA0u8, 0x0D, 0xAB, 0x2D]).ok(), Some(0x2DAB0DA0i32));
1054
1055 assert_eq!(deserialize([0, 0, 0, 0]).ok(), Some(-0_i32));
1056 assert_eq!(deserialize([0, 0, 0, 0]).ok(), Some(0_i32));
1057
1058 assert_eq!(deserialize([0xFF, 0xFF, 0xFF, 0xFF]).ok(), Some(-1_i32));
1059 assert_eq!(deserialize([0xFE, 0xFF, 0xFF, 0xFF]).ok(), Some(-2_i32));
1060 assert_eq!(deserialize([0x01, 0xFF, 0xFF, 0xFF]).ok(), Some(-255_i32));
1061 assert_eq!(deserialize([0x02, 0xFF, 0xFF, 0xFF]).ok(), Some(-254_i32));
1062
1063 let failurei32: Result<i32, _> = deserialize([1u8, 2, 3]);
1064 assert!(failurei32.is_err());
1065
1066 assert_eq!(deserialize([0xABu8, 0xCD, 0, 0, 0, 0, 0, 0]).ok(), Some(0xCDABu64));
1068 assert_eq!(
1069 deserialize([0xA0u8, 0x0D, 0xAB, 0xCD, 0x99, 0, 0, 0x99]).ok(),
1070 Some(0x99000099CDAB0DA0u64)
1071 );
1072 let failure64: Result<u64, _> = deserialize([1u8, 2, 3, 4, 5, 6, 7]);
1073 assert!(failure64.is_err());
1074 }
1075}