Skip to content

Commit

Permalink
Merge pull request #52 from hax0kartik/cmpctblocks
Browse files Browse the repository at this point in the history
Add target for compact block messages
  • Loading branch information
brunoerg authored Jul 1, 2024
2 parents 8533548 + 603cc2a commit 1b667c9
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ INCPATHS:= $(foreach dir,$(INCLUDES),-I$(dir))
LIBPATHS:= $(foreach lib,$(LIB_DIR),-L$(lib))
CXXFLAGS:= -O3 -g0 -Wall -fsanitize=fuzzer -DHAVE_GMTIME_R=1 -std=c++20 -march=native $(INCPATHS)
ORIGLDFLAGS := $(LDFLAGS) # need to save a copy of ld flags as these get modified below
LDFLAGS := $(LIBPATHS) -lbtcd_wrapper -lrust_bitcoin_lib -lbitcoin_common -lbitcoin_util -lbitcoinkernel -lsecp256k1 -lpthread -ldl
LDFLAGS := $(LIBPATHS) -lbtcd_wrapper -lrust_bitcoin_lib -lbitcoin_node -lbitcoin_common -lbitcoin_util -lbitcoinkernel -lunivalue -lsecp256k1 -lpthread -ldl

ifeq ($(UNAME_S),Darwin)
LDFLAGS += -framework CoreFoundation -Wl,-ld_classic
Expand Down
3 changes: 3 additions & 0 deletions fuzzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "targets/psbt.h"
#include "targets/script.h"
#include "targets/addrv2.h"
#include "targets/cmpctblocks.h"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
FuzzedDataProvider provider(data, size);
Expand All @@ -37,6 +38,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
Script(provider);
} else if (target == "addrv2") {
Addrv2(provider);
} else if (target == "cmpctblocks") {
CmpctBlocks(provider);
}

return 0; // Values other than 0 and -1 are reserved for future use.
Expand Down
1 change: 1 addition & 0 deletions rust_bitcoin_lib/rust_bitcoin_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ extern char* rust_miniscript_from_str_check_key(const char* miniscript_str);
extern char* rust_bitcoin_des_block(const uint8_t *data, size_t len);
extern char* rust_bitcoin_prefilledtransaction(const uint8_t *data, size_t len);
extern bool rust_bitcoin_addrv2(uint8_t *data, size_t len, uint64_t *count);
extern char* rust_bitcoin_cmpctblocks(uint8_t *data, size_t len);
20 changes: 20 additions & 0 deletions rust_bitcoin_lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::str::FromStr;
use std::str::Utf8Error;

use bitcoin::bip152::PrefilledTransaction;
use bitcoin::bip152::HeaderAndShortIds;
use bitcoin::consensus::deserialize_partial;
use bitcoin::consensus::encode;
use bitcoin::Block;
Expand Down Expand Up @@ -135,6 +136,25 @@ pub unsafe extern "C" fn rust_bitcoin_addrv2(data: *const u8, len: usize, actual
}
}

#[no_mangle]
pub unsafe extern "C" fn rust_bitcoin_cmpctblocks(data: *const u8, len: usize) -> i32 {
// Safety: Ensure that the data pointer is valid for the given length
let data_slice = slice::from_raw_parts(data, len);

let res = deserialize_partial::<HeaderAndShortIds>(data_slice);

match res {
Ok(block) => return (block.0.prefilled_txs.len() + block.0.short_ids.len()).try_into().unwrap(),
Err(err) => {
if err.to_string().starts_with("unsupported segwit version") {
return -2;
}

return -1;
}
}
}

#[no_mangle]
pub unsafe extern "C" fn rust_miniscript_from_str_check_key(input: *const c_char) -> *mut c_char {
let Ok(desc) = c_str_to_str(input) else {
Expand Down
35 changes: 35 additions & 0 deletions targets/cmpctblocks.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include <fuzzer/FuzzedDataProvider.h>
#include <string>
#include <iostream>

#include "cmpctblocks.h"
#include "bitcoin/src/blockencodings.h"
#include "bitcoin/src/streams.h"

extern "C" int rust_bitcoin_cmpctblocks(uint8_t *data, size_t len);

int CmpctBlocksCore(Span<const uint8_t> buffer)
{
DataStream ds{buffer};
CBlockHeaderAndShortTxIDs block_header_and_short_txids;
try {
ds >> block_header_and_short_txids;
} catch (const std::ios_base::failure& e) {
if (std::string(e.what()).find("Superfluous witness record") != std::string::npos)
return -2;
return -1;
}
return block_header_and_short_txids.BlockTxCount();
}

void CmpctBlocks(FuzzedDataProvider& provider)
{
std::vector<uint8_t> buffer{provider.ConsumeRemainingBytes<uint8_t>()};
int core{CmpctBlocksCore(buffer)};
int rust_bitcoin{rust_bitcoin_cmpctblocks(buffer.data(), buffer.size())};

if (core == -2 || rust_bitcoin == -2)
return;

assert(core == rust_bitcoin);
}
7 changes: 7 additions & 0 deletions targets/cmpctblocks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef CMPCT_BLOCKS_H
#define CMPCT_BLOCKS_H

#include <fuzzer/FuzzedDataProvider.h>

void CmpctBlocks(FuzzedDataProvider& provider);
#endif

0 comments on commit 1b667c9

Please sign in to comment.