Skip to content

Commit a951e8c

Browse files
committed
BIP152: Test net msg ser/der and diff encoding
This adds tests for serialization of BIP152 network messages and tests specifically for the differential encoding of the transaction indicies of 'getblocktx'. Previously, this code contained an off-by-one error.
1 parent f91878c commit a951e8c

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

src/network/message.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,8 @@ mod test {
453453
use crate::blockdata::script::Script;
454454
use crate::network::message_bloom::{FilterAdd, FilterLoad, BloomFlags};
455455
use crate::MerkleBlock;
456+
use crate::network::message_compact_blocks::{GetBlockTxn, SendCmpct};
457+
use crate::util::bip152::BlockTransactionsRequest;
456458

457459
fn hash(slice: [u8;32]) -> Hash {
458460
Hash::from_slice(&slice).unwrap()
@@ -467,6 +469,9 @@ mod test {
467469
let header: BlockHeader = deserialize(&Vec::from_hex("010000004ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914cd74d6e49ffff001d323b3a7b").unwrap()).unwrap();
468470
let script: Script = deserialize(&Vec::from_hex("1976a91431a420903c05a0a7de2de40c9f02ebedbacdc17288ac").unwrap()).unwrap();
469471
let merkle_block: MerkleBlock = deserialize(&Vec::from_hex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101").unwrap()).unwrap();
472+
let cmptblock = deserialize(&Vec::from_hex("00000030d923ad36ff2d955abab07f8a0a6e813bc6e066b973e780c5e36674cad5d1cd1f6e265f2a17a0d35cbe701fe9d06e2c6324cfe135f6233e8b767bfa3fb4479b71115dc562ffff7f2006000000000000000000000000010002000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0302ee00ffffffff0100f9029500000000015100000000").unwrap()).unwrap();
473+
let blocktxn = deserialize(&Vec::from_hex("2e93c0cff39ff605020072d96bc3a8d20b8447e294d08092351c8583e08d9b5a01020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402dc0000ffffffff0200f90295000000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000").unwrap()).unwrap();
474+
470475

471476
let msgs = vec![
472477
NetworkMessage::Version(version_msg),
@@ -502,6 +507,10 @@ mod test {
502507
NetworkMessage::WtxidRelay,
503508
NetworkMessage::AddrV2(vec![AddrV2Message{ addr: AddrV2::Ipv4(Ipv4Addr::new(127, 0, 0, 1)), port: 0, services: ServiceFlags::NONE, time: 0 }]),
504509
NetworkMessage::SendAddrV2,
510+
NetworkMessage::CmpctBlock(cmptblock),
511+
NetworkMessage::GetBlockTxn(GetBlockTxn { txs_request: BlockTransactionsRequest { block_hash: hash([11u8; 32]).into(), indexes: vec![0, 1, 2, 3, 10, 3002] } }),
512+
NetworkMessage::BlockTxn(blocktxn),
513+
NetworkMessage::SendCmpct(SendCmpct{send_compact: true, version: 8333}),
505514
];
506515

507516
for msg in msgs {

src/util/bip152.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,8 @@ impl BlockTransactions {
362362
#[cfg(test)]
363363
mod test {
364364
use super::*;
365+
use crate::consensus::encode::{deserialize, serialize};
365366
use crate::hashes::hex::FromHex;
366-
use crate::consensus::encode::deserialize;
367367
use crate::{
368368
Block, BlockHash, BlockHeader, OutPoint, Script, Sequence, Transaction, TxIn, TxMerkleNode,
369369
TxOut, Txid, Witness,
@@ -430,4 +430,56 @@ mod test {
430430

431431
assert_eq!(compact, compact_expected);
432432
}
433+
434+
#[test]
435+
fn test_getblocktx_differential_encoding_de_and_serialization() {
436+
let testcases = vec![
437+
// differentially encoded VarInts, indicies
438+
(vec![4, 0, 5, 1, 10], vec![0, 6, 8, 19]),
439+
(vec![1, 0], vec![0]),
440+
(vec![5, 0, 0, 0, 0, 0], vec![0, 1, 2, 3, 4]),
441+
(vec![3, 1, 1, 1], vec![1, 3, 5]),
442+
(vec![3, 0, 0, 253, 0, 1], vec![0, 1, 258]), // .., 253, 0, 1] == VarInt(256)
443+
];
444+
let deser_errorcases = vec![
445+
vec![2, 255, 254, 255, 255, 255, 255, 255, 255, 255, 0], // .., 255, 254, .., 255] == VarInt(u64::MAX-1)
446+
vec![1, 255, 255, 255, 255, 255, 255, 255, 255, 255], // .., 255, 255, .., 255] == VarInt(u64::MAX)
447+
];
448+
for testcase in testcases {
449+
{
450+
// test deserialization
451+
let mut raw: Vec<u8> = [0u8; 32].to_vec();
452+
raw.extend(testcase.0.clone());
453+
let btr: BlockTransactionsRequest = deserialize(&raw.to_vec()).unwrap();
454+
assert_eq!(testcase.1, btr.indexes);
455+
}
456+
{
457+
// test serialization
458+
let raw: Vec<u8> = serialize(&BlockTransactionsRequest {
459+
block_hash: Hash::all_zeros(),
460+
indexes: testcase.1,
461+
});
462+
let mut expected_raw: Vec<u8> = [0u8; 32].to_vec();
463+
expected_raw.extend(testcase.0);
464+
assert_eq!(expected_raw, raw);
465+
}
466+
}
467+
for errorcase in deser_errorcases {
468+
{
469+
// test that we return Err() if deserialization fails (and don't panic)
470+
let mut raw: Vec<u8> = [0u8; 32].to_vec();
471+
raw.extend(errorcase);
472+
assert!(deserialize::<BlockTransactionsRequest>(&raw.to_vec()).is_err());
473+
}
474+
}
475+
}
476+
477+
#[test]
478+
#[should_panic] // 'attempt to add with overflow' in consensus_encode()
479+
fn test_getblocktx_panic_when_encoding_u64_max() {
480+
serialize(&BlockTransactionsRequest {
481+
block_hash: Hash::all_zeros(),
482+
indexes: vec![core::u64::MAX],
483+
});
484+
}
433485
}

0 commit comments

Comments
 (0)