Skip to content

Commit

Permalink
BIP152: Test net msg ser/der and diff encoding
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
0xB10C committed Jul 24, 2022
1 parent cd1aaaf commit ee29910
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 1 deletion.
9 changes: 9 additions & 0 deletions src/network/message.rs
Expand Up @@ -453,6 +453,8 @@ mod test {
use crate::blockdata::script::Script;
use crate::network::message_bloom::{FilterAdd, FilterLoad, BloomFlags};
use crate::MerkleBlock;
use crate::network::message_compact_blocks::{GetBlockTxn, SendCmpct};
use crate::util::bip152::BlockTransactionsRequest;

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


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

for msg in msgs {
Expand Down
54 changes: 53 additions & 1 deletion src/util/bip152.rs
Expand Up @@ -362,8 +362,8 @@ impl BlockTransactions {
#[cfg(test)]
mod test {
use super::*;
use crate::consensus::encode::{deserialize, serialize};
use crate::hashes::hex::FromHex;
use crate::consensus::encode::deserialize;
use crate::{
Block, BlockHash, BlockHeader, OutPoint, Script, Sequence, Transaction, TxIn, TxMerkleNode,
TxOut, Txid, Witness,
Expand Down Expand Up @@ -430,4 +430,56 @@ mod test {

assert_eq!(compact, compact_expected);
}

#[test]
fn test_getblocktx_differential_encoding_de_and_serialization() {
let testcases = vec![
// differentially encoded VarInts, indicies
(vec![4, 0, 5, 1, 10], vec![0, 6, 8, 19]),
(vec![1, 0], vec![0]),
(vec![5, 0, 0, 0, 0, 0], vec![0, 1, 2, 3, 4]),
(vec![3, 1, 1, 1], vec![1, 3, 5]),
(vec![3, 0, 0, 253, 0, 1], vec![0, 1, 258]), // .., 253, 0, 1] == VarInt(256)
];
let deser_errorcases = vec![
vec![2, 255, 254, 255, 255, 255, 255, 255, 255, 255, 0], // .., 255, 254, .., 255] == VarInt(u64::MAX-1)
vec![1, 255, 255, 255, 255, 255, 255, 255, 255, 255], // .., 255, 255, .., 255] == VarInt(u64::MAX)
];
for testcase in testcases {
{
// test deserialization
let mut raw: Vec<u8> = [0u8; 32].to_vec();
raw.extend(testcase.0.clone());
let btr: BlockTransactionsRequest = deserialize(&raw.to_vec()).unwrap();
assert_eq!(testcase.1, btr.indexes);
}
{
// test serialization
let raw: Vec<u8> = serialize(&BlockTransactionsRequest {
block_hash: Hash::all_zeros(),
indexes: testcase.1,
});
let mut expected_raw: Vec<u8> = [0u8; 32].to_vec();
expected_raw.extend(testcase.0);
assert_eq!(expected_raw, raw);
}
}
for errorcase in deser_errorcases {
{
// test that we return Err() if deserialization fails (and don't panic)
let mut raw: Vec<u8> = [0u8; 32].to_vec();
raw.extend(errorcase);
assert!(deserialize::<BlockTransactionsRequest>(&raw.to_vec()).is_err());
}
}
}

#[test]
#[should_panic] // 'attempt to add with overflow' in consensus_encode()
fn test_getblocktx_panic_when_encoding_u64_max() {
serialize(&BlockTransactionsRequest {
block_hash: Hash::all_zeros(),
indexes: vec![core::u64::MAX],
});
}
}

0 comments on commit ee29910

Please sign in to comment.