• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stacks-network / stacks-core / 25904007932-1

15 May 2026 06:31AM UTC coverage: 47.459% (-38.5%) from 85.959%
25904007932-1

Pull #7210

github

869a54
web-flow
Merge 27877974d into 1c7b8e6ac
Pull Request #7210: [wip] epoch 4 release branch

36 of 53 new or added lines in 1 file covered. (67.92%)

88645 existing lines in 346 files now uncovered.

104136 of 219422 relevant lines covered (47.46%)

12897381.15 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

46.79
/stackslib/src/net/codec.rs
1
// Copyright (C) 2013-2020 Blockstack PBC, a public benefit corporation
2
// Copyright (C) 2020-2026 Stacks Open Internet Foundation
3
//
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

17
use std::collections::HashSet;
18
use std::io;
19
use std::io::prelude::*;
20
use std::io::Read;
21

22
use clarity::vm::types::QualifiedContractIdentifier;
23
use clarity::vm::ContractName;
24
use rand::{self, Rng};
25
use sha2::{Digest, Sha512_256};
26
use stacks_common::bitvec::BitVec;
27
use stacks_common::codec::{
28
    read_next, read_next_at_most, read_next_exact, write_next, Error as codec_error,
29
    StacksMessageCodec, MAX_MESSAGE_LEN, MAX_RELAYERS_LEN, PREAMBLE_ENCODED_SIZE,
30
};
31
use stacks_common::types::chainstate::{BlockHeaderHash, BurnchainHeaderHash};
32
use stacks_common::types::net::PeerAddress;
33
use stacks_common::types::StacksPublicKeyBuffer;
34
use stacks_common::util::hash::{to_hex, Hash160};
35
use stacks_common::util::retry::BoundReader;
36
use stacks_common::util::secp256k1::{MessageSignature, Secp256k1PrivateKey, Secp256k1PublicKey};
37

38
use crate::burnchains::{BurnchainView, PrivateKey, PublicKey};
39
use crate::chainstate::burn::ConsensusHash;
40
use crate::chainstate::nakamoto::NakamotoBlock;
41
use crate::chainstate::stacks::{
42
    StacksBlock, StacksMicroblock, StacksPublicKey, StacksTransaction, MAX_BLOCK_LEN,
43
};
44
use crate::net::db::LocalPeer;
45
use crate::net::{Error as net_error, *};
46

47
pub fn bitvec_len(bitlen: u16) -> u16 {
2,915,748✔
48
    (bitlen / 8) + (if bitlen % 8 != 0 { 1 } else { 0 })
2,915,748✔
49
}
2,915,748✔
50

51
impl Preamble {
52
    /// Make an empty preamble with the given version and fork-set identifier, and payload length.
53
    pub fn new(
12,948,274✔
54
        peer_version: u32,
12,948,274✔
55
        network_id: u32,
12,948,274✔
56
        block_height: u64,
12,948,274✔
57
        burn_block_hash: &BurnchainHeaderHash,
12,948,274✔
58
        stable_block_height: u64,
12,948,274✔
59
        stable_burn_block_hash: &BurnchainHeaderHash,
12,948,274✔
60
        payload_len: u32,
12,948,274✔
61
    ) -> Preamble {
12,948,274✔
62
        Preamble {
12,948,274✔
63
            peer_version,
12,948,274✔
64
            network_id,
12,948,274✔
65
            seq: 0,
12,948,274✔
66
            burn_block_height: block_height,
12,948,274✔
67
            burn_block_hash: burn_block_hash.clone(),
12,948,274✔
68
            burn_stable_block_height: stable_block_height,
12,948,274✔
69
            burn_stable_block_hash: stable_burn_block_hash.clone(),
12,948,274✔
70
            additional_data: 0,
12,948,274✔
71
            signature: MessageSignature::empty(),
12,948,274✔
72
            payload_len,
12,948,274✔
73
        }
12,948,274✔
74
    }
12,948,274✔
75

76
    /// Given the serialized message type and bits, sign the resulting message and store the
77
    /// signature.  message_bits includes the relayers, payload type, and payload.
78
    pub fn sign(
12,948,274✔
79
        &mut self,
12,948,274✔
80
        message_bits: &[u8],
12,948,274✔
81
        privkey: &Secp256k1PrivateKey,
12,948,274✔
82
    ) -> Result<(), net_error> {
12,948,274✔
83
        let mut digest_bits = [0u8; 32];
12,948,274✔
84
        let mut sha2 = Sha512_256::new();
12,948,274✔
85

86
        // serialize the premable with a blank signature
87
        let old_signature = self.signature.clone();
12,948,274✔
88
        self.signature = MessageSignature::empty();
12,948,274✔
89

90
        let mut preamble_bits = vec![];
12,948,274✔
91
        self.consensus_serialize(&mut preamble_bits)?;
12,948,274✔
92
        self.signature = old_signature;
12,948,274✔
93

94
        sha2.update(&preamble_bits[..]);
12,948,274✔
95
        sha2.update(message_bits);
12,948,274✔
96

97
        digest_bits.copy_from_slice(sha2.finalize().as_slice());
12,948,274✔
98

99
        let sig = privkey
12,948,274✔
100
            .sign(&digest_bits)
12,948,274✔
101
            .map_err(|se| net_error::SigningError(se.to_string()))?;
12,948,274✔
102

103
        self.signature = sig;
12,948,274✔
104
        Ok(())
12,948,274✔
105
    }
12,948,274✔
106

107
    /// Given the serialized message type and bits, verify the signature.
108
    /// message_bits includes the relayers, payload type, and payload
109
    pub fn verify(
12,899,001✔
110
        &mut self,
12,899,001✔
111
        message_bits: &[u8],
12,899,001✔
112
        pubkey: &Secp256k1PublicKey,
12,899,001✔
113
    ) -> Result<(), net_error> {
12,899,001✔
114
        let mut digest_bits = [0u8; 32];
12,899,001✔
115
        let mut sha2 = Sha512_256::new();
12,899,001✔
116

117
        // serialize the preamble with a blank signature
118
        let sig_bits = self.signature.clone();
12,899,001✔
119
        self.signature = MessageSignature::empty();
12,899,001✔
120

121
        let mut preamble_bits = vec![];
12,899,001✔
122
        self.consensus_serialize(&mut preamble_bits)?;
12,899,001✔
123
        self.signature = sig_bits;
12,899,001✔
124

125
        sha2.update(&preamble_bits[..]);
12,899,001✔
126
        sha2.update(message_bits);
12,899,001✔
127

128
        digest_bits.copy_from_slice(sha2.finalize().as_slice());
12,899,001✔
129

130
        let res = pubkey
12,899,001✔
131
            .verify(&digest_bits, &self.signature)
12,899,001✔
132
            .map_err(|_ve| net_error::VerifyingError("Failed to verify signature".to_string()))?;
12,899,001✔
133

134
        if res {
12,899,001✔
135
            Ok(())
12,899,001✔
136
        } else {
UNCOV
137
            Err(net_error::VerifyingError(
×
UNCOV
138
                "Invalid message signature".to_string(),
×
UNCOV
139
            ))
×
140
        }
141
    }
12,899,001✔
142
}
143

144
impl StacksMessageCodec for Preamble {
145
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
38,795,549✔
146
        write_next(fd, &self.peer_version)?;
38,795,549✔
147
        write_next(fd, &self.network_id)?;
38,795,549✔
148
        write_next(fd, &self.seq)?;
38,795,549✔
149
        write_next(fd, &self.burn_block_height)?;
38,795,549✔
150
        write_next(fd, &self.burn_block_hash)?;
38,795,549✔
151
        write_next(fd, &self.burn_stable_block_height)?;
38,795,549✔
152
        write_next(fd, &self.burn_stable_block_hash)?;
38,795,549✔
153
        write_next(fd, &self.additional_data)?;
38,795,549✔
154
        write_next(fd, &self.signature)?;
38,795,549✔
155
        write_next(fd, &self.payload_len)?;
38,795,549✔
156
        Ok(())
38,795,549✔
157
    }
38,795,549✔
158

159
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<Preamble, codec_error> {
12,930,048✔
160
        let peer_version: u32 = read_next(fd)?;
12,930,048✔
161
        let network_id: u32 = read_next(fd)?;
12,930,048✔
162
        let seq: u32 = read_next(fd)?;
12,930,048✔
163
        let burn_block_height: u64 = read_next(fd)?;
12,930,048✔
164
        let burn_block_hash: BurnchainHeaderHash = read_next(fd)?;
12,930,048✔
165
        let burn_stable_block_height: u64 = read_next(fd)?;
12,930,048✔
166
        let burn_stable_block_hash: BurnchainHeaderHash = read_next(fd)?;
12,930,048✔
167
        let additional_data: u32 = read_next(fd)?;
12,930,048✔
168
        let signature: MessageSignature = read_next(fd)?;
12,930,048✔
169
        let payload_len: u32 = read_next(fd)?;
12,930,048✔
170

171
        // minimum is 5 bytes -- a zero-length vector (4 bytes of 0) plus a type identifier (1 byte)
172
        if payload_len < 5 {
12,930,048✔
173
            test_debug!("Payload len is too small: {}", payload_len);
×
174
            return Err(codec_error::DeserializeError(format!(
×
175
                "Payload len is too small: {}",
×
176
                payload_len
×
177
            )));
×
178
        }
12,930,048✔
179

180
        if payload_len >= MAX_MESSAGE_LEN {
12,930,048✔
181
            test_debug!("Payload len is too big: {}", payload_len);
×
182
            return Err(codec_error::DeserializeError(format!(
×
183
                "Payload len is too big: {}",
×
184
                payload_len
×
185
            )));
×
186
        }
12,930,048✔
187

188
        if burn_block_height <= burn_stable_block_height {
12,930,048✔
189
            test_debug!(
×
190
                "burn block height {} <= burn stable block height {}",
191
                burn_block_height,
192
                burn_stable_block_height
193
            );
194
            return Err(codec_error::DeserializeError(format!(
×
195
                "Burn block height {} <= burn stable block height {}",
×
196
                burn_block_height, burn_stable_block_height
×
197
            )));
×
198
        }
12,930,048✔
199

200
        Ok(Preamble {
12,930,048✔
201
            peer_version,
12,930,048✔
202
            network_id,
12,930,048✔
203
            seq,
12,930,048✔
204
            burn_block_height,
12,930,048✔
205
            burn_block_hash,
12,930,048✔
206
            burn_stable_block_height,
12,930,048✔
207
            burn_stable_block_hash,
12,930,048✔
208
            additional_data,
12,930,048✔
209
            signature,
12,930,048✔
210
            payload_len,
12,930,048✔
211
        })
12,930,048✔
212
    }
12,930,048✔
213
}
214

215
impl StacksMessageCodec for GetBlocksInv {
216
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
1,365,660✔
217
        write_next(fd, &self.consensus_hash)?;
1,365,660✔
218
        write_next(fd, &self.num_blocks)?;
1,365,660✔
219
        Ok(())
1,365,660✔
220
    }
1,365,660✔
221

222
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<GetBlocksInv, codec_error> {
682,830✔
223
        let consensus_hash: ConsensusHash = read_next(fd)?;
682,830✔
224
        let num_blocks: u16 = read_next(fd)?;
682,830✔
225
        if num_blocks == 0 {
682,830✔
226
            return Err(codec_error::DeserializeError(
×
227
                "GetBlocksInv must request at least one block".to_string(),
×
228
            ));
×
229
        }
682,830✔
230

231
        Ok(GetBlocksInv {
682,830✔
232
            consensus_hash,
682,830✔
233
            num_blocks,
682,830✔
234
        })
682,830✔
235
    }
682,830✔
236
}
237

238
impl StacksMessageCodec for BlocksInvData {
239
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
1,344,078✔
240
        write_next(fd, &self.bitlen)?;
1,344,078✔
241
        write_next(fd, &self.block_bitvec)?;
1,344,078✔
242
        write_next(fd, &self.microblocks_bitvec)?;
1,344,078✔
243
        Ok(())
1,344,078✔
244
    }
1,344,078✔
245

246
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<BlocksInvData, codec_error> {
671,976✔
247
        let bitlen: u16 = read_next(fd)?;
671,976✔
248
        if bitlen == 0 {
671,976✔
UNCOV
249
            return Err(codec_error::DeserializeError(
×
UNCOV
250
                "BlocksInv must contain at least one block/microblock bit".to_string(),
×
UNCOV
251
            ));
×
252
        }
671,976✔
253

254
        let block_bitvec: Vec<u8> = read_next_exact::<_, u8>(fd, bitvec_len(bitlen).into())?;
671,976✔
255
        let microblocks_bitvec: Vec<u8> = read_next_exact::<_, u8>(fd, bitvec_len(bitlen).into())?;
671,976✔
256

257
        Ok(BlocksInvData {
671,976✔
258
            bitlen,
671,976✔
259
            block_bitvec,
671,976✔
260
            microblocks_bitvec,
671,976✔
261
        })
671,976✔
262
    }
671,976✔
263
}
264

265
impl BlocksInvData {
266
    pub fn empty() -> BlocksInvData {
×
267
        BlocksInvData {
×
268
            bitlen: 0,
×
269
            block_bitvec: vec![],
×
270
            microblocks_bitvec: vec![],
×
271
        }
×
272
    }
×
273

274
    #[allow(clippy::indexing_slicing)]
275
    pub fn compress_bools(bits: &[bool]) -> Vec<u8> {
1,367,334✔
276
        let bvl: u16 = bits
1,367,334✔
277
            .len()
1,367,334✔
278
            .try_into()
1,367,334✔
279
            .expect("FATAL: tried to compress more than u16::MAX bools");
1,367,334✔
280
        let mut bitvec = vec![0u8; bitvec_len(bvl) as usize];
1,367,334✔
281
        for (i, bit) in bits.iter().enumerate() {
22,328,280✔
282
            if *bit {
22,328,280✔
283
                bitvec[i / 8] |= 1u8 << (i % 8);
1,311,201✔
284
            }
21,017,079✔
285
        }
286
        bitvec
1,367,334✔
287
    }
1,367,334✔
288

289
    pub fn has_ith_block(&self, block_index: u16) -> bool {
42,660✔
290
        if block_index >= self.bitlen {
42,660✔
291
            return false;
3,312✔
292
        }
39,348✔
293

294
        let idx = block_index / 8;
39,348✔
295
        let bit = block_index % 8;
39,348✔
296
        let Some(bitvec_entry) = self.block_bitvec.get(idx as usize) else {
39,348✔
297
            return false;
×
298
        };
299
        (bitvec_entry & (1 << bit)) != 0
39,348✔
300
    }
42,660✔
301

302
    pub fn has_ith_microblock_stream(&self, block_index: u16) -> bool {
42,651✔
303
        if block_index >= self.bitlen {
42,651✔
304
            return false;
3,312✔
305
        }
39,339✔
306

307
        let idx = block_index / 8;
39,339✔
308
        let bit = block_index % 8;
39,339✔
309
        let Some(bitvec_entry) = self.microblocks_bitvec.get(idx as usize) else {
39,339✔
310
            return false;
×
311
        };
312
        bitvec_entry & (1 << bit) != 0
39,339✔
313
    }
42,651✔
314
}
315

316
impl StacksMessageCodec for GetNakamotoInvData {
317
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
465,984✔
318
        write_next(fd, &self.consensus_hash)?;
465,984✔
319
        Ok(())
465,984✔
320
    }
465,984✔
321

322
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<Self, codec_error> {
232,632✔
323
        let consensus_hash: ConsensusHash = read_next(fd)?;
232,632✔
324
        Ok(Self { consensus_hash })
232,632✔
325
    }
232,632✔
326
}
327

328
impl StacksMessageCodec for NakamotoInvData {
329
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
461,574✔
330
        write_next(fd, &self.tenures)?;
461,574✔
331
        Ok(())
461,574✔
332
    }
461,574✔
333

334
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<Self, codec_error> {
230,175✔
335
        Ok(Self {
336
            tenures: read_next(fd)?,
230,175✔
337
        })
338
    }
230,175✔
339
}
340

341
impl NakamotoInvData {
342
    pub fn try_from(bits: &[bool]) -> Result<Self, codec_error> {
230,787✔
343
        Ok(Self {
344
            tenures: BitVec::<2100>::try_from(bits).map_err(|e| {
230,787✔
345
                codec_error::SerializeError(format!(
×
346
                    "Could not serialize vec of {} bools: {}",
×
347
                    bits.len(),
×
348
                    e
×
349
                ))
×
350
            })?,
×
351
        })
352
    }
230,787✔
353

354
    pub fn has_ith_tenure(&self, tenure_index: u16) -> bool {
×
355
        self.tenures.get(tenure_index).unwrap_or(false)
×
356
    }
×
357
}
358

359
impl StacksMessageCodec for NakamotoBlocksData {
360
    #[cfg_attr(test, mutants::skip)]
361
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
17,100✔
362
        write_next(fd, &self.blocks)?;
17,100✔
363
        Ok(())
17,100✔
364
    }
17,100✔
365

366
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<Self, codec_error> {
8,496✔
367
        let blocks: Vec<NakamotoBlock> = {
8,496✔
368
            // loose upper-bound
369
            let mut bound_read = BoundReader::from_reader(fd, MAX_MESSAGE_LEN as u64);
8,496✔
370
            read_next_at_most::<_, NakamotoBlock>(&mut bound_read, NAKAMOTO_BLOCKS_PUSHED_MAX)
8,496✔
371
        }?;
×
372

373
        // only valid if there are no dups
374
        let mut present = HashSet::new();
8,496✔
375
        for block in blocks.iter() {
8,559✔
376
            if present.contains(&block.block_id()) {
8,559✔
377
                // no dups allowed
378
                return Err(codec_error::DeserializeError(
×
379
                    "Invalid NakamotoBlocksData: duplicate block".to_string(),
×
380
                ));
×
381
            }
8,559✔
382

383
            present.insert(block.block_id());
8,559✔
384
        }
385

386
        Ok(NakamotoBlocksData { blocks })
8,496✔
387
    }
8,496✔
388
}
389

390
impl StacksMessageCodec for GetPoxInv {
391
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
408,996✔
392
        write_next(fd, &self.consensus_hash)?;
408,996✔
393
        write_next(fd, &self.num_cycles)?;
408,996✔
394
        Ok(())
408,996✔
395
    }
408,996✔
396

397
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<GetPoxInv, codec_error> {
204,498✔
398
        let ch: ConsensusHash = read_next(fd)?;
204,498✔
399
        let num_rcs: u16 = read_next(fd)?;
204,498✔
400
        if num_rcs == 0 || num_rcs as u64 > GETPOXINV_MAX_BITLEN {
204,498✔
UNCOV
401
            return Err(codec_error::DeserializeError(
×
UNCOV
402
                "Invalid GetPoxInv bitlen".to_string(),
×
UNCOV
403
            ));
×
404
        }
204,498✔
405
        Ok(GetPoxInv {
204,498✔
406
            consensus_hash: ch,
204,498✔
407
            num_cycles: num_rcs,
204,498✔
408
        })
204,498✔
409
    }
204,498✔
410
}
411

412
impl PoxInvData {
413
    pub fn has_ith_reward_cycle(&self, index: u16) -> bool {
1,534,455✔
414
        if index >= self.bitlen {
1,534,455✔
415
            return false;
×
416
        }
1,534,455✔
417

418
        let idx = index / 8;
1,534,455✔
419
        let bit = index % 8;
1,534,455✔
420
        let Some(bitvec_entry) = self.pox_bitvec.get(idx as usize) else {
1,534,455✔
421
            return false;
×
422
        };
423
        bitvec_entry & (1 << bit) != 0
1,534,455✔
424
    }
1,534,455✔
425
}
426

427
impl StacksMessageCodec for PoxInvData {
428
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
408,996✔
429
        write_next(fd, &self.bitlen)?;
408,996✔
430
        write_next(fd, &self.pox_bitvec)?;
408,996✔
431
        Ok(())
408,996✔
432
    }
408,996✔
433

434
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<PoxInvData, codec_error> {
204,462✔
435
        let bitlen: u16 = read_next(fd)?;
204,462✔
436
        if bitlen == 0 || (bitlen as u64) > GETPOXINV_MAX_BITLEN {
204,462✔
UNCOV
437
            return Err(codec_error::DeserializeError(
×
UNCOV
438
                "Invalid PoxInvData bitlen".to_string(),
×
UNCOV
439
            ));
×
440
        }
204,462✔
441

442
        let pox_bitvec: Vec<u8> = read_next_exact::<_, u8>(fd, bitvec_len(bitlen).into())?;
204,462✔
443
        Ok(PoxInvData { bitlen, pox_bitvec })
204,462✔
444
    }
204,462✔
445
}
446

447
impl StacksMessageCodec for BlocksAvailableData {
448
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
21,060✔
449
        write_next(fd, &self.available)?;
21,060✔
450
        Ok(())
21,060✔
451
    }
21,060✔
452

453
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<BlocksAvailableData, codec_error> {
10,530✔
454
        let available: Vec<(ConsensusHash, BurnchainHeaderHash)> =
10,530✔
455
            read_next_at_most::<_, (ConsensusHash, BurnchainHeaderHash)>(
10,530✔
456
                fd,
10,530✔
457
                BLOCKS_AVAILABLE_MAX_LEN,
UNCOV
458
            )?;
×
459
        Ok(BlocksAvailableData { available })
10,530✔
460
    }
10,530✔
461
}
462

463
impl BlocksAvailableData {
464
    pub fn new() -> BlocksAvailableData {
×
465
        BlocksAvailableData { available: vec![] }
×
466
    }
×
467

468
    pub fn try_push(
×
469
        &mut self,
×
470
        ch: ConsensusHash,
×
471
        bhh: BurnchainHeaderHash,
×
472
    ) -> Result<(), net_error> {
×
473
        if self.available.len() < BLOCKS_AVAILABLE_MAX_LEN as usize {
×
474
            self.available.push((ch, bhh));
×
475
            return Ok(());
×
476
        } else {
477
            return Err(net_error::InvalidMessage);
×
478
        }
479
    }
×
480
}
481

482
impl StacksMessageCodec for BlocksDatum {
483
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
36,576✔
484
        write_next(fd, &self.0)?;
36,576✔
485
        write_next(fd, &self.1)?;
36,576✔
486
        Ok(())
36,576✔
487
    }
36,576✔
488

489
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<BlocksDatum, codec_error> {
18,288✔
490
        let ch: ConsensusHash = read_next(fd)?;
18,288✔
491
        let block = {
18,288✔
492
            let mut bound_read = BoundReader::from_reader(fd, MAX_BLOCK_LEN as u64);
18,288✔
493
            read_next(&mut bound_read)
18,288✔
494
        }?;
×
495

496
        Ok(BlocksDatum(ch, block))
18,288✔
497
    }
18,288✔
498
}
499

500
impl BlocksData {
501
    pub fn new() -> BlocksData {
×
502
        BlocksData { blocks: vec![] }
×
503
    }
×
504

505
    pub fn push(&mut self, ch: ConsensusHash, block: StacksBlock) {
×
506
        self.blocks.push(BlocksDatum(ch, block))
×
507
    }
×
508
}
509

510
impl StacksMessageCodec for BlocksData {
511
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
36,414✔
512
        write_next(fd, &self.blocks)?;
36,414✔
513
        Ok(())
36,414✔
514
    }
36,414✔
515

516
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<BlocksData, codec_error> {
18,207✔
517
        let blocks: Vec<BlocksDatum> = {
18,207✔
518
            // loose upper-bound
519
            let mut bound_read = BoundReader::from_reader(fd, MAX_MESSAGE_LEN as u64);
18,207✔
520
            read_next_at_most::<_, BlocksDatum>(&mut bound_read, BLOCKS_PUSHED_MAX)
18,207✔
521
        }?;
×
522

523
        // only valid if there are no dups
524
        let mut present = HashSet::new();
18,207✔
525
        for BlocksDatum(consensus_hash, _block) in blocks.iter() {
18,288✔
526
            if present.contains(consensus_hash) {
18,288✔
527
                // no dups allowed
528
                return Err(codec_error::DeserializeError(
×
529
                    "Invalid BlocksData: duplicate block".to_string(),
×
530
                ));
×
531
            }
18,288✔
532

533
            present.insert(consensus_hash.clone());
18,288✔
534
        }
535

536
        Ok(BlocksData { blocks })
18,207✔
537
    }
18,207✔
538
}
539

540
impl StacksMessageCodec for MicroblocksData {
541
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
×
542
        write_next(fd, &self.index_anchor_block)?;
×
543
        write_next(fd, &self.microblocks)?;
×
544
        Ok(())
×
545
    }
×
546

547
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<MicroblocksData, codec_error> {
×
548
        let index_anchor_block = read_next(fd)?;
×
549
        let microblocks: Vec<StacksMicroblock> = {
×
550
            // loose upper-bound
551
            let mut bound_read = BoundReader::from_reader(fd, MAX_MESSAGE_LEN as u64);
×
552
            read_next(&mut bound_read)
×
553
        }?;
×
554

555
        Ok(MicroblocksData {
×
556
            index_anchor_block,
×
557
            microblocks,
×
558
        })
×
559
    }
×
560
}
561

562
impl NeighborAddress {
563
    pub fn from_neighbor(n: &Neighbor) -> NeighborAddress {
9,989,382✔
564
        NeighborAddress {
9,989,382✔
565
            addrbytes: n.addr.addrbytes.clone(),
9,989,382✔
566
            port: n.addr.port,
9,989,382✔
567
            public_key_hash: Hash160::from_node_public_key(&n.public_key),
9,989,382✔
568
        }
9,989,382✔
569
    }
9,989,382✔
570
}
571

572
impl StacksMessageCodec for NeighborAddress {
573
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
1,134,950✔
574
        write_next(fd, &self.addrbytes)?;
1,134,950✔
575
        write_next(fd, &self.port)?;
1,134,950✔
576
        write_next(fd, &self.public_key_hash)?;
1,134,950✔
577
        Ok(())
1,134,950✔
578
    }
1,134,950✔
579

580
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<NeighborAddress, codec_error> {
566,739✔
581
        let addrbytes: PeerAddress = read_next(fd)?;
566,739✔
582
        let port: u16 = read_next(fd)?;
566,739✔
583
        let public_key_hash: Hash160 = read_next(fd)?;
566,739✔
584

585
        Ok(NeighborAddress {
566,739✔
586
            addrbytes,
566,739✔
587
            port,
566,739✔
588
            public_key_hash,
566,739✔
589
        })
566,739✔
590
    }
566,739✔
591
}
592

593
impl StacksMessageCodec for NeighborsData {
594
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
684,216✔
595
        write_next(fd, &self.neighbors)?;
684,216✔
596
        Ok(())
684,216✔
597
    }
684,216✔
598

599
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<NeighborsData, codec_error> {
342,005✔
600
        // don't allow list of more than the pre-set number of neighbors
601
        let neighbors: Vec<NeighborAddress> =
342,005✔
602
            read_next_at_most::<_, NeighborAddress>(fd, MAX_NEIGHBORS_DATA_LEN)?;
342,005✔
603
        Ok(NeighborsData { neighbors })
342,005✔
604
    }
342,005✔
605
}
606

607
impl HandshakeData {
608
    pub fn from_local_peer(local_peer: &LocalPeer) -> HandshakeData {
814,854✔
609
        let (addrbytes, port) = match local_peer.public_ip_address {
814,854✔
610
            Some((ref public_addrbytes, ref port)) => (public_addrbytes.clone(), *port),
413,638✔
611
            None => (local_peer.addrbytes.clone(), local_peer.port),
401,216✔
612
        };
613

614
        // transmit the empty string if our data URL compels us to bind to the anynet address
615
        let data_url = if local_peer.data_url.has_routable_host() {
814,854✔
616
            local_peer.data_url.clone()
814,854✔
617
        } else if let Some(data_port) = local_peer.data_url.get_port() {
×
618
            // deduce from public IP
619
            UrlString::try_from(format!("http://{}", addrbytes.to_socketaddr(data_port))).unwrap()
×
620
        } else {
621
            // unroutable, so don't bother
622
            UrlString::try_from("").unwrap()
×
623
        };
624

625
        HandshakeData {
814,854✔
626
            addrbytes,
814,854✔
627
            port,
814,854✔
628
            services: local_peer.services,
814,854✔
629
            node_public_key: StacksPublicKeyBuffer::from_public_key(
814,854✔
630
                &Secp256k1PublicKey::from_private(&local_peer.private_key),
814,854✔
631
            ),
814,854✔
632
            expire_block_height: local_peer.private_key_expire,
814,854✔
633
            data_url,
814,854✔
634
        }
814,854✔
635
    }
814,854✔
636
}
637

638
impl StacksMessageCodec for HandshakeData {
639
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
1,641,989✔
640
        write_next(fd, &self.addrbytes)?;
1,641,989✔
641
        write_next(fd, &self.port)?;
1,641,989✔
642
        write_next(fd, &self.services)?;
1,641,989✔
643
        write_next(fd, &self.node_public_key)?;
1,641,989✔
644
        write_next(fd, &self.expire_block_height)?;
1,641,989✔
645
        write_next(fd, &self.data_url)?;
1,641,989✔
646
        Ok(())
1,641,989✔
647
    }
1,641,989✔
648

649
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<HandshakeData, codec_error> {
814,276✔
650
        let addrbytes: PeerAddress = read_next(fd)?;
814,276✔
651
        let port: u16 = read_next(fd)?;
814,276✔
652
        if port == 0 {
814,276✔
653
            return Err(codec_error::DeserializeError(
×
654
                "Invalid handshake data: port is 0".to_string(),
×
655
            ));
×
656
        }
814,276✔
657

658
        let services: u16 = read_next(fd)?;
814,276✔
659
        let node_public_key: StacksPublicKeyBuffer = read_next(fd)?;
814,276✔
660
        let expire_block_height: u64 = read_next(fd)?;
814,276✔
661
        let data_url: UrlString = read_next(fd)?;
814,276✔
662
        Ok(HandshakeData {
814,276✔
663
            addrbytes,
814,276✔
664
            port,
814,276✔
665
            services,
814,276✔
666
            node_public_key,
814,276✔
667
            expire_block_height,
814,276✔
668
            data_url,
814,276✔
669
        })
814,276✔
670
    }
814,276✔
671
}
672

673
impl HandshakeAcceptData {
674
    pub fn new(local_peer: &LocalPeer, heartbeat_interval: u32) -> HandshakeAcceptData {
407,385✔
675
        HandshakeAcceptData {
407,385✔
676
            handshake: HandshakeData::from_local_peer(local_peer),
407,385✔
677
            heartbeat_interval,
407,385✔
678
        }
407,385✔
679
    }
407,385✔
680
}
681

682
impl StacksMessageCodec for HandshakeAcceptData {
683
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
814,770✔
684
        write_next(fd, &self.handshake)?;
814,770✔
685
        write_next(fd, &self.heartbeat_interval)?;
814,770✔
686
        Ok(())
814,770✔
687
    }
814,770✔
688

689
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<HandshakeAcceptData, codec_error> {
406,891✔
690
        let handshake: HandshakeData = read_next(fd)?;
406,891✔
691
        let heartbeat_interval: u32 = read_next(fd)?;
406,891✔
692
        Ok(HandshakeAcceptData {
406,891✔
693
            handshake,
406,891✔
694
            heartbeat_interval,
406,891✔
695
        })
406,891✔
696
    }
406,891✔
697
}
698

699
impl NackData {
700
    pub fn new(error_code: u32) -> NackData {
460,854✔
701
        NackData { error_code }
460,854✔
702
    }
460,854✔
703
}
704

705
impl StacksMessageCodec for NackData {
706
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
897,876✔
707
        write_next(fd, &self.error_code)?;
897,876✔
708
        Ok(())
897,876✔
709
    }
897,876✔
710

711
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<NackData, codec_error> {
448,695✔
712
        let error_code: u32 = read_next(fd)?;
448,695✔
713
        Ok(NackData { error_code })
448,695✔
714
    }
448,695✔
715
}
716

717
impl PingData {
UNCOV
718
    pub fn new() -> PingData {
×
UNCOV
719
        let mut rng = rand::thread_rng();
×
UNCOV
720
        let n = rng.gen();
×
UNCOV
721
        PingData { nonce: n }
×
UNCOV
722
    }
×
723
}
724

725
impl StacksMessageCodec for PingData {
UNCOV
726
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
×
UNCOV
727
        write_next(fd, &self.nonce)?;
×
UNCOV
728
        Ok(())
×
UNCOV
729
    }
×
730

UNCOV
731
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<PingData, codec_error> {
×
UNCOV
732
        let nonce: u32 = read_next(fd)?;
×
UNCOV
733
        Ok(PingData { nonce })
×
UNCOV
734
    }
×
735
}
736

737
impl PongData {
UNCOV
738
    pub fn from_ping(p: &PingData) -> PongData {
×
UNCOV
739
        PongData { nonce: p.nonce }
×
UNCOV
740
    }
×
741
}
742

743
impl StacksMessageCodec for PongData {
UNCOV
744
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
×
UNCOV
745
        write_next(fd, &self.nonce)?;
×
UNCOV
746
        Ok(())
×
UNCOV
747
    }
×
748

UNCOV
749
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<PongData, codec_error> {
×
UNCOV
750
        let nonce: u32 = read_next(fd)?;
×
UNCOV
751
        Ok(PongData { nonce })
×
UNCOV
752
    }
×
753
}
754

755
impl StacksMessageCodec for NatPunchData {
756
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
1,236✔
757
        write_next(fd, &self.addrbytes)?;
1,236✔
758
        write_next(fd, &self.port)?;
1,236✔
759
        write_next(fd, &self.nonce)?;
1,236✔
760
        Ok(())
1,236✔
761
    }
1,236✔
762

763
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<NatPunchData, codec_error> {
618✔
764
        let addrbytes: PeerAddress = read_next(fd)?;
618✔
765
        let port: u16 = read_next(fd)?;
618✔
766
        let nonce: u32 = read_next(fd)?;
618✔
767
        Ok(NatPunchData {
618✔
768
            addrbytes,
618✔
769
            port,
618✔
770
            nonce,
618✔
771
        })
618✔
772
    }
618✔
773
}
774

775
fn contract_id_consensus_serialize<W: Write>(
19,271,732✔
776
    fd: &mut W,
19,271,732✔
777
    cid: &QualifiedContractIdentifier,
19,271,732✔
778
) -> Result<(), codec_error> {
19,271,732✔
779
    let addr = &cid.issuer;
19,271,732✔
780
    let name = &cid.name;
19,271,732✔
781
    write_next(fd, &addr.version())?;
19,271,732✔
782
    write_next(fd, &addr.1)?;
19,271,732✔
783
    write_next(fd, name)?;
19,271,732✔
784
    Ok(())
19,271,732✔
785
}
19,271,732✔
786

787
fn contract_id_consensus_deserialize<R: Read>(
9,617,620✔
788
    fd: &mut R,
9,617,620✔
789
) -> Result<QualifiedContractIdentifier, codec_error> {
9,617,620✔
790
    let version: u8 = read_next(fd)?;
9,617,620✔
791
    let bytes: [u8; 20] = read_next(fd)?;
9,617,620✔
792
    let name: ContractName = read_next(fd)?;
9,617,620✔
793
    let qn = QualifiedContractIdentifier::new(
9,617,620✔
794
        StacksAddress::new(version, Hash160(bytes))
9,617,620✔
795
            .map_err(|_| {
9,617,620✔
796
                codec_error::DeserializeError(
×
797
                    "Failed to make StacksAddress with given version".into(),
×
798
                )
×
799
            })?
×
800
            .into(),
9,617,620✔
801
        name,
9,617,620✔
802
    );
803
    Ok(qn)
9,617,620✔
804
}
9,617,620✔
805

806
impl StacksMessageCodec for StackerDBHandshakeData {
807
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
786,596✔
808
        if self.smart_contracts.len() > 256 {
786,596✔
809
            return Err(codec_error::ArrayTooLong);
×
810
        }
786,596✔
811
        // force no more than 256 names in the protocol
812
        let len_u8: u8 = self.smart_contracts.len().try_into().expect("Unreachable");
786,596✔
813
        write_next(fd, &self.rc_consensus_hash)?;
786,596✔
814
        write_next(fd, &len_u8)?;
786,596✔
815
        for cid in self.smart_contracts.iter() {
10,451,372✔
816
            contract_id_consensus_serialize(fd, cid)?;
10,078,502✔
817
        }
818
        Ok(())
786,596✔
819
    }
786,596✔
820

821
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<StackerDBHandshakeData, codec_error> {
392,932✔
822
        let rc_consensus_hash = read_next(fd)?;
392,932✔
823
        let len_u8: u8 = read_next(fd)?;
392,932✔
824
        let mut smart_contracts = Vec::with_capacity(len_u8 as usize);
392,932✔
825
        for _ in 0..len_u8 {
392,932✔
826
            let cid: QualifiedContractIdentifier = contract_id_consensus_deserialize(fd)?;
5,030,095✔
827
            smart_contracts.push(cid);
5,030,095✔
828
        }
829
        Ok(StackerDBHandshakeData {
392,932✔
830
            rc_consensus_hash,
392,932✔
831
            smart_contracts,
392,932✔
832
        })
392,932✔
833
    }
392,932✔
834
}
835

836
impl StacksMessageCodec for StackerDBGetChunkInvData {
837
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
8,029,350✔
838
        contract_id_consensus_serialize(fd, &self.contract_id)?;
8,029,350✔
839
        write_next(fd, &self.rc_consensus_hash)?;
8,029,350✔
840
        Ok(())
8,029,350✔
841
    }
8,029,350✔
842

843
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<StackerDBGetChunkInvData, codec_error> {
4,005,936✔
844
        let contract_id: QualifiedContractIdentifier = contract_id_consensus_deserialize(fd)?;
4,005,936✔
845
        let rc_consensus_hash: ConsensusHash = read_next(fd)?;
4,005,936✔
846
        Ok(StackerDBGetChunkInvData {
4,005,936✔
847
            contract_id,
4,005,936✔
848
            rc_consensus_hash,
4,005,936✔
849
        })
4,005,936✔
850
    }
4,005,936✔
851
}
852

853
impl StacksMessageCodec for StackerDBChunkInvData {
854
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
8,092,746✔
855
        if self.slot_versions.len() > (stackerdb::STACKERDB_INV_MAX as usize) {
8,092,746✔
856
            return Err(codec_error::ArrayTooLong);
×
857
        }
8,092,746✔
858
        write_next(fd, &self.slot_versions)?;
8,092,746✔
859
        write_next(fd, &self.num_outbound_replicas)?;
8,092,746✔
860
        Ok(())
8,092,746✔
861
    }
8,092,746✔
862

863
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<StackerDBChunkInvData, codec_error> {
4,039,371✔
864
        let slot_versions: Vec<u32> = read_next_at_most(fd, stackerdb::STACKERDB_INV_MAX)?;
4,039,371✔
865
        let num_outbound_replicas: u32 = read_next(fd)?;
4,039,371✔
866
        Ok(StackerDBChunkInvData {
4,039,371✔
867
            slot_versions,
4,039,371✔
868
            num_outbound_replicas,
4,039,371✔
869
        })
4,039,371✔
870
    }
4,039,371✔
871
}
872

873
impl StacksMessageCodec for StackerDBGetChunkData {
874
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
173,934✔
875
        contract_id_consensus_serialize(fd, &self.contract_id)?;
173,934✔
876
        write_next(fd, &self.rc_consensus_hash)?;
173,934✔
877
        write_next(fd, &self.slot_id)?;
173,934✔
878
        write_next(fd, &self.slot_version)?;
173,934✔
879
        Ok(())
173,934✔
880
    }
173,934✔
881

882
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<StackerDBGetChunkData, codec_error> {
86,958✔
883
        let contract_id: QualifiedContractIdentifier = contract_id_consensus_deserialize(fd)?;
86,958✔
884
        let rc_consensus_hash: ConsensusHash = read_next(fd)?;
86,958✔
885
        let slot_id: u32 = read_next(fd)?;
86,958✔
886
        let slot_version: u32 = read_next(fd)?;
86,958✔
887
        Ok(StackerDBGetChunkData {
86,958✔
888
            contract_id,
86,958✔
889
            rc_consensus_hash,
86,958✔
890
            slot_id,
86,958✔
891
            slot_version,
86,958✔
892
        })
86,958✔
893
    }
86,958✔
894
}
895

896
impl StacksMessageCodec for StackerDBPushChunkData {
897
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
989,946✔
898
        contract_id_consensus_serialize(fd, &self.contract_id)?;
989,946✔
899
        write_next(fd, &self.rc_consensus_hash)?;
989,946✔
900
        write_next(fd, &self.chunk_data)?;
989,946✔
901
        Ok(())
989,946✔
902
    }
989,946✔
903

904
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<StackerDBPushChunkData, codec_error> {
494,631✔
905
        let contract_id: QualifiedContractIdentifier = contract_id_consensus_deserialize(fd)?;
494,631✔
906
        let rc_consensus_hash: ConsensusHash = read_next(fd)?;
494,631✔
907
        let chunk_data: StackerDBChunkData = read_next(fd)?;
494,631✔
908
        Ok(StackerDBPushChunkData {
494,631✔
909
            contract_id,
494,631✔
910
            rc_consensus_hash,
494,631✔
911
            chunk_data,
494,631✔
912
        })
494,631✔
913
    }
494,631✔
914
}
915

916
impl StacksMessageCodec for RelayData {
917
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
814,338✔
918
        write_next(fd, &self.peer)?;
814,338✔
919
        write_next(fd, &self.seq)?;
814,338✔
920
        Ok(())
814,338✔
921
    }
814,338✔
922

923
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<RelayData, codec_error> {
406,773✔
924
        let peer: NeighborAddress = read_next(fd)?;
406,773✔
925
        let seq: u32 = read_next(fd)?;
406,773✔
926
        Ok(RelayData { peer, seq })
406,773✔
927
    }
406,773✔
928
}
929

930
impl StacksMessageType {
931
    pub fn get_message_id(&self) -> StacksMessageID {
38,826,596✔
932
        match *self {
38,826,596✔
933
            StacksMessageType::Handshake(ref _m) => StacksMessageID::Handshake,
1,222,323✔
934
            StacksMessageType::HandshakeAccept(ref _m) => StacksMessageID::HandshakeAccept,
42,133✔
UNCOV
935
            StacksMessageType::HandshakeReject => StacksMessageID::HandshakeReject,
×
936
            StacksMessageType::GetNeighbors => StacksMessageID::GetNeighbors,
1,026,404✔
937
            StacksMessageType::Neighbors(ref _m) => StacksMessageID::Neighbors,
1,026,221✔
938
            StacksMessageType::GetPoxInv(ref _m) => StacksMessageID::GetPoxInv,
613,494✔
939
            StacksMessageType::PoxInv(ref _m) => StacksMessageID::PoxInv,
613,458✔
940
            StacksMessageType::GetBlocksInv(ref _m) => StacksMessageID::GetBlocksInv,
2,048,490✔
941
            StacksMessageType::BlocksInv(ref _m) => StacksMessageID::BlocksInv,
2,016,054✔
942
            StacksMessageType::BlocksAvailable(ref _m) => StacksMessageID::BlocksAvailable,
31,590✔
UNCOV
943
            StacksMessageType::MicroblocksAvailable(ref _m) => {
×
UNCOV
944
                StacksMessageID::MicroblocksAvailable
×
945
            }
946
            StacksMessageType::Blocks(ref _m) => StacksMessageID::Blocks,
54,621✔
947
            StacksMessageType::Microblocks(ref _m) => StacksMessageID::Microblocks,
×
948
            StacksMessageType::Transaction(ref _m) => StacksMessageID::Transaction,
14,958✔
949
            StacksMessageType::Nack(ref _m) => StacksMessageID::Nack,
1,346,571✔
UNCOV
950
            StacksMessageType::Ping(ref _m) => StacksMessageID::Ping,
×
UNCOV
951
            StacksMessageType::Pong(ref _m) => StacksMessageID::Pong,
×
952
            StacksMessageType::NatPunchRequest(ref _m) => StacksMessageID::NatPunchRequest,
1,854✔
953
            StacksMessageType::NatPunchReply(ref _m) => StacksMessageID::NatPunchReply,
1,854✔
954
            StacksMessageType::StackerDBHandshakeAccept(ref _h, ref _m) => {
1,179,528✔
955
                StacksMessageID::StackerDBHandshakeAccept
1,179,528✔
956
            }
957
            StacksMessageType::StackerDBGetChunkInv(ref _m) => {
12,035,286✔
958
                StacksMessageID::StackerDBGetChunkInv
12,035,286✔
959
            }
960
            StacksMessageType::StackerDBChunkInv(ref _m) => StacksMessageID::StackerDBChunkInv,
12,132,117✔
961
            StacksMessageType::StackerDBGetChunk(ref _m) => StacksMessageID::StackerDBGetChunk,
260,892✔
962
            StacksMessageType::StackerDBChunk(ref _m) => StacksMessageID::StackerDBChunk,
258,210✔
963
            StacksMessageType::StackerDBPushChunk(ref _m) => StacksMessageID::StackerDBPushChunk,
1,484,577✔
964
            StacksMessageType::GetNakamotoInv(ref _m) => StacksMessageID::GetNakamotoInv,
698,616✔
965
            StacksMessageType::NakamotoInv(ref _m) => StacksMessageID::NakamotoInv,
691,749✔
966
            StacksMessageType::NakamotoBlocks(ref _m) => StacksMessageID::NakamotoBlocks,
25,596✔
967
        }
968
    }
38,826,596✔
969

970
    pub fn get_message_name(&self) -> &'static str {
18,264,436✔
971
        match *self {
18,264,436✔
972
            StacksMessageType::Handshake(ref _m) => "Handshake",
407,469✔
973
            StacksMessageType::HandshakeAccept(ref _m) => "HandshakeAccept",
13,959✔
UNCOV
974
            StacksMessageType::HandshakeReject => "HandshakeReject",
×
975
            StacksMessageType::GetNeighbors => "GetNeighbors",
342,148✔
976
            StacksMessageType::Neighbors(ref _m) => "Neighbors",
342,005✔
977
            StacksMessageType::GetPoxInv(ref _m) => "GetPoxInv",
204,498✔
978
            StacksMessageType::PoxInv(ref _m) => "PoxInv",
408,960✔
979
            StacksMessageType::GetBlocksInv(ref _m) => "GetBlocksInv",
682,830✔
980
            StacksMessageType::BlocksInv(ref _m) => "BlocksInv",
1,344,015✔
981
            StacksMessageType::BlocksAvailable(ref _m) => "BlocksAvailable",
10,530✔
982
            StacksMessageType::MicroblocksAvailable(ref _m) => "MicroblocksAvailable",
×
983
            StacksMessageType::Blocks(ref _m) => "Blocks",
18,207✔
984
            StacksMessageType::Microblocks(ref _m) => "Microblocks",
×
985
            StacksMessageType::Transaction(ref _m) => "Transaction",
4,986✔
986
            StacksMessageType::Nack(ref _m) => "Nack",
897,633✔
UNCOV
987
            StacksMessageType::Ping(ref _m) => "Ping",
×
UNCOV
988
            StacksMessageType::Pong(ref _m) => "Pong",
×
989
            StacksMessageType::NatPunchRequest(ref _m) => "NatPunchRequest",
618✔
990
            StacksMessageType::NatPunchReply(ref _m) => "NatPunchReply",
618✔
991
            StacksMessageType::StackerDBHandshakeAccept(ref _h, ref _m) => {
392,932✔
992
                "StackerDBHandshakeAccept"
392,932✔
993
            }
994
            StacksMessageType::StackerDBGetChunkInv(ref _m) => "StackerDBGetChunkInv",
4,014,675✔
995
            StacksMessageType::StackerDBChunkInv(ref _m) => "StackerDBChunkInv",
7,721,784✔
996
            StacksMessageType::StackerDBGetChunk(ref _m) => "StackerDBGetChunk",
86,967✔
997
            StacksMessageType::StackerDBChunk(ref _m) => "StackerDBChunk",
172,125✔
998
            StacksMessageType::StackerDBPushChunk(ref _m) => "StackerDBPushChunk",
494,973✔
999
            StacksMessageType::GetNakamotoInv(ref _m) => "GetNakamotoInv",
232,992✔
1000
            StacksMessageType::NakamotoInv(ref _m) => "NakamotoInv",
460,962✔
1001
            StacksMessageType::NakamotoBlocks(ref _m) => "NakamotoBlocks",
8,550✔
1002
        }
1003
    }
18,264,436✔
1004

1005
    pub fn get_message_description(&self) -> String {
19,992,840✔
1006
        match *self {
19,992,840✔
1007
            StacksMessageType::Handshake(ref m) => {
407,385✔
1008
                format!("Handshake({})", &to_hex(&m.node_public_key.to_bytes()))
407,385✔
1009
            }
1010
            StacksMessageType::HandshakeAccept(ref m) => format!(
28,046✔
1011
                "HandshakeAccept({},{})",
1012
                &to_hex(&m.handshake.node_public_key.to_bytes()),
28,046✔
1013
                m.heartbeat_interval
1014
            ),
UNCOV
1015
            StacksMessageType::HandshakeReject => "HandshakeReject".to_string(),
×
1016
            StacksMessageType::GetNeighbors => "GetNeighbors".to_string(),
342,108✔
1017
            StacksMessageType::Neighbors(ref m) => format!("Neighbors({:?})", m.neighbors),
684,113✔
1018
            StacksMessageType::GetPoxInv(ref m) => {
204,498✔
1019
                format!("GetPoxInv({},{}))", &m.consensus_hash, m.num_cycles)
204,498✔
1020
            }
1021
            StacksMessageType::PoxInv(ref m) => {
408,960✔
1022
                format!("PoxInv({},{:?})", &m.bitlen, &m.pox_bitvec)
408,960✔
1023
            }
1024
            StacksMessageType::GetBlocksInv(ref m) => {
682,830✔
1025
                format!("GetBlocksInv({},{})", &m.consensus_hash, m.num_blocks)
682,830✔
1026
            }
1027
            StacksMessageType::BlocksInv(ref m) => format!(
1,344,015✔
1028
                "BlocksInv({},{:?},{:?})",
1029
                m.bitlen, &m.block_bitvec, &m.microblocks_bitvec
1,344,015✔
1030
            ),
1031
            StacksMessageType::BlocksAvailable(ref m) => {
21,060✔
1032
                format!("BlocksAvailable({:?})", &m.available)
21,060✔
1033
            }
1034
            StacksMessageType::MicroblocksAvailable(ref m) => {
×
1035
                format!("MicroblocksAvailable({:?})", &m.available)
×
1036
            }
1037
            StacksMessageType::Blocks(ref m) => format!(
36,414✔
1038
                "Blocks({:?})",
1039
                m.blocks
36,414✔
1040
                    .iter()
36,414✔
1041
                    .map(|BlocksDatum(ch, blk)| (ch.clone(), blk.block_hash()))
36,576✔
1042
                    .collect::<Vec<(ConsensusHash, BlockHeaderHash)>>()
36,414✔
1043
            ),
1044
            StacksMessageType::Microblocks(ref m) => format!(
9✔
1045
                "Microblocks({},{:?})",
1046
                &m.index_anchor_block,
9✔
1047
                m.microblocks
9✔
1048
                    .iter()
9✔
1049
                    .map(|mblk| mblk.block_hash())
9✔
1050
                    .collect::<Vec<BlockHeaderHash>>()
9✔
1051
            ),
1052
            StacksMessageType::Transaction(ref m) => format!("Transaction({})", m.txid()),
42,588✔
1053
            StacksMessageType::Nack(ref m) => format!("Nack({})", m.error_code),
897,633✔
UNCOV
1054
            StacksMessageType::Ping(ref m) => format!("Ping({})", m.nonce),
×
UNCOV
1055
            StacksMessageType::Pong(ref m) => format!("Pong({})", m.nonce),
×
1056
            StacksMessageType::NatPunchRequest(ref m) => format!("NatPunchRequest({})", m),
618✔
1057
            StacksMessageType::NatPunchReply(ref m) => {
1,236✔
1058
                format!("NatPunchReply({},{}:{})", m.nonce, &m.addrbytes, m.port)
1,236✔
1059
            }
1060
            StacksMessageType::StackerDBHandshakeAccept(ref h, ref m) => {
786,230✔
1061
                format!(
786,230✔
1062
                    "StackerDBHandshakeAccept({},{},{:?})",
1063
                    &to_hex(&h.handshake.node_public_key.to_bytes()),
786,230✔
1064
                    &m.rc_consensus_hash,
786,230✔
1065
                    &m.smart_contracts
786,230✔
1066
                )
1067
            }
1068
            StacksMessageType::StackerDBGetChunkInv(ref m) => {
4,005,936✔
1069
                format!(
4,005,936✔
1070
                    "StackerDBGetChunkInv({}.{})",
1071
                    &m.contract_id, &m.rc_consensus_hash
4,005,936✔
1072
                )
1073
            }
1074
            StacksMessageType::StackerDBChunkInv(ref m) => {
7,609,878✔
1075
                format!("StackerDBChunkInv({:?})", &m.slot_versions)
7,609,878✔
1076
            }
1077
            StacksMessageType::StackerDBGetChunk(ref m) => {
86,958✔
1078
                format!(
86,958✔
1079
                    "StackerDBGetChunk({},{},{},{})",
1080
                    &m.contract_id, &m.rc_consensus_hash, m.slot_id, m.slot_version
86,958✔
1081
                )
1082
            }
1083
            StacksMessageType::StackerDBChunk(ref m) => {
172,125✔
1084
                format!(
172,125✔
1085
                    "StackerDBChunk({},{},{},sz={})",
1086
                    m.slot_id,
1087
                    m.slot_version,
1088
                    &m.sig,
172,125✔
1089
                    m.data.len()
172,125✔
1090
                )
1091
            }
1092
            StacksMessageType::StackerDBPushChunk(ref m) => {
1,433,961✔
1093
                format!(
1,433,961✔
1094
                    "StackerDBPushChunk({},{},{},{},{},sz={})",
1095
                    &m.contract_id,
1,433,961✔
1096
                    &m.rc_consensus_hash,
1,433,961✔
1097
                    m.chunk_data.slot_id,
1098
                    m.chunk_data.slot_version,
1099
                    &m.chunk_data.sig,
1,433,961✔
1100
                    m.chunk_data.data.len()
1,433,961✔
1101
                )
1102
            }
1103
            StacksMessageType::GetNakamotoInv(ref m) => {
232,632✔
1104
                format!("GetNakamotoInv({})", &m.consensus_hash,)
232,632✔
1105
            }
1106
            StacksMessageType::NakamotoInv(ref m) => {
460,962✔
1107
                format!("NakamotoInv({:?})", &m.tenures)
460,962✔
1108
            }
1109
            StacksMessageType::NakamotoBlocks(ref m) => {
102,645✔
1110
                format!(
102,645✔
1111
                    "NakamotoBlocks({:?})",
1112
                    m.blocks
102,645✔
1113
                        .iter()
102,645✔
1114
                        .map(|block| block.block_id())
102,771✔
1115
                        .collect::<Vec<_>>()
102,645✔
1116
                )
1117
            }
1118
        }
1119
    }
19,992,840✔
1120
}
1121

1122
impl StacksMessageCodec for StacksMessageID {
1123
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
×
1124
        write_next(fd, &(*self as u8))
×
1125
    }
×
1126

1127
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<StacksMessageID, codec_error> {
12,930,048✔
1128
        let as_u8: u8 = read_next(fd)?;
12,930,048✔
1129
        let id = match as_u8 {
12,930,048✔
1130
            x if x == StacksMessageID::Handshake as u8 => StacksMessageID::Handshake,
12,930,048✔
1131
            x if x == StacksMessageID::HandshakeAccept as u8 => StacksMessageID::HandshakeAccept,
12,522,663✔
1132
            x if x == StacksMessageID::HandshakeReject as u8 => StacksMessageID::HandshakeReject,
12,508,704✔
1133
            x if x == StacksMessageID::GetNeighbors as u8 => StacksMessageID::GetNeighbors,
12,508,704✔
1134
            x if x == StacksMessageID::Neighbors as u8 => StacksMessageID::Neighbors,
12,166,596✔
1135
            x if x == StacksMessageID::GetPoxInv as u8 => StacksMessageID::GetPoxInv,
11,824,591✔
1136
            x if x == StacksMessageID::PoxInv as u8 => StacksMessageID::PoxInv,
11,620,093✔
1137
            x if x == StacksMessageID::GetBlocksInv as u8 => StacksMessageID::GetBlocksInv,
11,415,631✔
1138
            x if x == StacksMessageID::BlocksInv as u8 => StacksMessageID::BlocksInv,
10,732,801✔
1139
            x if x == StacksMessageID::BlocksAvailable as u8 => StacksMessageID::BlocksAvailable,
10,060,825✔
1140
            x if x == StacksMessageID::MicroblocksAvailable as u8 => {
10,050,295✔
UNCOV
1141
                StacksMessageID::MicroblocksAvailable
×
1142
            }
1143
            x if x == StacksMessageID::Blocks as u8 => StacksMessageID::Blocks,
10,050,295✔
1144
            x if x == StacksMessageID::Microblocks as u8 => StacksMessageID::Microblocks,
10,032,088✔
1145
            x if x == StacksMessageID::Transaction as u8 => StacksMessageID::Transaction,
10,032,088✔
1146
            x if x == StacksMessageID::Nack as u8 => StacksMessageID::Nack,
10,027,102✔
1147
            x if x == StacksMessageID::Ping as u8 => StacksMessageID::Ping,
9,578,407✔
1148
            x if x == StacksMessageID::Pong as u8 => StacksMessageID::Pong,
9,578,407✔
1149
            x if x == StacksMessageID::NatPunchRequest as u8 => StacksMessageID::NatPunchRequest,
9,578,407✔
1150
            x if x == StacksMessageID::NatPunchReply as u8 => StacksMessageID::NatPunchReply,
9,577,789✔
1151
            x if x == StacksMessageID::StackerDBHandshakeAccept as u8 => {
9,577,171✔
1152
                StacksMessageID::StackerDBHandshakeAccept
392,932✔
1153
            }
1154
            x if x == StacksMessageID::StackerDBGetChunkInv as u8 => {
9,184,239✔
1155
                StacksMessageID::StackerDBGetChunkInv
4,005,936✔
1156
            }
1157
            x if x == StacksMessageID::StackerDBChunkInv as u8 => {
5,178,303✔
1158
                StacksMessageID::StackerDBChunkInv
4,039,371✔
1159
            }
1160
            x if x == StacksMessageID::StackerDBGetChunk as u8 => {
1,138,932✔
1161
                StacksMessageID::StackerDBGetChunk
86,958✔
1162
            }
1163
            x if x == StacksMessageID::StackerDBChunk as u8 => StacksMessageID::StackerDBChunk,
1,051,974✔
1164
            x if x == StacksMessageID::StackerDBPushChunk as u8 => {
965,934✔
1165
                StacksMessageID::StackerDBPushChunk
494,631✔
1166
            }
1167
            x if x == StacksMessageID::GetNakamotoInv as u8 => StacksMessageID::GetNakamotoInv,
471,303✔
1168
            x if x == StacksMessageID::NakamotoInv as u8 => StacksMessageID::NakamotoInv,
238,671✔
1169
            x if x == StacksMessageID::NakamotoBlocks as u8 => StacksMessageID::NakamotoBlocks,
8,496✔
1170
            _ => {
1171
                return Err(codec_error::DeserializeError(
×
1172
                    "Unknown message ID".to_string(),
×
1173
                ));
×
1174
            }
1175
        };
1176
        Ok(id)
12,930,048✔
1177
    }
12,930,048✔
1178
}
1179

1180
impl StacksMessageCodec for StacksMessageType {
1181
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
25,908,829✔
1182
        write_next(fd, &(self.get_message_id() as u8))?;
25,908,829✔
1183
        match *self {
25,908,829✔
1184
            StacksMessageType::Handshake(ref m) => write_next(fd, m)?,
827,219✔
1185
            StacksMessageType::HandshakeAccept(ref m) => write_next(fd, m)?,
28,174✔
UNCOV
1186
            StacksMessageType::HandshakeReject => {}
×
1187
            StacksMessageType::GetNeighbors => {}
684,296✔
1188
            StacksMessageType::Neighbors(ref m) => write_next(fd, m)?,
684,216✔
1189
            StacksMessageType::GetPoxInv(ref m) => write_next(fd, m)?,
408,996✔
1190
            StacksMessageType::PoxInv(ref m) => write_next(fd, m)?,
408,996✔
1191
            StacksMessageType::GetBlocksInv(ref m) => write_next(fd, m)?,
1,365,660✔
1192
            StacksMessageType::BlocksInv(ref m) => write_next(fd, m)?,
1,344,078✔
1193
            StacksMessageType::BlocksAvailable(ref m) => write_next(fd, m)?,
21,060✔
UNCOV
1194
            StacksMessageType::MicroblocksAvailable(ref m) => write_next(fd, m)?,
×
1195
            StacksMessageType::Blocks(ref m) => write_next(fd, m)?,
36,414✔
1196
            StacksMessageType::Microblocks(ref m) => write_next(fd, m)?,
×
1197
            StacksMessageType::Transaction(ref m) => write_next(fd, m)?,
9,972✔
1198
            StacksMessageType::Nack(ref m) => write_next(fd, m)?,
897,876✔
UNCOV
1199
            StacksMessageType::Ping(ref m) => write_next(fd, m)?,
×
UNCOV
1200
            StacksMessageType::Pong(ref m) => write_next(fd, m)?,
×
1201
            StacksMessageType::NatPunchRequest(ref nonce) => write_next(fd, nonce)?,
1,236✔
1202
            StacksMessageType::NatPunchReply(ref m) => write_next(fd, m)?,
1,236✔
1203
            StacksMessageType::StackerDBHandshakeAccept(ref h, ref m) => {
786,596✔
1204
                write_next(fd, h)?;
786,596✔
1205
                write_next(fd, m)?
786,596✔
1206
            }
1207
            StacksMessageType::StackerDBGetChunkInv(ref m) => write_next(fd, m)?,
8,029,350✔
1208
            StacksMessageType::StackerDBChunkInv(ref m) => write_next(fd, m)?,
8,092,746✔
1209
            StacksMessageType::StackerDBGetChunk(ref m) => write_next(fd, m)?,
173,934✔
1210
            StacksMessageType::StackerDBChunk(ref m) => write_next(fd, m)?,
172,170✔
1211
            StacksMessageType::StackerDBPushChunk(ref m) => write_next(fd, m)?,
989,946✔
1212
            StacksMessageType::GetNakamotoInv(ref m) => write_next(fd, m)?,
465,984✔
1213
            StacksMessageType::NakamotoInv(ref m) => write_next(fd, m)?,
461,574✔
1214
            StacksMessageType::NakamotoBlocks(ref m) => write_next(fd, m)?,
17,100✔
1215
        }
1216
        Ok(())
25,908,829✔
1217
    }
25,908,829✔
1218

1219
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<StacksMessageType, codec_error> {
12,930,048✔
1220
        let message_id: StacksMessageID = read_next(fd)?;
12,930,048✔
1221
        let message = match message_id {
12,930,048✔
1222
            StacksMessageID::Handshake => {
1223
                let m: HandshakeData = read_next(fd)?;
407,385✔
1224
                StacksMessageType::Handshake(m)
407,385✔
1225
            }
1226
            StacksMessageID::HandshakeAccept => {
1227
                let m: HandshakeAcceptData = read_next(fd)?;
13,959✔
1228
                StacksMessageType::HandshakeAccept(m)
13,959✔
1229
            }
UNCOV
1230
            StacksMessageID::HandshakeReject => StacksMessageType::HandshakeReject,
×
1231
            StacksMessageID::GetNeighbors => StacksMessageType::GetNeighbors,
342,108✔
1232
            StacksMessageID::Neighbors => {
1233
                let m: NeighborsData = read_next(fd)?;
342,005✔
1234
                StacksMessageType::Neighbors(m)
342,005✔
1235
            }
1236
            StacksMessageID::GetPoxInv => {
1237
                let m: GetPoxInv = read_next(fd)?;
204,498✔
1238
                StacksMessageType::GetPoxInv(m)
204,498✔
1239
            }
1240
            StacksMessageID::PoxInv => {
1241
                let m: PoxInvData = read_next(fd)?;
204,462✔
1242
                StacksMessageType::PoxInv(m)
204,462✔
1243
            }
1244
            StacksMessageID::GetBlocksInv => {
1245
                let m: GetBlocksInv = read_next(fd)?;
682,830✔
1246
                StacksMessageType::GetBlocksInv(m)
682,830✔
1247
            }
1248
            StacksMessageID::BlocksInv => {
1249
                let m: BlocksInvData = read_next(fd)?;
671,976✔
1250
                StacksMessageType::BlocksInv(m)
671,976✔
1251
            }
1252
            StacksMessageID::BlocksAvailable => {
1253
                let m: BlocksAvailableData = read_next(fd)?;
10,530✔
1254
                StacksMessageType::BlocksAvailable(m)
10,530✔
1255
            }
1256
            StacksMessageID::MicroblocksAvailable => {
UNCOV
1257
                let m: BlocksAvailableData = read_next(fd)?;
×
UNCOV
1258
                StacksMessageType::MicroblocksAvailable(m)
×
1259
            }
1260
            StacksMessageID::Blocks => {
1261
                let m: BlocksData = read_next(fd)?;
18,207✔
1262
                StacksMessageType::Blocks(m)
18,207✔
1263
            }
1264
            StacksMessageID::Microblocks => {
1265
                let m: MicroblocksData = read_next(fd)?;
×
1266
                StacksMessageType::Microblocks(m)
×
1267
            }
1268
            StacksMessageID::Transaction => {
1269
                let m: StacksTransaction = read_next(fd)?;
4,986✔
1270
                StacksMessageType::Transaction(m)
4,986✔
1271
            }
1272
            StacksMessageID::Nack => {
1273
                let m: NackData = read_next(fd)?;
448,695✔
1274
                StacksMessageType::Nack(m)
448,695✔
1275
            }
1276
            StacksMessageID::Ping => {
UNCOV
1277
                let m: PingData = read_next(fd)?;
×
UNCOV
1278
                StacksMessageType::Ping(m)
×
1279
            }
1280
            StacksMessageID::Pong => {
UNCOV
1281
                let m: PongData = read_next(fd)?;
×
UNCOV
1282
                StacksMessageType::Pong(m)
×
1283
            }
1284
            StacksMessageID::NatPunchRequest => {
1285
                let nonce: u32 = read_next(fd)?;
618✔
1286
                StacksMessageType::NatPunchRequest(nonce)
618✔
1287
            }
1288
            StacksMessageID::NatPunchReply => {
1289
                let m: NatPunchData = read_next(fd)?;
618✔
1290
                StacksMessageType::NatPunchReply(m)
618✔
1291
            }
1292
            StacksMessageID::StackerDBHandshakeAccept => {
1293
                let h: HandshakeAcceptData = read_next(fd)?;
392,932✔
1294
                let m: StackerDBHandshakeData = read_next(fd)?;
392,932✔
1295
                StacksMessageType::StackerDBHandshakeAccept(h, m)
392,932✔
1296
            }
1297
            StacksMessageID::StackerDBGetChunkInv => {
1298
                let m: StackerDBGetChunkInvData = read_next(fd)?;
4,005,936✔
1299
                StacksMessageType::StackerDBGetChunkInv(m)
4,005,936✔
1300
            }
1301
            StacksMessageID::StackerDBChunkInv => {
1302
                let m: StackerDBChunkInvData = read_next(fd)?;
4,039,371✔
1303
                StacksMessageType::StackerDBChunkInv(m)
4,039,371✔
1304
            }
1305
            StacksMessageID::StackerDBGetChunk => {
1306
                let m: StackerDBGetChunkData = read_next(fd)?;
86,958✔
1307
                StacksMessageType::StackerDBGetChunk(m)
86,958✔
1308
            }
1309
            StacksMessageID::StackerDBChunk => {
1310
                let m: StackerDBChunkData = read_next(fd)?;
86,040✔
1311
                StacksMessageType::StackerDBChunk(m)
86,040✔
1312
            }
1313
            StacksMessageID::StackerDBPushChunk => {
1314
                let m: StackerDBPushChunkData = read_next(fd)?;
494,631✔
1315
                StacksMessageType::StackerDBPushChunk(m)
494,631✔
1316
            }
1317
            StacksMessageID::GetNakamotoInv => {
1318
                let m: GetNakamotoInvData = read_next(fd)?;
232,632✔
1319
                StacksMessageType::GetNakamotoInv(m)
232,632✔
1320
            }
1321
            StacksMessageID::NakamotoInv => {
1322
                let m: NakamotoInvData = read_next(fd)?;
230,175✔
1323
                StacksMessageType::NakamotoInv(m)
230,175✔
1324
            }
1325
            StacksMessageID::NakamotoBlocks => {
1326
                let m: NakamotoBlocksData = read_next(fd)?;
8,496✔
1327
                StacksMessageType::NakamotoBlocks(m)
8,496✔
1328
            }
1329
            StacksMessageID::Reserved => {
1330
                return Err(codec_error::DeserializeError(
×
1331
                    "Unsupported message ID 'reserved'".to_string(),
×
1332
                ));
×
1333
            }
1334
        };
1335
        Ok(message)
12,930,048✔
1336
    }
12,930,048✔
1337
}
1338

1339
impl StacksMessageCodec for StacksMessage {
1340
    fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
12,948,274✔
1341
        write_next(fd, &self.preamble)?;
12,948,274✔
1342
        write_next(fd, &self.relayers)?;
12,948,274✔
1343
        write_next(fd, &self.payload)?;
12,948,274✔
1344
        Ok(())
12,948,274✔
1345
    }
12,948,274✔
1346

UNCOV
1347
    fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<StacksMessage, codec_error> {
×
UNCOV
1348
        let preamble: Preamble = read_next(fd)?;
×
UNCOV
1349
        if preamble.payload_len > MAX_MESSAGE_LEN - PREAMBLE_ENCODED_SIZE {
×
1350
            return Err(codec_error::DeserializeError(
×
1351
                "Message would be too big".to_string(),
×
1352
            ));
×
UNCOV
1353
        }
×
1354

UNCOV
1355
        let relayers: Vec<RelayData> = read_next_at_most::<_, RelayData>(fd, MAX_RELAYERS_LEN)?;
×
UNCOV
1356
        let payload: StacksMessageType = read_next(fd)?;
×
1357

UNCOV
1358
        let message = StacksMessage {
×
UNCOV
1359
            preamble,
×
UNCOV
1360
            relayers,
×
UNCOV
1361
            payload,
×
UNCOV
1362
        };
×
UNCOV
1363
        Ok(message)
×
UNCOV
1364
    }
×
1365
}
1366

1367
impl StacksMessage {
1368
    /// Create an unsigned Stacks p2p message
1369
    pub fn new(
12,948,274✔
1370
        peer_version: u32,
12,948,274✔
1371
        network_id: u32,
12,948,274✔
1372
        block_height: u64,
12,948,274✔
1373
        burn_header_hash: &BurnchainHeaderHash,
12,948,274✔
1374
        stable_block_height: u64,
12,948,274✔
1375
        stable_burn_header_hash: &BurnchainHeaderHash,
12,948,274✔
1376
        message: StacksMessageType,
12,948,274✔
1377
    ) -> StacksMessage {
12,948,274✔
1378
        let preamble = Preamble::new(
12,948,274✔
1379
            peer_version,
12,948,274✔
1380
            network_id,
12,948,274✔
1381
            block_height,
12,948,274✔
1382
            burn_header_hash,
12,948,274✔
1383
            stable_block_height,
12,948,274✔
1384
            stable_burn_header_hash,
12,948,274✔
1385
            0,
1386
        );
1387
        StacksMessage {
12,948,274✔
1388
            preamble,
12,948,274✔
1389
            relayers: vec![],
12,948,274✔
1390
            payload: message,
12,948,274✔
1391
        }
12,948,274✔
1392
    }
12,948,274✔
1393

1394
    /// Create an unsigned Stacks message
1395
    pub fn from_chain_view(
12,948,274✔
1396
        peer_version: u32,
12,948,274✔
1397
        network_id: u32,
12,948,274✔
1398
        chain_view: &BurnchainView,
12,948,274✔
1399
        message: StacksMessageType,
12,948,274✔
1400
    ) -> StacksMessage {
12,948,274✔
1401
        StacksMessage::new(
12,948,274✔
1402
            peer_version,
12,948,274✔
1403
            network_id,
12,948,274✔
1404
            chain_view.burn_block_height,
12,948,274✔
1405
            &chain_view.burn_block_hash,
12,948,274✔
1406
            chain_view.burn_stable_block_height,
12,948,274✔
1407
            &chain_view.burn_stable_block_hash,
12,948,274✔
1408
            message,
12,948,274✔
1409
        )
1410
    }
12,948,274✔
1411

1412
    /// represent as neighbor key
1413
    pub fn to_neighbor_key(&self, addrbytes: &PeerAddress, port: u16) -> NeighborKey {
4,091✔
1414
        NeighborKey {
4,091✔
1415
            peer_version: self.preamble.peer_version,
4,091✔
1416
            network_id: self.preamble.network_id,
4,091✔
1417
            addrbytes: addrbytes.clone(),
4,091✔
1418
            port,
4,091✔
1419
        }
4,091✔
1420
    }
4,091✔
1421

1422
    /// Sign the stacks message
1423
    fn do_sign(&mut self, private_key: &Secp256k1PrivateKey) -> Result<(), net_error> {
12,948,274✔
1424
        let mut message_bits = vec![];
12,948,274✔
1425
        self.relayers.consensus_serialize(&mut message_bits)?;
12,948,274✔
1426
        self.payload.consensus_serialize(&mut message_bits)?;
12,948,274✔
1427

1428
        self.preamble.payload_len = message_bits.len() as u32;
12,948,274✔
1429
        self.preamble.sign(&message_bits[..], private_key)
12,948,274✔
1430
    }
12,948,274✔
1431

1432
    /// Sign the StacksMessage.  The StacksMessage must _not_ have any relayers (i.e. we're
1433
    /// originating this messsage).
1434
    pub fn sign(&mut self, seq: u32, private_key: &Secp256k1PrivateKey) -> Result<(), net_error> {
12,541,105✔
1435
        if !self.relayers.is_empty() {
12,541,105✔
1436
            return Err(net_error::InvalidMessage);
×
1437
        }
12,541,105✔
1438
        self.preamble.seq = seq;
12,541,105✔
1439
        self.do_sign(private_key)
12,541,105✔
1440
    }
12,541,105✔
1441

1442
    /// Sign the StacksMessage and add ourselves as a relayer.
1443
    pub fn sign_relay(
407,169✔
1444
        &mut self,
407,169✔
1445
        private_key: &Secp256k1PrivateKey,
407,169✔
1446
        our_seq: u32,
407,169✔
1447
        our_addr: &NeighborAddress,
407,169✔
1448
    ) -> Result<(), net_error> {
407,169✔
1449
        if self.relayers.len() >= MAX_RELAYERS_LEN as usize {
407,169✔
1450
            warn!(
×
1451
                "Message {:?} has too many relayers; will not sign",
1452
                self.payload.get_message_description()
×
1453
            );
1454
            return Err(net_error::InvalidMessage);
×
1455
        }
407,169✔
1456

1457
        // don't sign if signed more than once
1458
        for relayer in &self.relayers {
407,169✔
UNCOV
1459
            if relayer.peer.public_key_hash == our_addr.public_key_hash {
×
UNCOV
1460
                warn!(
×
1461
                    "Message {:?} already signed by {}",
UNCOV
1462
                    self.payload.get_message_description(),
×
UNCOV
1463
                    &our_addr.public_key_hash
×
1464
                );
UNCOV
1465
                return Err(net_error::InvalidMessage);
×
UNCOV
1466
            }
×
1467
        }
1468

1469
        // save relayer state
1470
        let our_relay = RelayData {
407,169✔
1471
            peer: our_addr.clone(),
407,169✔
1472
            seq: self.preamble.seq,
407,169✔
1473
        };
407,169✔
1474

1475
        self.relayers.push(our_relay);
407,169✔
1476
        self.preamble.seq = our_seq;
407,169✔
1477
        self.do_sign(private_key)
407,169✔
1478
    }
407,169✔
1479

1480
    pub fn deserialize_body<R: Read>(
12,930,048✔
1481
        fd: &mut R,
12,930,048✔
1482
    ) -> Result<(Vec<RelayData>, StacksMessageType), net_error> {
12,930,048✔
1483
        let relayers: Vec<RelayData> = read_next_at_most::<_, RelayData>(fd, MAX_RELAYERS_LEN)?;
12,930,048✔
1484
        let payload: StacksMessageType = read_next(fd)?;
12,930,048✔
1485
        Ok((relayers, payload))
12,930,048✔
1486
    }
12,930,048✔
1487

1488
    /// Verify this message by treating the public key buffer as a secp256k1 public key.
1489
    /// Fails if:
1490
    /// * the signature doesn't match
1491
    /// * the buffer doesn't encode a secp256k1 public key
1492
    pub fn verify_secp256k1(&self, public_key: &StacksPublicKeyBuffer) -> Result<(), net_error> {
12,281✔
1493
        let secp256k1_pubkey = public_key
12,281✔
1494
            .to_public_key()
12,281✔
1495
            .map_err(|e| net_error::DeserializeError(e.into()))?;
12,281✔
1496

1497
        let mut message_bits = vec![];
12,281✔
1498
        self.relayers.consensus_serialize(&mut message_bits)?;
12,281✔
1499
        self.payload.consensus_serialize(&mut message_bits)?;
12,281✔
1500

1501
        let mut p = self.preamble.clone();
12,281✔
1502
        p.verify(&message_bits, &secp256k1_pubkey).map(|_m| ())
12,281✔
1503
    }
12,281✔
1504
}
1505

1506
impl MessageSequence for StacksMessage {
1507
    fn request_id(&self) -> u32 {
559,223,485✔
1508
        self.preamble.seq
559,223,485✔
1509
    }
559,223,485✔
1510

1511
    fn get_message_name(&self) -> &'static str {
12,644,413✔
1512
        self.payload.get_message_name()
12,644,413✔
1513
    }
12,644,413✔
1514
}
1515

1516
impl StacksP2P {
1517
    pub fn new() -> StacksP2P {
24,835✔
1518
        StacksP2P {}
24,835✔
1519
    }
24,835✔
1520
}
1521

1522
impl ProtocolFamily for StacksP2P {
1523
    type Preamble = Preamble;
1524
    type Message = StacksMessage;
1525

1526
    /// How big can a P2P preamble get?
1527
    fn preamble_size_hint(&mut self) -> usize {
12,930,156✔
1528
        PREAMBLE_ENCODED_SIZE as usize
12,930,156✔
1529
    }
12,930,156✔
1530

1531
    /// How long is an encoded message payload going to be, if we can tell at all?
1532
    fn payload_len(&mut self, preamble: &Preamble) -> Option<usize> {
38,807,532✔
1533
        Some(preamble.payload_len as usize)
38,807,532✔
1534
    }
38,807,532✔
1535

1536
    /// StacksP2P deals with Preambles
1537
    fn read_preamble(&mut self, buf: &[u8]) -> Result<(Preamble, usize), net_error> {
12,930,156✔
1538
        let mut preamble_bytes = buf.get(..PREAMBLE_ENCODED_SIZE as usize).ok_or_else(|| {
12,930,156✔
1539
            Error::UnderflowError("Not enough bytes to form a P2P preamble".to_string())
108✔
1540
        })?;
108✔
1541

1542
        let preamble: Preamble = read_next(&mut preamble_bytes)?;
12,930,048✔
1543
        Ok((preamble, PREAMBLE_ENCODED_SIZE as usize))
12,930,048✔
1544
    }
12,930,156✔
1545

1546
    /// StacksP2P messages are never streamed, since we always know how long they are.
1547
    /// This should be unreachable, since payload_len() always returns Some(...)
1548
    fn stream_payload<R: Read>(
×
1549
        &mut self,
×
1550
        _preamble: &Preamble,
×
1551
        _fd: &mut R,
×
1552
    ) -> Result<(Option<(StacksMessage, usize)>, usize), net_error> {
×
1553
        panic!(
×
1554
            "BUG: tried to stream a StacksP2P message, even though their lengths are always known"
1555
        )
1556
    }
1557

1558
    /// StacksP2P deals with StacksMessages
1559
    fn read_payload(
12,930,048✔
1560
        &mut self,
12,930,048✔
1561
        preamble: &Preamble,
12,930,048✔
1562
        bytes: &[u8],
12,930,048✔
1563
    ) -> Result<(StacksMessage, usize), net_error> {
12,930,048✔
1564
        let preamble_bytes = bytes.get(..preamble.payload_len as usize).ok_or_else(|| {
12,930,048✔
1565
            Error::UnderflowError("Not enough bytes to form a StacksMessage".to_string())
×
1566
        })?;
×
1567

1568
        let mut cursor = io::Cursor::new(preamble_bytes);
12,930,048✔
1569
        let (relayers, payload) = StacksMessage::deserialize_body(&mut cursor)?;
12,930,048✔
1570
        let message = StacksMessage {
12,930,048✔
1571
            preamble: preamble.clone(),
12,930,048✔
1572
            relayers,
12,930,048✔
1573
            payload,
12,930,048✔
1574
        };
12,930,048✔
1575
        Ok((message, cursor.position() as usize))
12,930,048✔
1576
    }
12,930,048✔
1577

1578
    fn verify_payload_bytes(
12,886,720✔
1579
        &mut self,
12,886,720✔
1580
        key: &StacksPublicKey,
12,886,720✔
1581
        preamble: &Preamble,
12,886,720✔
1582
        bytes: &[u8],
12,886,720✔
1583
    ) -> Result<(), Error> {
12,886,720✔
1584
        let preamble_bytes = bytes.get(..preamble.payload_len as usize).ok_or_else(|| {
12,886,720✔
1585
            Error::UnderflowError("Not enough bytes to form a StacksMessage".to_string())
×
1586
        })?;
×
1587
        preamble.clone().verify(preamble_bytes, key).map(|_m| ())
12,886,720✔
1588
    }
12,886,720✔
1589

UNCOV
1590
    fn write_message<W: Write>(
×
UNCOV
1591
        &mut self,
×
UNCOV
1592
        fd: &mut W,
×
UNCOV
1593
        message: &StacksMessage,
×
UNCOV
1594
    ) -> Result<(), net_error> {
×
UNCOV
1595
        message.consensus_serialize(fd).map_err(|e| e.into())
×
UNCOV
1596
    }
×
1597
}
1598

1599
#[cfg(test)]
1600
pub mod test {
1601
    use clarity::consts::PEER_VERSION_TESTNET;
1602
    use stacks_common::bitvec::BitVec;
1603
    use stacks_common::codec::NEIGHBOR_ADDRESS_ENCODED_SIZE;
1604
    use stacks_common::util::hash::hex_bytes;
1605
    use stacks_common::util::secp256k1::*;
1606

1607
    use super::*;
1608
    use crate::net::{GetNakamotoInvData, NakamotoInvData};
1609

1610
    fn check_overflow<T>(r: Result<T, net_error>) -> bool {
×
1611
        match r {
×
1612
            Ok(_) => {
1613
                test_debug!("did not get an overflow error, or any error");
×
1614
                false
×
1615
            }
1616
            Err(e) => match e {
×
1617
                net_error::OverflowError(_) => true,
×
1618
                _ => {
1619
                    test_debug!("did not get an overflow error, but got {:?}", &e);
×
1620
                    false
×
1621
                }
1622
            },
1623
        }
1624
    }
×
1625

1626
    fn check_underflow<T>(r: Result<T, net_error>) -> bool {
×
1627
        match r {
×
1628
            Ok(_) => {
1629
                test_debug!("did not get an underflow error, or any error");
×
1630
                false
×
1631
            }
1632
            Err(e) => match e {
×
1633
                net_error::UnderflowError(_) => true,
×
1634
                _ => {
1635
                    test_debug!("did not get an underflow error, but got {:?}", &e);
×
1636
                    false
×
1637
                }
1638
            },
1639
        }
1640
    }
×
1641

UNCOV
1642
    fn check_deserialize<T: std::fmt::Debug>(r: Result<T, codec_error>) -> bool {
×
UNCOV
1643
        match r {
×
1644
            Ok(m) => {
×
1645
                test_debug!("deserialized {m:?}");
×
1646
                false
×
1647
            }
UNCOV
1648
            Err(e) => matches!(e, codec_error::DeserializeError(_)),
×
1649
        }
UNCOV
1650
    }
×
1651

UNCOV
1652
    fn check_deserialize_failure<T: StacksMessageCodec + fmt::Debug + Clone + PartialEq>(
×
UNCOV
1653
        obj: &T,
×
UNCOV
1654
    ) -> bool {
×
UNCOV
1655
        let mut bytes: Vec<u8> = vec![];
×
UNCOV
1656
        obj.consensus_serialize(&mut bytes).unwrap();
×
UNCOV
1657
        check_deserialize(T::consensus_deserialize(&mut &bytes[..]))
×
UNCOV
1658
    }
×
1659

UNCOV
1660
    pub fn check_codec_and_corruption<T: StacksMessageCodec + fmt::Debug + Clone + PartialEq>(
×
UNCOV
1661
        obj: &T,
×
UNCOV
1662
        bytes: &[u8],
×
UNCOV
1663
    ) {
×
1664
        // obj should serialize to bytes
UNCOV
1665
        let mut write_buf: Vec<u8> = Vec::with_capacity(bytes.len());
×
UNCOV
1666
        obj.consensus_serialize(&mut write_buf).unwrap();
×
UNCOV
1667
        assert_eq!(write_buf, *bytes);
×
1668

1669
        // bytes should deserialize to obj
UNCOV
1670
        let read_buf: Vec<u8> = write_buf.clone();
×
UNCOV
1671
        let res = T::consensus_deserialize(&mut &read_buf[..]);
×
UNCOV
1672
        match res {
×
UNCOV
1673
            Ok(out) => {
×
UNCOV
1674
                assert_eq!(out, *obj);
×
1675
            }
1676
            Err(e) => {
×
1677
                panic!("Failed to parse to {obj:?}: {bytes:?}\nerror: {e:?}");
×
1678
            }
1679
        }
1680

1681
        // short message shouldn't parse, but should EOF
UNCOV
1682
        if !write_buf.is_empty() {
×
UNCOV
1683
            let mut short_buf = write_buf.clone();
×
UNCOV
1684
            let short_len = short_buf.len() - 1;
×
UNCOV
1685
            short_buf.truncate(short_len);
×
1686

UNCOV
1687
            let underflow_res = T::consensus_deserialize(&mut &short_buf[..]);
×
UNCOV
1688
            match underflow_res {
×
1689
                Ok(oops) => {
×
1690
                    test_debug!(
×
1691
                        "\nMissing Underflow: Parsed {oops:?}\nFrom {:?}\n",
1692
                        &write_buf[0..short_len].to_vec()
×
1693
                    );
1694
                }
UNCOV
1695
                Err(codec_error::ReadError(io_error)) => match io_error.kind() {
×
UNCOV
1696
                    io::ErrorKind::UnexpectedEof => {}
×
1697
                    _ => {
1698
                        panic!("Got unexpected I/O error: {io_error:?}");
×
1699
                    }
1700
                },
1701
                Err(e) => {
×
1702
                    panic!("Got unexpected Net error: {e:?}");
×
1703
                }
1704
            };
1705
        }
×
UNCOV
1706
    }
×
1707

1708
    #[test]
UNCOV
1709
    fn codec_primitive_types() {
×
UNCOV
1710
        check_codec_and_corruption::<u8>(&0x01, &[0x01]);
×
UNCOV
1711
        check_codec_and_corruption::<u16>(&0x0203, &[0x02, 0x03]);
×
UNCOV
1712
        check_codec_and_corruption::<u32>(&0x04050607, &[0x04, 0x05, 0x06, 0x07]);
×
UNCOV
1713
        check_codec_and_corruption::<u64>(
×
UNCOV
1714
            &0x08090a0b0c0d0e0f,
×
UNCOV
1715
            &[0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f],
×
1716
        );
UNCOV
1717
    }
×
1718

1719
    #[test]
UNCOV
1720
    fn codec_primitive_vector() {
×
UNCOV
1721
        check_codec_and_corruption::<Vec<u8>>(&vec![], &[0x00, 0x00, 0x00, 0x00]);
×
UNCOV
1722
        check_codec_and_corruption::<Vec<u8>>(
×
UNCOV
1723
            &vec![0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09],
×
UNCOV
1724
            &[
×
UNCOV
1725
                0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
×
UNCOV
1726
            ],
×
1727
        );
1728

UNCOV
1729
        check_codec_and_corruption::<Vec<u16>>(&vec![], &[0x00, 0x00, 0x00, 0x00]);
×
UNCOV
1730
        check_codec_and_corruption::<Vec<u16>>(
×
UNCOV
1731
            &vec![
×
UNCOV
1732
                0xf000, 0xf101, 0xf202, 0xf303, 0xf404, 0xf505, 0xf606, 0xf707, 0xf808, 0xf909,
×
UNCOV
1733
            ],
×
UNCOV
1734
            &[
×
UNCOV
1735
                0x00, 0x00, 0x00, 0x0a, 0xf0, 0x00, 0xf1, 0x01, 0xf2, 0x02, 0xf3, 0x03, 0xf4, 0x04,
×
UNCOV
1736
                0xf5, 0x05, 0xf6, 0x06, 0xf7, 0x07, 0xf8, 0x08, 0xf9, 0x09,
×
UNCOV
1737
            ],
×
1738
        );
1739

UNCOV
1740
        check_codec_and_corruption::<Vec<u32>>(&vec![], &[0x00, 0x00, 0x00, 0x00]);
×
UNCOV
1741
        check_codec_and_corruption::<Vec<u32>>(
×
UNCOV
1742
            &vec![
×
UNCOV
1743
                0xa0b0f000, 0xa1b1f101, 0xa2b2f202, 0xa3b3f303, 0xa4b4f404, 0xa5b5f505, 0xa6b6f606,
×
UNCOV
1744
                0xa7b7f707, 0xa8b8f808, 0xa9b9f909,
×
UNCOV
1745
            ],
×
UNCOV
1746
            &[
×
UNCOV
1747
                0x00, 0x00, 0x00, 0x0a, 0xa0, 0xb0, 0xf0, 0x00, 0xa1, 0xb1, 0xf1, 0x01, 0xa2, 0xb2,
×
UNCOV
1748
                0xf2, 0x02, 0xa3, 0xb3, 0xf3, 0x03, 0xa4, 0xb4, 0xf4, 0x04, 0xa5, 0xb5, 0xf5, 0x05,
×
UNCOV
1749
                0xa6, 0xb6, 0xf6, 0x06, 0xa7, 0xb7, 0xf7, 0x07, 0xa8, 0xb8, 0xf8, 0x08, 0xa9, 0xb9,
×
UNCOV
1750
                0xf9, 0x09,
×
UNCOV
1751
            ],
×
1752
        );
1753

UNCOV
1754
        check_codec_and_corruption::<Vec<u64>>(&vec![], &[0x00, 0x00, 0x00, 0x00]);
×
UNCOV
1755
        check_codec_and_corruption::<Vec<u64>>(
×
UNCOV
1756
            &vec![
×
UNCOV
1757
                0x1020304050607080,
×
UNCOV
1758
                0x1121314151617181,
×
UNCOV
1759
                0x1222324252627282,
×
UNCOV
1760
                0x1323334353637383,
×
UNCOV
1761
                0x1424344454647484,
×
UNCOV
1762
                0x1525354555657585,
×
UNCOV
1763
                0x1626364656667686,
×
UNCOV
1764
                0x1727374757677787,
×
UNCOV
1765
                0x1828384858687888,
×
UNCOV
1766
            ],
×
UNCOV
1767
            &[
×
UNCOV
1768
                0x00, 0x00, 0x00, 0x09, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x11, 0x21,
×
UNCOV
1769
                0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, 0x82,
×
UNCOV
1770
                0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, 0x83, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64,
×
UNCOV
1771
                0x74, 0x84, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, 0x85, 0x16, 0x26, 0x36, 0x46,
×
UNCOV
1772
                0x56, 0x66, 0x76, 0x86, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, 0x87, 0x18, 0x28,
×
UNCOV
1773
                0x38, 0x48, 0x58, 0x68, 0x78, 0x88,
×
UNCOV
1774
            ],
×
1775
        );
UNCOV
1776
    }
×
1777

1778
    #[test]
UNCOV
1779
    fn codec_Preamble() {
×
UNCOV
1780
        let preamble = Preamble {
×
UNCOV
1781
            peer_version: 0x01020304,
×
UNCOV
1782
            network_id: 0x05060708,
×
UNCOV
1783
            seq: 0x090a0b0c,
×
UNCOV
1784
            burn_block_height: 0x00001122,
×
UNCOV
1785
            burn_block_hash: BurnchainHeaderHash([0x11; 32]),
×
UNCOV
1786
            burn_stable_block_height: 0x00001111,
×
UNCOV
1787
            burn_stable_block_hash: BurnchainHeaderHash([0x22; 32]),
×
UNCOV
1788
            additional_data: 0x33333333,
×
UNCOV
1789
            signature: MessageSignature::from_raw(&[0x44; 65]),
×
UNCOV
1790
            payload_len: 0x000007ff,
×
UNCOV
1791
        };
×
UNCOV
1792
        let preamble_bytes: Vec<u8> = vec![
×
1793
            // peer_version
1794
            0x01, 0x02, 0x03, 0x04, // network_id
1795
            0x05, 0x06, 0x07, 0x08, // seq
1796
            0x09, 0x0a, 0x0b, 0x0c, // burn_block_height
1797
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x22, // burn_block_hash
1798
            0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1799
            0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1800
            0x11, 0x11, 0x11, 0x11, // stable_burn_block_height
1801
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, // stable_burn_block_hash
1802
            0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1803
            0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1804
            0x22, 0x22, 0x22, 0x22, // additional_data
1805
            0x33, 0x33, 0x33, 0x33, // signature
1806
            0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1807
            0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1808
            0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1809
            0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1810
            0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, // payload_len
1811
            0x00, 0x00, 0x07, 0xff,
1812
        ];
1813

UNCOV
1814
        assert_eq!(preamble_bytes.len() as u32, PREAMBLE_ENCODED_SIZE);
×
UNCOV
1815
        check_codec_and_corruption::<Preamble>(&preamble, &preamble_bytes);
×
UNCOV
1816
    }
×
1817

1818
    #[test]
UNCOV
1819
    fn codec_GetPoxInv() {
×
UNCOV
1820
        let getpoxinv = GetPoxInv {
×
UNCOV
1821
            consensus_hash: ConsensusHash([0x55; 20]),
×
UNCOV
1822
            num_cycles: GETPOXINV_MAX_BITLEN as u16,
×
UNCOV
1823
        };
×
1824

UNCOV
1825
        let getpoxinv_bytes: Vec<u8> = vec![
×
1826
            // consensus hash
1827
            0x55,
1828
            0x55,
1829
            0x55,
1830
            0x55,
1831
            0x55,
1832
            0x55,
1833
            0x55,
1834
            0x55,
1835
            0x55,
1836
            0x55,
1837
            0x55,
1838
            0x55,
1839
            0x55,
1840
            0x55,
1841
            0x55,
1842
            0x55,
1843
            0x55,
1844
            0x55,
1845
            0x55,
1846
            0x55,
1847
            // num reward cycles
1848
            0x00,
UNCOV
1849
            GETPOXINV_MAX_BITLEN as u8,
×
1850
        ];
1851

UNCOV
1852
        check_codec_and_corruption::<GetPoxInv>(&getpoxinv, &getpoxinv_bytes);
×
1853

1854
        // should fail to decode if the block range is too big
UNCOV
1855
        let getpoxinv_range_too_big = GetPoxInv {
×
UNCOV
1856
            consensus_hash: ConsensusHash([0x55; 20]),
×
UNCOV
1857
            num_cycles: (GETPOXINV_MAX_BITLEN + 1) as u16,
×
UNCOV
1858
        };
×
1859

UNCOV
1860
        assert!(check_deserialize_failure::<GetPoxInv>(
×
UNCOV
1861
            &getpoxinv_range_too_big
×
1862
        ));
UNCOV
1863
    }
×
1864

1865
    #[test]
UNCOV
1866
    fn codec_PoxInvData() {
×
1867
        // maximially big PoxInvData
UNCOV
1868
        let maximal_bitvec = vec![0xffu8; (GETPOXINV_MAX_BITLEN / 8) as usize];
×
UNCOV
1869
        let mut too_big_bitvec: Vec<u8> = vec![];
×
UNCOV
1870
        for i in 0..GETPOXINV_MAX_BITLEN + 1 {
×
UNCOV
1871
            too_big_bitvec.push(0xff);
×
UNCOV
1872
        }
×
1873

UNCOV
1874
        let maximal_poxinvdata = PoxInvData {
×
UNCOV
1875
            bitlen: GETPOXINV_MAX_BITLEN as u16,
×
UNCOV
1876
            pox_bitvec: maximal_bitvec.clone(),
×
UNCOV
1877
        };
×
1878

UNCOV
1879
        let mut maximal_poxinvdata_bytes: Vec<u8> = vec![];
×
1880
        // bitlen
UNCOV
1881
        maximal_poxinvdata_bytes.append(&mut (GETPOXINV_MAX_BITLEN as u16).to_be_bytes().to_vec());
×
1882
        // pox bitvec
UNCOV
1883
        maximal_poxinvdata_bytes
×
UNCOV
1884
            .append(&mut ((GETPOXINV_MAX_BITLEN / 8) as u32).to_be_bytes().to_vec());
×
UNCOV
1885
        maximal_poxinvdata_bytes.extend_from_slice(&maximal_bitvec);
×
1886

UNCOV
1887
        assert!((maximal_poxinvdata_bytes.len() as u32) < MAX_MESSAGE_LEN);
×
1888

UNCOV
1889
        check_codec_and_corruption::<PoxInvData>(&maximal_poxinvdata, &maximal_poxinvdata_bytes);
×
1890

1891
        // should fail to decode if the bitlen is too big
UNCOV
1892
        let too_big_poxinvdata = PoxInvData {
×
UNCOV
1893
            bitlen: (GETPOXINV_MAX_BITLEN + 1) as u16,
×
UNCOV
1894
            pox_bitvec: too_big_bitvec.clone(),
×
UNCOV
1895
        };
×
UNCOV
1896
        assert!(check_deserialize_failure::<PoxInvData>(&too_big_poxinvdata));
×
1897

1898
        // should fail to decode if the bitlen doesn't match the bitvec
UNCOV
1899
        let long_bitlen = PoxInvData {
×
UNCOV
1900
            bitlen: 1,
×
UNCOV
1901
            pox_bitvec: vec![0xff, 0x01],
×
UNCOV
1902
        };
×
UNCOV
1903
        assert!(check_deserialize_failure::<PoxInvData>(&long_bitlen));
×
1904

UNCOV
1905
        let short_bitlen = PoxInvData {
×
UNCOV
1906
            bitlen: 9,
×
UNCOV
1907
            pox_bitvec: vec![0xff],
×
UNCOV
1908
        };
×
UNCOV
1909
        assert!(check_deserialize_failure::<PoxInvData>(&short_bitlen));
×
1910

1911
        // empty
UNCOV
1912
        let empty_inv = PoxInvData {
×
UNCOV
1913
            bitlen: 0,
×
UNCOV
1914
            pox_bitvec: vec![],
×
UNCOV
1915
        };
×
UNCOV
1916
        let empty_inv_bytes = [
×
UNCOV
1917
            // bitlen
×
UNCOV
1918
            0x00, 0x00, 0x00, 0x00, // bitvec
×
UNCOV
1919
            0x00, 0x00, 0x00, 0x00,
×
UNCOV
1920
        ];
×
1921

UNCOV
1922
        check_codec_and_corruption::<PoxInvData>(&maximal_poxinvdata, &maximal_poxinvdata_bytes);
×
UNCOV
1923
    }
×
1924

1925
    #[test]
UNCOV
1926
    fn codec_GetBlocksInv() {
×
UNCOV
1927
        let getblocksdata = GetBlocksInv {
×
UNCOV
1928
            consensus_hash: ConsensusHash([0x55; 20]),
×
UNCOV
1929
            num_blocks: 32,
×
UNCOV
1930
        };
×
1931

UNCOV
1932
        let getblocksdata_bytes: Vec<u8> = vec![
×
1933
            // consensus hash
1934
            0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
1935
            0x55, 0x55, 0x55, 0x55, 0x55, 0x55, // num blocks
1936
            0x00, 0x20,
1937
        ];
1938

UNCOV
1939
        check_codec_and_corruption::<GetBlocksInv>(&getblocksdata, &getblocksdata_bytes);
×
UNCOV
1940
    }
×
1941

1942
    #[test]
UNCOV
1943
    fn codec_BlocksInvData() {
×
UNCOV
1944
        let blocks_bitlen: u32 = 32;
×
1945

UNCOV
1946
        let maximal_bitvec = vec![0xffu8; (blocks_bitlen / 8) as usize];
×
UNCOV
1947
        let maximal_blocksinvdata = BlocksInvData {
×
UNCOV
1948
            bitlen: blocks_bitlen as u16,
×
UNCOV
1949
            block_bitvec: maximal_bitvec.clone(),
×
UNCOV
1950
            microblocks_bitvec: maximal_bitvec.clone(),
×
UNCOV
1951
        };
×
1952

UNCOV
1953
        let mut maximal_blocksinvdata_bytes: Vec<u8> = vec![];
×
1954
        // bitlen
UNCOV
1955
        maximal_blocksinvdata_bytes.append(&mut (blocks_bitlen as u16).to_be_bytes().to_vec());
×
1956
        // block bitvec
UNCOV
1957
        maximal_blocksinvdata_bytes.append(&mut (blocks_bitlen / 8).to_be_bytes().to_vec());
×
UNCOV
1958
        maximal_blocksinvdata_bytes.extend_from_slice(&maximal_bitvec);
×
1959
        // microblock bitvec
UNCOV
1960
        maximal_blocksinvdata_bytes.append(&mut (blocks_bitlen / 8).to_be_bytes().to_vec());
×
UNCOV
1961
        maximal_blocksinvdata_bytes.extend_from_slice(&maximal_bitvec);
×
1962

UNCOV
1963
        assert!((maximal_blocksinvdata_bytes.len() as u32) < MAX_MESSAGE_LEN);
×
1964

UNCOV
1965
        check_codec_and_corruption::<BlocksInvData>(
×
UNCOV
1966
            &maximal_blocksinvdata,
×
UNCOV
1967
            &maximal_blocksinvdata_bytes,
×
1968
        );
1969

1970
        // should fail to decode if the bitlen doesn't match the bitvec
UNCOV
1971
        let long_bitlen = BlocksInvData {
×
UNCOV
1972
            bitlen: 1,
×
UNCOV
1973
            block_bitvec: vec![0xff, 0x01],
×
UNCOV
1974
            microblocks_bitvec: vec![0xff, 0x01],
×
UNCOV
1975
        };
×
UNCOV
1976
        assert!(check_deserialize_failure::<BlocksInvData>(&long_bitlen));
×
1977

UNCOV
1978
        let short_bitlen = BlocksInvData {
×
UNCOV
1979
            bitlen: 9,
×
UNCOV
1980
            block_bitvec: vec![0xff],
×
UNCOV
1981
            microblocks_bitvec: vec![0xff],
×
UNCOV
1982
        };
×
UNCOV
1983
        assert!(check_deserialize_failure::<BlocksInvData>(&short_bitlen));
×
1984

1985
        // empty
UNCOV
1986
        let empty_inv = BlocksInvData {
×
UNCOV
1987
            bitlen: 0,
×
UNCOV
1988
            block_bitvec: vec![],
×
UNCOV
1989
            microblocks_bitvec: vec![],
×
UNCOV
1990
        };
×
UNCOV
1991
        let empty_inv_bytes = [
×
UNCOV
1992
            // bitlen
×
UNCOV
1993
            0x00, 0x00, 0x00, 0x00, // bitvec
×
UNCOV
1994
            0x00, 0x00, 0x00, 0x00, // microblock bitvec
×
UNCOV
1995
            0x00, 0x00, 0x00, 0x00,
×
UNCOV
1996
        ];
×
1997

UNCOV
1998
        assert!(check_deserialize_failure::<BlocksInvData>(&empty_inv));
×
UNCOV
1999
    }
×
2000

2001
    #[test]
UNCOV
2002
    fn codec_NeighborAddress() {
×
UNCOV
2003
        let data = NeighborAddress {
×
UNCOV
2004
            addrbytes: PeerAddress([
×
UNCOV
2005
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
×
UNCOV
2006
                0x0e, 0x0f,
×
UNCOV
2007
            ]),
×
UNCOV
2008
            port: 12345,
×
UNCOV
2009
            public_key_hash: Hash160::from_bytes(
×
UNCOV
2010
                &hex_bytes("1111111111111111111111111111111111111111").unwrap(),
×
UNCOV
2011
            )
×
UNCOV
2012
            .unwrap(),
×
UNCOV
2013
        };
×
UNCOV
2014
        let bytes = vec![
×
2015
            // addrbytes
2016
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
2017
            0x0e, 0x0f, // port
2018
            0x30, 0x39, // public key hash
2019
            0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2020
            0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2021
        ];
2022

UNCOV
2023
        assert_eq!(bytes.len() as u32, NEIGHBOR_ADDRESS_ENCODED_SIZE);
×
UNCOV
2024
        check_codec_and_corruption::<NeighborAddress>(&data, &bytes);
×
UNCOV
2025
    }
×
2026

2027
    #[test]
UNCOV
2028
    fn codec_NeighborsData() {
×
UNCOV
2029
        let data = NeighborsData {
×
UNCOV
2030
            neighbors: vec![
×
UNCOV
2031
                NeighborAddress {
×
UNCOV
2032
                    addrbytes: PeerAddress([
×
UNCOV
2033
                        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
×
UNCOV
2034
                        0x0c, 0x0d, 0x0e, 0x0f,
×
UNCOV
2035
                    ]),
×
UNCOV
2036
                    port: 12345,
×
UNCOV
2037
                    public_key_hash: Hash160::from_bytes(
×
UNCOV
2038
                        &hex_bytes("1111111111111111111111111111111111111111").unwrap(),
×
UNCOV
2039
                    )
×
UNCOV
2040
                    .unwrap(),
×
UNCOV
2041
                },
×
UNCOV
2042
                NeighborAddress {
×
UNCOV
2043
                    addrbytes: PeerAddress([
×
UNCOV
2044
                        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
×
UNCOV
2045
                        0x1c, 0x1d, 0x1e, 0x1f,
×
UNCOV
2046
                    ]),
×
UNCOV
2047
                    port: 23456,
×
UNCOV
2048
                    public_key_hash: Hash160::from_bytes(
×
UNCOV
2049
                        &hex_bytes("2222222222222222222222222222222222222222").unwrap(),
×
UNCOV
2050
                    )
×
UNCOV
2051
                    .unwrap(),
×
UNCOV
2052
                },
×
UNCOV
2053
            ],
×
UNCOV
2054
        };
×
UNCOV
2055
        let bytes = vec![
×
2056
            // length
2057
            0x00, 0x00, 0x00, 0x02, // addrbytes
2058
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
2059
            0x0e, 0x0f, // port
2060
            0x30, 0x39, // public key hash
2061
            0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2062
            0x11, 0x11, 0x11, 0x11, 0x11, 0x11, // addrbytes
2063
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
2064
            0x1e, 0x1f, // port
2065
            0x5b, 0xa0, // public key hash
2066
            0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
2067
            0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
2068
        ];
2069

UNCOV
2070
        check_codec_and_corruption::<NeighborsData>(&data, &bytes);
×
UNCOV
2071
    }
×
2072

2073
    #[test]
UNCOV
2074
    fn codec_HandshakeData() {
×
UNCOV
2075
        let data = HandshakeData {
×
UNCOV
2076
            addrbytes: PeerAddress([
×
UNCOV
2077
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
×
UNCOV
2078
                0x0e, 0x0f,
×
UNCOV
2079
            ]),
×
UNCOV
2080
            port: 12345,
×
UNCOV
2081
            services: 0x0001,
×
UNCOV
2082
            node_public_key: StacksPublicKeyBuffer::from_bytes(
×
UNCOV
2083
                &hex_bytes("034e316be04870cef1795fba64d581cf64bad0c894b01a068fb9edf85321dcd9bb")
×
UNCOV
2084
                    .unwrap(),
×
UNCOV
2085
            )
×
UNCOV
2086
            .unwrap(),
×
UNCOV
2087
            expire_block_height: 0x0102030405060708,
×
UNCOV
2088
            data_url: UrlString::try_from("https://the-new-interwebs.com/data").unwrap(),
×
UNCOV
2089
        };
×
UNCOV
2090
        let mut bytes = vec![
×
2091
            // addrbytes
2092
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
2093
            0x0e, 0x0f, // port
2094
            0x30, 0x39, // services
2095
            0x00, 0x01, // public key
2096
            0x03, 0x4e, 0x31, 0x6b, 0xe0, 0x48, 0x70, 0xce, 0xf1, 0x79, 0x5f, 0xba, 0x64, 0xd5,
2097
            0x81, 0xcf, 0x64, 0xba, 0xd0, 0xc8, 0x94, 0xb0, 0x1a, 0x06, 0x8f, 0xb9, 0xed, 0xf8,
2098
            0x53, 0x21, 0xdc, 0xd9, 0xbb, // expire block height
2099
            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
2100
        ];
2101
        // data URL
UNCOV
2102
        bytes.push(data.data_url.len() as u8);
×
UNCOV
2103
        bytes.extend_from_slice(data.data_url.as_bytes());
×
2104

UNCOV
2105
        check_codec_and_corruption::<HandshakeData>(&data, &bytes);
×
UNCOV
2106
    }
×
2107

2108
    #[test]
UNCOV
2109
    fn codec_HandshakeAcceptData() {
×
UNCOV
2110
        let data = HandshakeAcceptData {
×
UNCOV
2111
            handshake: HandshakeData {
×
UNCOV
2112
                addrbytes: PeerAddress([
×
UNCOV
2113
                    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
×
UNCOV
2114
                    0x0d, 0x0e, 0x0f,
×
UNCOV
2115
                ]),
×
UNCOV
2116
                port: 12345,
×
UNCOV
2117
                services: 0x0001,
×
UNCOV
2118
                node_public_key: StacksPublicKeyBuffer::from_bytes(
×
UNCOV
2119
                    &hex_bytes(
×
UNCOV
2120
                        "034e316be04870cef1795fba64d581cf64bad0c894b01a068fb9edf85321dcd9bb",
×
UNCOV
2121
                    )
×
UNCOV
2122
                    .unwrap(),
×
UNCOV
2123
                )
×
UNCOV
2124
                .unwrap(),
×
UNCOV
2125
                expire_block_height: 0x0102030405060708,
×
UNCOV
2126
                data_url: UrlString::try_from("https://the-new-interwebs.com/data").unwrap(),
×
UNCOV
2127
            },
×
UNCOV
2128
            heartbeat_interval: 0x01020304,
×
UNCOV
2129
        };
×
UNCOV
2130
        let mut bytes = vec![
×
2131
            // addrbytes
2132
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
2133
            0x0e, 0x0f, // port
2134
            0x30, 0x39, // services
2135
            0x00, 0x01, // public key
2136
            0x03, 0x4e, 0x31, 0x6b, 0xe0, 0x48, 0x70, 0xce, 0xf1, 0x79, 0x5f, 0xba, 0x64, 0xd5,
2137
            0x81, 0xcf, 0x64, 0xba, 0xd0, 0xc8, 0x94, 0xb0, 0x1a, 0x06, 0x8f, 0xb9, 0xed, 0xf8,
2138
            0x53, 0x21, 0xdc, 0xd9, 0xbb, // expire block height
2139
            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
2140
        ];
2141
        // data URL
UNCOV
2142
        bytes.push(data.handshake.data_url.len() as u8);
×
UNCOV
2143
        bytes.extend_from_slice(data.handshake.data_url.as_bytes());
×
2144

UNCOV
2145
        bytes.extend_from_slice(&[
×
UNCOV
2146
            // heartbeat
×
UNCOV
2147
            0x01, 0x02, 0x03, 0x04,
×
UNCOV
2148
        ]);
×
2149

UNCOV
2150
        check_codec_and_corruption::<HandshakeAcceptData>(&data, &bytes);
×
UNCOV
2151
    }
×
2152

2153
    #[test]
UNCOV
2154
    fn codec_NackData() {
×
UNCOV
2155
        let data = NackData {
×
UNCOV
2156
            error_code: 0x01020304,
×
UNCOV
2157
        };
×
UNCOV
2158
        let bytes = vec![
×
2159
            // error code
2160
            0x01, 0x02, 0x03, 0x04,
2161
        ];
2162

UNCOV
2163
        check_codec_and_corruption::<NackData>(&data, &bytes);
×
UNCOV
2164
    }
×
2165

2166
    #[test]
UNCOV
2167
    fn codec_RelayData() {
×
UNCOV
2168
        let data = RelayData {
×
UNCOV
2169
            peer: NeighborAddress {
×
UNCOV
2170
                addrbytes: PeerAddress([
×
UNCOV
2171
                    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
×
UNCOV
2172
                    0x0d, 0x0e, 0x0f,
×
UNCOV
2173
                ]),
×
UNCOV
2174
                port: 12345,
×
UNCOV
2175
                public_key_hash: Hash160::from_bytes(
×
UNCOV
2176
                    &hex_bytes("1111111111111111111111111111111111111111").unwrap(),
×
UNCOV
2177
                )
×
UNCOV
2178
                .unwrap(),
×
UNCOV
2179
            },
×
UNCOV
2180
            seq: 0x01020304,
×
UNCOV
2181
        };
×
UNCOV
2182
        let bytes = vec![
×
2183
            // peer.addrbytes
2184
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
2185
            0x0e, 0x0f, // peer.port
2186
            0x30, 0x39, // peer.public_key_hash
2187
            0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2188
            0x11, 0x11, 0x11, 0x11, 0x11, 0x11, // seq
2189
            0x01, 0x02, 0x03, 0x04,
2190
        ];
2191

UNCOV
2192
        check_codec_and_corruption::<RelayData>(&data, &bytes);
×
UNCOV
2193
    }
×
2194

2195
    #[test]
UNCOV
2196
    fn codec_BlocksAvailable() {
×
UNCOV
2197
        let data = BlocksAvailableData {
×
UNCOV
2198
            available: vec![
×
UNCOV
2199
                (ConsensusHash([0x11; 20]), BurnchainHeaderHash([0x22; 32])),
×
UNCOV
2200
                (ConsensusHash([0x33; 20]), BurnchainHeaderHash([0x44; 32])),
×
UNCOV
2201
            ],
×
UNCOV
2202
        };
×
UNCOV
2203
        let bytes = vec![
×
2204
            // length
2205
            0x00, 0x00, 0x00, 0x02, // first tuple
2206
            0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2207
            0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
2208
            0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
2209
            0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, // second tuple
2210
            0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
2211
            0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2212
            0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2213
            0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2214
        ];
2215

UNCOV
2216
        check_codec_and_corruption::<BlocksAvailableData>(&data, &bytes);
×
UNCOV
2217
    }
×
2218

2219
    #[test]
UNCOV
2220
    fn codec_NatPunch() {
×
UNCOV
2221
        let data = NatPunchData {
×
UNCOV
2222
            addrbytes: PeerAddress([0x1; 16]),
×
UNCOV
2223
            port: 0x1234,
×
UNCOV
2224
            nonce: 0x56789abc,
×
UNCOV
2225
        };
×
UNCOV
2226
        let bytes = vec![
×
2227
            // peer address
2228
            0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
2229
            0x01, 0x01, // port
2230
            0x12, 0x34, // nonce
2231
            0x56, 0x78, 0x9a, 0xbc,
2232
        ];
2233

UNCOV
2234
        check_codec_and_corruption::<NatPunchData>(&data, &bytes);
×
UNCOV
2235
    }
×
2236

2237
    #[test]
UNCOV
2238
    fn codec_StackerDBHandshakeAccept() {
×
UNCOV
2239
        let data = StackerDBHandshakeData {
×
UNCOV
2240
            rc_consensus_hash: ConsensusHash([0x01; 20]),
×
UNCOV
2241
            smart_contracts: vec![
×
UNCOV
2242
                QualifiedContractIdentifier::parse("SP8QPP8TVXYAXS1VFSERG978A6WKBF59NSYJQEMN.foo")
×
UNCOV
2243
                    .unwrap(),
×
UNCOV
2244
                QualifiedContractIdentifier::parse("SP28D54YKFCMRKXBR6BR0E4BPN57S62RSM4XEVPRP.bar")
×
UNCOV
2245
                    .unwrap(),
×
UNCOV
2246
            ],
×
UNCOV
2247
        };
×
UNCOV
2248
        let bytes = vec![
×
2249
            // rc consensus hash
2250
            0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
2251
            0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // len(smart_contracts)
2252
            0x02, // SP8QPP8TVXYAXS1VFSERG978A6WKBF59NSYJQEMN
2253
            0x16, 0x11, 0x7b, 0x59, 0x1a, 0xdf, 0x7c, 0xae, 0xe4, 0x3b, 0x7e, 0x5d, 0x88, 0x24,
2254
            0xe8, 0x51, 0xb9, 0x35, 0xbc, 0xa9, 0xae, // len(foo)
2255
            0x03, // foo
2256
            0x66, 0x6f, 0x6f, // SP28D54YKFCMRKXBR6BR0E4BPN57S62RSM4XEVPRP
2257
            0x16, 0x90, 0xd2, 0x93, 0xd3, 0x7b, 0x29, 0x89, 0xf5, 0x78, 0x32, 0xf0, 0x07, 0x11,
2258
            0x76, 0xa9, 0x4f, 0x93, 0x0b, 0x19, 0xa1, // len(bar)
2259
            0x03, // bar
2260
            0x62, 0x61, 0x72,
2261
        ];
2262

UNCOV
2263
        check_codec_and_corruption::<StackerDBHandshakeData>(&data, &bytes);
×
UNCOV
2264
    }
×
2265

2266
    #[test]
UNCOV
2267
    fn codec_StackerDBGetChunkInvData() {
×
UNCOV
2268
        let data = StackerDBGetChunkInvData {
×
UNCOV
2269
            contract_id: QualifiedContractIdentifier::parse(
×
UNCOV
2270
                "SP8QPP8TVXYAXS1VFSERG978A6WKBF59NSYJQEMN.foo",
×
UNCOV
2271
            )
×
UNCOV
2272
            .unwrap(),
×
UNCOV
2273
            rc_consensus_hash: ConsensusHash([0x01; 20]),
×
UNCOV
2274
        };
×
2275

UNCOV
2276
        let bytes = vec![
×
2277
            // SP8QPP8TVXYAXS1VFSERG978A6WKBF59NSYJQEMN
2278
            0x16, 0x11, 0x7b, 0x59, 0x1a, 0xdf, 0x7c, 0xae, 0xe4, 0x3b, 0x7e, 0x5d, 0x88, 0x24,
2279
            0xe8, 0x51, 0xb9, 0x35, 0xbc, 0xa9, 0xae, // len(foo)
2280
            0x03, // foo
2281
            0x66, 0x6f, 0x6f, // rc consensus hash
2282
            0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
2283
            0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
2284
        ];
2285

UNCOV
2286
        check_codec_and_corruption::<StackerDBGetChunkInvData>(&data, &bytes);
×
UNCOV
2287
    }
×
2288

2289
    #[test]
UNCOV
2290
    fn codec_StackerDBChunkInvData() {
×
UNCOV
2291
        let data = StackerDBChunkInvData {
×
UNCOV
2292
            slot_versions: vec![0, 1, 2, 3],
×
UNCOV
2293
            num_outbound_replicas: 4,
×
UNCOV
2294
        };
×
2295

UNCOV
2296
        let bytes = vec![
×
2297
            // len(slot_versions)
2298
            0x00, 0x00, 0x00, 0x04, // 0u32
2299
            0x00, 0x00, 0x00, 0x00, // 1u32
2300
            0x00, 0x00, 0x00, 0x01, // 2u32
2301
            0x00, 0x00, 0x00, 0x02, // 3u32
2302
            0x00, 0x00, 0x00, 0x03, // num_outbound_replicas
2303
            0x00, 0x00, 0x00, 0x04,
2304
        ];
2305

UNCOV
2306
        check_codec_and_corruption::<StackerDBChunkInvData>(&data, &bytes);
×
UNCOV
2307
    }
×
2308

2309
    #[test]
UNCOV
2310
    fn codec_StackerDBGetChunkData() {
×
UNCOV
2311
        let data = StackerDBGetChunkData {
×
UNCOV
2312
            contract_id: QualifiedContractIdentifier::parse(
×
UNCOV
2313
                "SP8QPP8TVXYAXS1VFSERG978A6WKBF59NSYJQEMN.foo",
×
UNCOV
2314
            )
×
UNCOV
2315
            .unwrap(),
×
UNCOV
2316
            rc_consensus_hash: ConsensusHash([0x01; 20]),
×
UNCOV
2317
            slot_id: 2,
×
UNCOV
2318
            slot_version: 3,
×
UNCOV
2319
        };
×
2320

UNCOV
2321
        let bytes = vec![
×
2322
            // SP8QPP8TVXYAXS1VFSERG978A6WKBF59NSYJQEMN
2323
            0x16, 0x11, 0x7b, 0x59, 0x1a, 0xdf, 0x7c, 0xae, 0xe4, 0x3b, 0x7e, 0x5d, 0x88, 0x24,
2324
            0xe8, 0x51, 0xb9, 0x35, 0xbc, 0xa9, 0xae, // len(foo)
2325
            0x03, // foo
2326
            0x66, 0x6f, 0x6f, // rc consensus hash
2327
            0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
2328
            0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // slot id
2329
            0x00, 0x00, 0x00, 0x02, // slot version
2330
            0x00, 0x00, 0x00, 0x03,
2331
        ];
2332

UNCOV
2333
        check_codec_and_corruption::<StackerDBGetChunkData>(&data, &bytes);
×
UNCOV
2334
    }
×
2335

2336
    #[test]
UNCOV
2337
    fn codec_StackerDBChunkData() {
×
UNCOV
2338
        let data = StackerDBChunkData {
×
UNCOV
2339
            slot_id: 2,
×
UNCOV
2340
            slot_version: 3,
×
UNCOV
2341
            sig: MessageSignature::from_raw(&[0x44; 65]),
×
UNCOV
2342
            data: vec![
×
UNCOV
2343
                0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
×
UNCOV
2344
            ],
×
UNCOV
2345
        };
×
2346

UNCOV
2347
        let bytes = vec![
×
2348
            // slot id
2349
            0x00, 0x00, 0x00, 0x02, // slot version
2350
            0x00, 0x00, 0x00, 0x03, // signature
2351
            0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2352
            0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2353
            0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2354
            0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2355
            0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, // length
2356
            0x00, 0x00, 0x00, 0x0b, // data
2357
            0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
2358
        ];
2359

UNCOV
2360
        check_codec_and_corruption::<StackerDBChunkData>(&data, &bytes);
×
UNCOV
2361
    }
×
2362

2363
    #[test]
UNCOV
2364
    fn codec_StackerDBPushChunkData() {
×
UNCOV
2365
        let data = StackerDBChunkData {
×
UNCOV
2366
            slot_id: 2,
×
UNCOV
2367
            slot_version: 3,
×
UNCOV
2368
            sig: MessageSignature::from_raw(&[0x44; 65]),
×
UNCOV
2369
            data: vec![
×
UNCOV
2370
                0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
×
UNCOV
2371
            ],
×
UNCOV
2372
        };
×
2373

UNCOV
2374
        let push_data = StackerDBPushChunkData {
×
UNCOV
2375
            contract_id: QualifiedContractIdentifier::parse(
×
UNCOV
2376
                "SP8QPP8TVXYAXS1VFSERG978A6WKBF59NSYJQEMN.foo",
×
UNCOV
2377
            )
×
UNCOV
2378
            .unwrap(),
×
UNCOV
2379
            rc_consensus_hash: ConsensusHash([0x01; 20]),
×
UNCOV
2380
            chunk_data: data,
×
UNCOV
2381
        };
×
2382

UNCOV
2383
        let bytes = vec![
×
2384
            // SP8QPP8TVXYAXS1VFSERG978A6WKBF59NSYJQEMN
2385
            0x16, 0x11, 0x7b, 0x59, 0x1a, 0xdf, 0x7c, 0xae, 0xe4, 0x3b, 0x7e, 0x5d, 0x88, 0x24,
2386
            0xe8, 0x51, 0xb9, 0x35, 0xbc, 0xa9, 0xae, // len(foo)
2387
            0x03, // foo
2388
            0x66, 0x6f, 0x6f, // rc consensus hash
2389
            0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
2390
            0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // slot id
2391
            0x00, 0x00, 0x00, 0x02, // slot version
2392
            0x00, 0x00, 0x00, 0x03, // signature
2393
            0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2394
            0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2395
            0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2396
            0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2397
            0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, // length
2398
            0x00, 0x00, 0x00, 0x0b, // data
2399
            0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
2400
        ];
2401

UNCOV
2402
        check_codec_and_corruption::<StackerDBPushChunkData>(&push_data, &bytes);
×
UNCOV
2403
    }
×
2404

2405
    #[test]
UNCOV
2406
    fn codec_GetNakamotoInv() {
×
UNCOV
2407
        let get_nakamoto_inv = GetNakamotoInvData {
×
UNCOV
2408
            consensus_hash: ConsensusHash([0x55; 20]),
×
UNCOV
2409
        };
×
2410

UNCOV
2411
        let get_nakamoto_inv_bytes: Vec<u8> = vec![
×
2412
            // consensus hash
2413
            0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
2414
            0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
2415
        ];
2416

UNCOV
2417
        check_codec_and_corruption::<GetNakamotoInvData>(
×
UNCOV
2418
            &get_nakamoto_inv,
×
UNCOV
2419
            &get_nakamoto_inv_bytes,
×
2420
        );
UNCOV
2421
    }
×
2422

2423
    #[test]
UNCOV
2424
    fn codec_NakamotoInv() {
×
UNCOV
2425
        let nakamoto_inv = NakamotoInvData {
×
UNCOV
2426
            tenures: BitVec::<2100>::try_from(
×
UNCOV
2427
                // 0xdd
×
UNCOV
2428
                vec![
×
UNCOV
2429
                    true, false, true, true, true, false, true, true, // 0xee
×
UNCOV
2430
                    false, true, true, true, false, true, true, true, // 0xaa
×
UNCOV
2431
                    false, true, false, true, false, true, false, true, // 0xdd
×
UNCOV
2432
                    true, false, true, true, true, false, true, true, // 0xbb
×
UNCOV
2433
                    true, true, false, true, true, true, false, true, // 0xee
×
UNCOV
2434
                    false, true, true, true, false, true, true, true, // 0xee
×
UNCOV
2435
                    false, true, true, true, false, true, true, true, // 0xff
×
UNCOV
2436
                    true, true, true, true, true, true, true, true,
×
UNCOV
2437
                ]
×
UNCOV
2438
                .as_slice(),
×
UNCOV
2439
            )
×
UNCOV
2440
            .unwrap(),
×
UNCOV
2441
        };
×
2442

UNCOV
2443
        let nakamoto_inv_bytes = [
×
UNCOV
2444
            // bitlen
×
UNCOV
2445
            0x00, 0x40, // vec len
×
UNCOV
2446
            0x00, 0x00, 0x00, 0x08, // bits
×
UNCOV
2447
            0xdd, 0xee, 0xaa, 0xdd, 0xbb, 0xee, 0xee, 0xff,
×
UNCOV
2448
        ];
×
2449

UNCOV
2450
        check_codec_and_corruption::<NakamotoInvData>(&nakamoto_inv, &nakamoto_inv_bytes);
×
2451

2452
        // should fail
UNCOV
2453
        let nakamoto_inv_bytes = [
×
UNCOV
2454
            // bitlen
×
UNCOV
2455
            0x00, 0x20, // vec len
×
UNCOV
2456
            0x00, 0x00, 0x00, 0x05, // bits
×
UNCOV
2457
            0x00, 0x00, 0x00, 0x00,
×
UNCOV
2458
        ];
×
2459

UNCOV
2460
        let _ = NakamotoInvData::consensus_deserialize(&mut &nakamoto_inv_bytes[..]).unwrap_err();
×
2461

2462
        // should fail
UNCOV
2463
        let nakamoto_inv_bytes = [
×
UNCOV
2464
            // bitlen
×
UNCOV
2465
            0x00, 0x21, // vec len
×
UNCOV
2466
            0x00, 0x00, 0x00, 0x04, // bits
×
UNCOV
2467
            0x00, 0x00, 0x00, 0x00,
×
UNCOV
2468
        ];
×
2469

UNCOV
2470
        let _ = NakamotoInvData::consensus_deserialize(&mut &nakamoto_inv_bytes[..]).unwrap_err();
×
UNCOV
2471
    }
×
2472

2473
    #[test]
UNCOV
2474
    fn codec_StacksMessage() {
×
UNCOV
2475
        let payloads: Vec<StacksMessageType> = vec![
×
UNCOV
2476
            StacksMessageType::Handshake(HandshakeData {
×
UNCOV
2477
                addrbytes: PeerAddress([
×
UNCOV
2478
                    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
×
UNCOV
2479
                    0x0d, 0x0e, 0x0f,
×
UNCOV
2480
                ]),
×
UNCOV
2481
                port: 12345,
×
UNCOV
2482
                services: 0x0001,
×
UNCOV
2483
                node_public_key: StacksPublicKeyBuffer::from_bytes(
×
UNCOV
2484
                    &hex_bytes(
×
UNCOV
2485
                        "034e316be04870cef1795fba64d581cf64bad0c894b01a068fb9edf85321dcd9bb",
×
UNCOV
2486
                    )
×
UNCOV
2487
                    .unwrap(),
×
UNCOV
2488
                )
×
UNCOV
2489
                .unwrap(),
×
UNCOV
2490
                expire_block_height: 0x0102030405060708,
×
UNCOV
2491
                data_url: UrlString::try_from("https://the-new-interwebs.com:4008/the-data")
×
UNCOV
2492
                    .unwrap(),
×
UNCOV
2493
            }),
×
UNCOV
2494
            StacksMessageType::HandshakeAccept(HandshakeAcceptData {
×
UNCOV
2495
                heartbeat_interval: 0x01020304,
×
UNCOV
2496
                handshake: HandshakeData {
×
UNCOV
2497
                    addrbytes: PeerAddress([
×
UNCOV
2498
                        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
×
UNCOV
2499
                        0x0c, 0x0d, 0x0e, 0x0f,
×
UNCOV
2500
                    ]),
×
UNCOV
2501
                    port: 12345,
×
UNCOV
2502
                    services: 0x0001,
×
UNCOV
2503
                    node_public_key: StacksPublicKeyBuffer::from_bytes(
×
UNCOV
2504
                        &hex_bytes(
×
UNCOV
2505
                            "034e316be04870cef1795fba64d581cf64bad0c894b01a068fb9edf85321dcd9bb",
×
UNCOV
2506
                        )
×
UNCOV
2507
                        .unwrap(),
×
UNCOV
2508
                    )
×
UNCOV
2509
                    .unwrap(),
×
UNCOV
2510
                    expire_block_height: 0x0102030405060708,
×
UNCOV
2511
                    data_url: UrlString::try_from("https://the-new-interwebs.com:4008/the-data")
×
UNCOV
2512
                        .unwrap(),
×
UNCOV
2513
                },
×
UNCOV
2514
            }),
×
UNCOV
2515
            StacksMessageType::HandshakeReject,
×
UNCOV
2516
            StacksMessageType::GetNeighbors,
×
UNCOV
2517
            StacksMessageType::Neighbors(NeighborsData {
×
UNCOV
2518
                neighbors: vec![
×
UNCOV
2519
                    NeighborAddress {
×
UNCOV
2520
                        addrbytes: PeerAddress([
×
UNCOV
2521
                            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
×
UNCOV
2522
                            0x0c, 0x0d, 0x0e, 0x0f,
×
UNCOV
2523
                        ]),
×
UNCOV
2524
                        port: 12345,
×
UNCOV
2525
                        public_key_hash: Hash160::from_bytes(
×
UNCOV
2526
                            &hex_bytes("1111111111111111111111111111111111111111").unwrap(),
×
UNCOV
2527
                        )
×
UNCOV
2528
                        .unwrap(),
×
UNCOV
2529
                    },
×
UNCOV
2530
                    NeighborAddress {
×
UNCOV
2531
                        addrbytes: PeerAddress([
×
UNCOV
2532
                            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
×
UNCOV
2533
                            0x1c, 0x1d, 0x1e, 0x1f,
×
UNCOV
2534
                        ]),
×
UNCOV
2535
                        port: 23456,
×
UNCOV
2536
                        public_key_hash: Hash160::from_bytes(
×
UNCOV
2537
                            &hex_bytes("2222222222222222222222222222222222222222").unwrap(),
×
UNCOV
2538
                        )
×
UNCOV
2539
                        .unwrap(),
×
UNCOV
2540
                    },
×
UNCOV
2541
                ],
×
UNCOV
2542
            }),
×
UNCOV
2543
            StacksMessageType::GetPoxInv(GetPoxInv {
×
UNCOV
2544
                consensus_hash: ConsensusHash([0x55; 20]),
×
UNCOV
2545
                num_cycles: GETPOXINV_MAX_BITLEN as u16,
×
UNCOV
2546
            }),
×
UNCOV
2547
            StacksMessageType::PoxInv(PoxInvData {
×
UNCOV
2548
                bitlen: 2,
×
UNCOV
2549
                pox_bitvec: vec![0x03],
×
UNCOV
2550
            }),
×
UNCOV
2551
            StacksMessageType::GetBlocksInv(GetBlocksInv {
×
UNCOV
2552
                consensus_hash: ConsensusHash([0x55; 20]),
×
UNCOV
2553
                num_blocks: 32,
×
UNCOV
2554
            }),
×
UNCOV
2555
            StacksMessageType::BlocksInv(BlocksInvData {
×
UNCOV
2556
                bitlen: 2,
×
UNCOV
2557
                block_bitvec: vec![0x03],
×
UNCOV
2558
                microblocks_bitvec: vec![0x03],
×
UNCOV
2559
            }),
×
UNCOV
2560
            StacksMessageType::BlocksAvailable(BlocksAvailableData {
×
UNCOV
2561
                available: vec![
×
UNCOV
2562
                    (ConsensusHash([0x11; 20]), BurnchainHeaderHash([0x22; 32])),
×
UNCOV
2563
                    (ConsensusHash([0x33; 20]), BurnchainHeaderHash([0x44; 32])),
×
UNCOV
2564
                ],
×
UNCOV
2565
            }),
×
UNCOV
2566
            StacksMessageType::MicroblocksAvailable(BlocksAvailableData {
×
UNCOV
2567
                available: vec![
×
UNCOV
2568
                    (ConsensusHash([0x11; 20]), BurnchainHeaderHash([0x22; 32])),
×
UNCOV
2569
                    (ConsensusHash([0x33; 20]), BurnchainHeaderHash([0x44; 32])),
×
UNCOV
2570
                ],
×
UNCOV
2571
            }),
×
2572
            // TODO: Blocks
2573
            // TODO: Microblocks
2574
            // TODO: Transaction
UNCOV
2575
            StacksMessageType::Nack(NackData {
×
UNCOV
2576
                error_code: 0x01020304,
×
UNCOV
2577
            }),
×
UNCOV
2578
            StacksMessageType::Ping(PingData { nonce: 0x01020304 }),
×
UNCOV
2579
            StacksMessageType::Pong(PongData { nonce: 0x01020304 }),
×
UNCOV
2580
            StacksMessageType::NatPunchRequest(0x12345678),
×
UNCOV
2581
            StacksMessageType::NatPunchReply(NatPunchData {
×
UNCOV
2582
                addrbytes: PeerAddress([
×
UNCOV
2583
                    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
×
UNCOV
2584
                    0x0d, 0x0e, 0x0f,
×
UNCOV
2585
                ]),
×
UNCOV
2586
                port: 12345,
×
UNCOV
2587
                nonce: 0x12345678,
×
UNCOV
2588
            }),
×
UNCOV
2589
            StacksMessageType::StackerDBHandshakeAccept(
×
UNCOV
2590
                HandshakeAcceptData {
×
UNCOV
2591
                    heartbeat_interval: 0x01020304,
×
UNCOV
2592
                    handshake: HandshakeData {
×
UNCOV
2593
                        addrbytes: PeerAddress([
×
UNCOV
2594
                            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
×
UNCOV
2595
                            0x0c, 0x0d, 0x0e, 0x0f,
×
UNCOV
2596
                        ]),
×
UNCOV
2597
                        port: 12345,
×
UNCOV
2598
                        services: 0x0001,
×
UNCOV
2599
                        node_public_key: StacksPublicKeyBuffer::from_bytes(
×
UNCOV
2600
                            &hex_bytes(
×
UNCOV
2601
                                "034e316be04870cef1795fba64d581cf64bad0c894b01a068fb9edf85321dcd9bb",
×
UNCOV
2602
                            )
×
UNCOV
2603
                            .unwrap(),
×
UNCOV
2604
                        )
×
UNCOV
2605
                        .unwrap(),
×
UNCOV
2606
                        expire_block_height: 0x0102030405060708,
×
UNCOV
2607
                        data_url: UrlString::try_from("https://the-new-interwebs.com:4008/the-data")
×
UNCOV
2608
                            .unwrap(),
×
UNCOV
2609
                    },
×
UNCOV
2610
                },
×
UNCOV
2611
                StackerDBHandshakeData {
×
UNCOV
2612
                    rc_consensus_hash: ConsensusHash([0x01; 20]),
×
UNCOV
2613
                    smart_contracts: vec![QualifiedContractIdentifier::parse("SP8QPP8TVXYAXS1VFSERG978A6WKBF59NSYJQEMN.foo").unwrap(), QualifiedContractIdentifier::parse("SP28D54YKFCMRKXBR6BR0E4BPN57S62RSM4XEVPRP.bar").unwrap()]
×
UNCOV
2614
                }
×
UNCOV
2615
            ),
×
UNCOV
2616
            StacksMessageType::StackerDBGetChunkInv(StackerDBGetChunkInvData {
×
UNCOV
2617
                contract_id: QualifiedContractIdentifier::parse("SP8QPP8TVXYAXS1VFSERG978A6WKBF59NSYJQEMN.foo").unwrap(),
×
UNCOV
2618
                rc_consensus_hash: ConsensusHash([0x01; 20]),
×
UNCOV
2619
            }),
×
UNCOV
2620
            StacksMessageType::StackerDBChunkInv(StackerDBChunkInvData {
×
UNCOV
2621
                slot_versions: vec![0, 1, 2, 3],
×
UNCOV
2622
                num_outbound_replicas: 4,
×
UNCOV
2623
            }),
×
UNCOV
2624
            StacksMessageType::StackerDBGetChunk(StackerDBGetChunkData {
×
UNCOV
2625
                contract_id: QualifiedContractIdentifier::parse("SP8QPP8TVXYAXS1VFSERG978A6WKBF59NSYJQEMN.foo").unwrap(),
×
UNCOV
2626
                rc_consensus_hash: ConsensusHash([0x01; 20]),
×
UNCOV
2627
                slot_id: 2,
×
UNCOV
2628
                slot_version: 3
×
UNCOV
2629
            }),
×
UNCOV
2630
            StacksMessageType::StackerDBChunk(StackerDBChunkData {
×
UNCOV
2631
                slot_id: 2,
×
UNCOV
2632
                slot_version: 3,
×
UNCOV
2633
                sig: MessageSignature::from_raw(&[0x44; 65]),
×
UNCOV
2634
                data: vec![0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]
×
UNCOV
2635
            }),
×
UNCOV
2636
            StacksMessageType::StackerDBPushChunk(StackerDBPushChunkData {
×
UNCOV
2637
                contract_id: QualifiedContractIdentifier::parse("SP8QPP8TVXYAXS1VFSERG978A6WKBF59NSYJQEMN.foo").unwrap(),
×
UNCOV
2638
                rc_consensus_hash: ConsensusHash([0x01; 20]),
×
UNCOV
2639
                chunk_data: StackerDBChunkData {
×
UNCOV
2640
                    slot_id: 2,
×
UNCOV
2641
                    slot_version: 3,
×
UNCOV
2642
                    sig: MessageSignature::from_raw(&[0x44; 65]),
×
UNCOV
2643
                    data: vec![0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]
×
UNCOV
2644
                }
×
UNCOV
2645
            }),
×
UNCOV
2646
            StacksMessageType::GetNakamotoInv(GetNakamotoInvData {
×
UNCOV
2647
                consensus_hash: ConsensusHash([0x01; 20]),
×
UNCOV
2648
            }),
×
UNCOV
2649
            StacksMessageType::NakamotoInv(NakamotoInvData {
×
UNCOV
2650
                tenures: BitVec::<2100>::try_from(
×
UNCOV
2651
                    // 0xdd
×
UNCOV
2652
                    vec![true, true, false, true, true, true, false, true,
×
UNCOV
2653
                    // 0xee
×
UNCOV
2654
                    true, true, true, false, true, true, true, false,
×
UNCOV
2655
                    // 0xaa
×
UNCOV
2656
                    true, false, true, false, true, false, true, false,
×
UNCOV
2657
                    // 0xdd
×
UNCOV
2658
                    true, true, false, true, true, true, false, true,
×
UNCOV
2659
                    // 0xbb
×
UNCOV
2660
                    true, false, true, true, true, false, true, true,
×
UNCOV
2661
                    // 0xee
×
UNCOV
2662
                    true, true, true, false, true, true, true, false,
×
UNCOV
2663
                    // 0xee
×
UNCOV
2664
                    true, true, true, false, true, true, true, false,
×
UNCOV
2665
                    // 0xff
×
UNCOV
2666
                    true, true, true, true, true, true, true, true].as_slice()
×
UNCOV
2667
                ).unwrap()
×
UNCOV
2668
            }),
×
2669
        ];
2670

UNCOV
2671
        let mut maximal_relayers: Vec<RelayData> = vec![];
×
UNCOV
2672
        let mut too_many_relayers: Vec<RelayData> = vec![];
×
UNCOV
2673
        for i in 0..MAX_RELAYERS_LEN {
×
UNCOV
2674
            let next_relayer = RelayData {
×
UNCOV
2675
                peer: NeighborAddress {
×
UNCOV
2676
                    addrbytes: PeerAddress([
×
UNCOV
2677
                        i as u8, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
×
UNCOV
2678
                        0x0c, 0x0d, 0x0e, 0x0f,
×
UNCOV
2679
                    ]),
×
UNCOV
2680
                    port: 12345 + (i as u16),
×
UNCOV
2681
                    public_key_hash: Hash160::from_bytes(
×
UNCOV
2682
                        &hex_bytes("1111111111111111111111111111111111111111").unwrap(),
×
UNCOV
2683
                    )
×
UNCOV
2684
                    .unwrap(),
×
UNCOV
2685
                },
×
UNCOV
2686
                seq: 0x01020304 + i,
×
UNCOV
2687
            };
×
UNCOV
2688
            too_many_relayers.push(next_relayer.clone());
×
UNCOV
2689
            maximal_relayers.push(next_relayer);
×
UNCOV
2690
        }
×
UNCOV
2691
        too_many_relayers.push(RelayData {
×
UNCOV
2692
            peer: NeighborAddress {
×
UNCOV
2693
                addrbytes: PeerAddress([
×
UNCOV
2694
                    0xff, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
×
UNCOV
2695
                    0x0d, 0x0e, 0x0f,
×
UNCOV
2696
                ]),
×
UNCOV
2697
                port: 65535,
×
UNCOV
2698
                public_key_hash: Hash160::from_bytes(
×
UNCOV
2699
                    &hex_bytes("1111111111111111111111111111111111111111").unwrap(),
×
UNCOV
2700
                )
×
UNCOV
2701
                .unwrap(),
×
UNCOV
2702
            },
×
UNCOV
2703
            seq: 0x010203ff,
×
UNCOV
2704
        });
×
2705

UNCOV
2706
        let mut relayers_bytes: Vec<u8> = vec![];
×
UNCOV
2707
        maximal_relayers
×
UNCOV
2708
            .consensus_serialize(&mut relayers_bytes)
×
UNCOV
2709
            .unwrap();
×
2710

UNCOV
2711
        let mut too_many_relayer_bytes: Vec<u8> = vec![];
×
UNCOV
2712
        too_many_relayers
×
UNCOV
2713
            .consensus_serialize(&mut too_many_relayer_bytes)
×
UNCOV
2714
            .unwrap();
×
2715

UNCOV
2716
        for payload in &payloads {
×
2717
            // just testing codec; don't worry about signatures
2718
            // (only payload_len must be valid)
UNCOV
2719
            let mut payload_bytes: Vec<u8> = vec![];
×
UNCOV
2720
            payload.consensus_serialize(&mut payload_bytes).unwrap();
×
2721

UNCOV
2722
            let preamble = Preamble {
×
UNCOV
2723
                peer_version: 0x01020304,
×
UNCOV
2724
                network_id: 0x05060708,
×
UNCOV
2725
                seq: 0x090a0b0c,
×
UNCOV
2726
                burn_block_height: 0x00001122,
×
UNCOV
2727
                burn_block_hash: BurnchainHeaderHash([0x11; 32]),
×
UNCOV
2728
                burn_stable_block_height: 0x00001111,
×
UNCOV
2729
                burn_stable_block_hash: BurnchainHeaderHash([0x22; 32]),
×
UNCOV
2730
                additional_data: 0x33333333,
×
UNCOV
2731
                signature: MessageSignature::from_raw(&[0x44; 65]),
×
UNCOV
2732
                payload_len: (relayers_bytes.len() + payload_bytes.len()) as u32,
×
UNCOV
2733
            };
×
2734

UNCOV
2735
            let stacks_message = StacksMessage {
×
UNCOV
2736
                preamble: preamble.clone(),
×
UNCOV
2737
                relayers: maximal_relayers.clone(),
×
UNCOV
2738
                payload: payload.clone(),
×
UNCOV
2739
            };
×
2740

UNCOV
2741
            let mut stacks_message_bytes: Vec<u8> = vec![];
×
UNCOV
2742
            preamble
×
UNCOV
2743
                .consensus_serialize(&mut stacks_message_bytes)
×
UNCOV
2744
                .unwrap();
×
UNCOV
2745
            stacks_message_bytes.append(&mut relayers_bytes.clone());
×
UNCOV
2746
            stacks_message_bytes.append(&mut payload_bytes.clone());
×
2747

UNCOV
2748
            test_debug!(
×
2749
                "Test {}-byte relayer, {}-byte payload {:?}",
2750
                relayers_bytes.len(),
×
2751
                payload_bytes.len(),
×
2752
                &payload
×
2753
            );
UNCOV
2754
            check_codec_and_corruption::<StacksMessage>(&stacks_message, &stacks_message_bytes);
×
2755

2756
            // can't have too many relayers
UNCOV
2757
            let mut preamble_too_many_relayers = preamble.clone();
×
UNCOV
2758
            preamble_too_many_relayers.payload_len =
×
UNCOV
2759
                (too_many_relayer_bytes.len() + payload_bytes.len() + 1) as u32;
×
2760

UNCOV
2761
            let stacks_message_too_many_relayers = StacksMessage {
×
UNCOV
2762
                preamble: preamble_too_many_relayers.clone(),
×
UNCOV
2763
                relayers: too_many_relayers.clone(),
×
UNCOV
2764
                payload: payload.clone(),
×
UNCOV
2765
            };
×
UNCOV
2766
            assert!(check_deserialize_failure(&stacks_message_too_many_relayers));
×
2767
        }
UNCOV
2768
    }
×
2769

2770
    #[test]
UNCOV
2771
    fn codec_sign_and_verify() {
×
UNCOV
2772
        let privkey = Secp256k1PrivateKey::random();
×
UNCOV
2773
        let pubkey_buf =
×
UNCOV
2774
            StacksPublicKeyBuffer::from_public_key(&Secp256k1PublicKey::from_private(&privkey));
×
2775

UNCOV
2776
        let mut ping = StacksMessage::new(
×
2777
            PEER_VERSION_TESTNET,
2778
            0x9abcdef0,
2779
            12345,
UNCOV
2780
            &BurnchainHeaderHash([0x11; 32]),
×
2781
            12339,
UNCOV
2782
            &BurnchainHeaderHash([0x22; 32]),
×
UNCOV
2783
            StacksMessageType::Ping(PingData { nonce: 0x01020304 }),
×
2784
        );
2785

UNCOV
2786
        ping.sign(444, &privkey).unwrap();
×
UNCOV
2787
        ping.verify_secp256k1(&pubkey_buf).unwrap();
×
UNCOV
2788
    }
×
2789

2790
    #[test]
UNCOV
2791
    fn codec_stacks_public_key_roundtrip() {
×
UNCOV
2792
        for i in 0..100 {
×
UNCOV
2793
            let privkey = Secp256k1PrivateKey::random();
×
UNCOV
2794
            let pubkey = Secp256k1PublicKey::from_private(&privkey);
×
2795

UNCOV
2796
            let pubkey_buf = StacksPublicKeyBuffer::from_public_key(&pubkey);
×
UNCOV
2797
            let pubkey_2 = pubkey_buf.to_public_key().unwrap();
×
2798

UNCOV
2799
            assert_eq!(pubkey, pubkey_2);
×
2800
        }
UNCOV
2801
    }
×
2802

2803
    #[test]
UNCOV
2804
    fn blocks_inv_compress_bools() {
×
UNCOV
2805
        let block_flags = vec![
×
2806
            true, true, true, false, false, false, false, true, true, false, true,
2807
        ];
UNCOV
2808
        let block_bitvec = BlocksInvData::compress_bools(&block_flags);
×
UNCOV
2809
        assert_eq!(block_bitvec, vec![0x87, 0x05]);
×
2810

UNCOV
2811
        let short_block_flags = vec![true, false, true];
×
UNCOV
2812
        let short_block_bitvec = BlocksInvData::compress_bools(&short_block_flags);
×
UNCOV
2813
        assert_eq!(short_block_bitvec, vec![0x05]);
×
UNCOV
2814
    }
×
2815
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc