refactor: Use SpanReader over DataStream
What changed, and why it matters
This is a routine code cleanup in Bitcoin Core that swaps one internal data-reading helper (DataStream) for another (SpanReader) across many files. The commit message explicitly says it does not change behavior, and the diff only shows mechanical replacements with no new logic. There is no security issue visible in the change.
No security action needed. Treat as a normal performance/refactor review; verify SpanReader is behavior-compatible with DataStream for the affected call sites if desired.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors deserialization call sites to use SpanReader instead of DataStream. SpanReader reads directly from a span (a non-owning view of bytes), avoiding a vector copy. The diff is purely mechanical: variable declarations are removed and SpanReader{…} is used inline, or DataStream variables are renamed to SpanReader. No serialization format, validation logic, error handling, or control flow is altered. The change touches benchmarks, core I/O, the kernel API, networking seeds, PSBT, REST/RPC, wallet backup RPC, and many tests/fuzz targets.
Changed components
src/bench/readwriteblock.cppsrc/core_io.cppsrc/kernel/bitcoinkernel.cppsrc/net.cppsrc/psbt.cppsrc/qt/test/wallettests.cppsrc/rest.cppsrc/rpc/blockchain.cppsrc/rpc/txoutproof.cppsrc/test/bloom_tests.cppsrc/test/coins_tests.cppsrc/test/fuzz/block.cppsrc/test/fuzz/deserialize.cppsrc/test/fuzz/script_flags.cppsrc/test/fuzz/transaction.cppsrc/test/fuzz/tx_in.cppsrc/test/fuzz/tx_out.cppsrc/test/fuzz/util.hsrc/test/net_tests.cppsrc/test/netbase_tests.cppsrc/test/sighash_tests.cppsrc/test/transaction_tests.cppsrc/wallet/rpc/backup.cppInspect captured patch +37 / −60
diff --git a/src/bench/readwriteblock.cpp b/src/bench/readwriteblock.cpp
index e1372a26..b8e226c6 100644
--- a/src/bench/readwriteblock.cpp
+++ b/src/bench/readwriteblock.cpp
@@ -21,9 +21,8 @@
static CBlock CreateTestBlock()
{
- DataStream stream{benchmark::data::block413567};
CBlock block;
- stream >> TX_WITH_WITNESS(block);
+ SpanReader{benchmark::data::block413567} >> TX_WITH_WITNESS(block);
return block;
}
diff --git a/src/core_io.cpp b/src/core_io.cpp
index a4b726cd..ec446deb 100644
--- a/src/core_io.cpp
+++ b/src/core_io.cpp
@@ -174,7 +174,7 @@ static bool DecodeTx(CMutableTransaction& tx, const std::vector<unsigned char>&
// Try decoding with extended serialization support, and remember if the result successfully
// consumes the entire input.
if (try_witness) {
- DataStream ssData(tx_data);
+ SpanReader ssData{tx_data};
try {
ssData >> TX_WITH_WITNESS(tx_extended);
if (ssData.empty()) ok_extended = true;
@@ -192,7 +192,7 @@ static bool DecodeTx(CMutableTransaction& tx, const std::vector<unsigned char>&
// Try decoding with legacy serialization, and remember if the result successfully consumes the entire input.
if (try_no_witness) {
- DataStream ssData(tx_data);
+ SpanReader ssData{tx_data};
try {
ssData >> TX_NO_WITNESS(tx_legacy);
if (ssData.empty()) ok_legacy = true;
@@ -239,9 +239,8 @@ bool DecodeHexBlockHeader(CBlockHeader& header, const std::string& hex_header)
if (!IsHex(hex_header)) return false;
const std::vector<unsigned char> header_data{ParseHex(hex_header)};
- DataStream ser_header{header_data};
try {
- ser_header >> header;
+ SpanReader{header_data} >> header;
} catch (const std::exception&) {
return false;
}
@@ -254,9 +253,8 @@ bool DecodeHexBlk(CBlock& block, const std::string& strHexBlk)
return false;
std::vector<unsigned char> blockData(ParseHex(strHexBlk));
- DataStream ssBlock(blockData);
try {
- ssBlock >> TX_WITH_WITNESS(block);
+ SpanReader{blockData} >> TX_WITH_WITNESS(block);
}
catch (const std::exception&) {
return false;
diff --git a/src/kernel/bitcoinkernel.cpp b/src/kernel/bitcoinkernel.cpp
index c8189b62..23aa0ec2 100644
--- a/src/kernel/bitcoinkernel.cpp
+++ b/src/kernel/bitcoinkernel.cpp
@@ -504,7 +504,7 @@ btck_Transaction* btck_transaction_create(const void* raw_transaction, size_t ra
return nullptr;
}
try {
- DataStream stream{std::span{reinterpret_cast<const std::byte*>(raw_transaction), raw_transaction_len}};
+ SpanReader stream{std::span{reinterpret_cast<const std::byte*>(raw_transaction), raw_transaction_len}};
return btck_Transaction::create(std::make_shared<const CTransaction>(deserialize, TX_WITH_WITNESS, stream));
} catch (...) {
return nullptr;
@@ -1093,7 +1093,7 @@ btck_Block* btck_block_create(const void* raw_block, size_t raw_block_length)
}
auto block{std::make_shared<CBlock>()};
- DataStream stream{std::span{reinterpret_cast<const std::byte*>(raw_block), raw_block_length}};
+ SpanReader stream{std::span{reinterpret_cast<const std::byte*>(raw_block), raw_block_length}};
try {
stream >> TX_WITH_WITNESS(*block);
@@ -1344,7 +1344,7 @@ btck_BlockHeader* btck_block_header_create(const void* raw_block_header, size_t
return nullptr;
}
auto header{std::make_unique<CBlockHeader>()};
- DataStream stream{std::span{reinterpret_cast<const std::byte*>(raw_block_header), raw_block_header_len}};
+ SpanReader stream{std::span{reinterpret_cast<const std::byte*>(raw_block_header), raw_block_header_len}};
try {
stream >> *header;
diff --git a/src/net.cpp b/src/net.cpp
index 3ed7fd27..f99a76f2 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -201,7 +201,7 @@ static std::vector<CAddress> ConvertSeeds(const std::vector<uint8_t> &vSeedsIn)
const auto one_week{7 * 24h};
std::vector<CAddress> vSeedsOut;
FastRandomContext rng;
- ParamsStream s{DataStream{vSeedsIn}, CAddress::V2_NETWORK};
+ ParamsStream s{SpanReader{vSeedsIn}, CAddress::V2_NETWORK};
while (!s.empty()) {
CService endpoint;
s >> endpoint;
diff --git a/src/psbt.cpp b/src/psbt.cpp
index a1eafbc0..4ee5f5bd 100644
--- a/src/psbt.cpp
+++ b/src/psbt.cpp
@@ -617,7 +617,7 @@ bool DecodeBase64PSBT(PartiallySignedTransaction& psbt, const std::string& base6
bool DecodeRawPSBT(PartiallySignedTransaction& psbt, std::span<const std::byte> tx_data, std::string& error)
{
- DataStream ss_data{tx_data};
+ SpanReader ss_data{tx_data};
try {
ss_data >> psbt;
if (!ss_data.empty()) {
diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp
index b62b2a3b..1350b11e 100644
--- a/src/qt/test/wallettests.cpp
+++ b/src/qt/test/wallettests.cpp
@@ -365,7 +365,7 @@ void TestGUI(interfaces::Node& node, const std::shared_ptr<CWallet>& wallet)
std::vector<std::string> requests = walletModel.wallet().getAddressReceiveRequests();
QCOMPARE(requests.size(), size_t{1});
RecentRequestEntry entry;
- DataStream{MakeUCharSpan(requests[0])} >> entry;
+ SpanReader{MakeByteSpan(requests[0])} >> entry;
QCOMPARE(entry.nVersion, int{1});
QCOMPARE(entry.id, int64_t{1});
QVERIFY(entry.date.isValid());
diff --git a/src/rest.cpp b/src/rest.cpp
index b91b229a..9d73c1e6 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -451,8 +451,7 @@ static bool rest_block(const std::any& context,
case RESTResponseFormat::JSON: {
if (tx_verbosity) {
CBlock block{};
- DataStream block_stream{*block_data};
- block_stream >> TX_WITH_WITNESS(block);
+ SpanReader{*block_data} >> TX_WITH_WITNESS(block);
UniValue objBlock = blockToJSON(chainman.m_blockman, block, *tip, *pblockindex, *tx_verbosity, chainman.GetConsensus().powLimit);
std::string strJSON = objBlock.write() + "\n";
req->WriteHeader("Content-Type", "application/json");
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index a883570f..d5c99876 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -832,9 +832,8 @@ static RPCHelpMan getblock()
return HexStr(block_data);
}
- DataStream block_stream{block_data};
CBlock block{};
- block_stream >> TX_WITH_WITNESS(block);
+ SpanReader{block_data} >> TX_WITH_WITNESS(block);
TxVerbosity tx_verbosity;
if (verbosity == 1) {
diff --git a/src/rpc/txoutproof.cpp b/src/rpc/txoutproof.cpp
index 7e8e3bdb..89611a0c 100644
--- a/src/rpc/txoutproof.cpp
+++ b/src/rpc/txoutproof.cpp
@@ -144,9 +144,8 @@ static RPCHelpMan verifytxoutproof()
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- DataStream ssMB{ParseHexV(request.params[0], "proof")};
CMerkleBlock merkleBlock;
- ssMB >> merkleBlock;
+ SpanReader{ParseHexV(request.params[0], "proof")} >> merkleBlock;
UniValue res(UniValue::VARR);
diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp
index 938aa233..8e02cfd0 100644
--- a/src/test/bloom_tests.cpp
+++ b/src/test/bloom_tests.cpp
@@ -110,7 +110,7 @@ BOOST_AUTO_TEST_CASE(bloom_match)
// and one which spends it (e2769b09e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436)
unsigned char ch[] = {0x01, 0x00, 0x00, 0x00, 0x01, 0x6b, 0xff, 0x7f, 0xcd, 0x4f, 0x85, 0x65, 0xef, 0x40, 0x6d, 0xd5, 0xd6, 0x3d, 0x4f, 0xf9, 0x4f, 0x31, 0x8f, 0xe8, 0x20, 0x27, 0xfd, 0x4d, 0xc4, 0x51, 0xb0, 0x44, 0x74, 0x01, 0x9f, 0x74, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x49, 0x30, 0x46, 0x02, 0x21, 0x00, 0xda, 0x0d, 0xc6, 0xae, 0xce, 0xfe, 0x1e, 0x06, 0xef, 0xdf, 0x05, 0x77, 0x37, 0x57, 0xde, 0xb1, 0x68, 0x82, 0x09, 0x30, 0xe3, 0xb0, 0xd0, 0x3f, 0x46, 0xf5, 0xfc, 0xf1, 0x50, 0xbf, 0x99, 0x0c, 0x02, 0x21, 0x00, 0xd2, 0x5b, 0x5c, 0x87, 0x04, 0x00, 0x76, 0xe4, 0xf2, 0x53, 0xf8, 0x26, 0x2e, 0x76, 0x3e, 0x2d, 0xd5, 0x1e, 0x7f, 0xf0, 0xbe, 0x15, 0x77, 0x27, 0xc4, 0xbc, 0x42, 0x80, 0x7f, 0x17, 0xbd, 0x39, 0x01, 0x41, 0x04, 0xe6, 0xc2, 0x6e, 0xf6, 0x7d, 0xc6, 0x10, 0xd2, 0xcd, 0x19, 0x24, 0x84, 0x78, 0x9a, 0x6c, 0xf9, 0xae, 0xa9, 0x93, 0x0b, 0x94, 0x4b, 0x7e, 0x2d, 0xb5, 0x34, 0x2b, 0x9d, 0x9e, 0x5b, 0x9f, 0xf7, 0x9a, 0xff, 0x9a, 0x2e, 0xe1, 0x97, 0x8d, 0xd7, 0xfd, 0x01, 0xdf, 0xc5, 0x22, 0xee, 0x02, 0x28, 0x3d, 0x3b, 0x06, 0xa9, 0xd0, 0x3a, 0xcf, 0x80, 0x96, 0x96, 0x8d, 0x7d, 0xbb, 0x0f, 0x91, 0x78, 0xff, 0xff, 0xff, 0xff, 0x02, 0x8b, 0xa7, 0x94, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xba, 0xde, 0xec, 0xfd, 0xef, 0x05, 0x07, 0x24, 0x7f, 0xc8, 0xf7, 0x42, 0x41, 0xd7, 0x3b, 0xc0, 0x39, 0x97, 0x2d, 0x7b, 0x88, 0xac, 0x40, 0x94, 0xa8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xc1, 0x09, 0x32, 0x48, 0x3f, 0xec, 0x93, 0xed, 0x51, 0xf5, 0xfe, 0x95, 0xe7, 0x25, 0x59, 0xf2, 0xcc, 0x70, 0x43, 0xf9, 0x88, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00};
std::vector<unsigned char> vch(ch, ch + sizeof(ch) -1);
- DataStream spendStream{vch};
+ SpanReader spendStream{vch};
CTransaction spendingTx(deserialize, TX_WITH_WITNESS, spendStream);
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp
index 4d6ee661..8c0756d8 100644
--- a/src/test/coins_tests.cpp
+++ b/src/test/coins_tests.cpp
@@ -517,37 +517,33 @@ BOOST_FIXTURE_TEST_CASE(updatecoins_simulation_test, UpdateTest)
BOOST_AUTO_TEST_CASE(ccoins_serialization)
{
// Good example
- DataStream ss1{"97f23c835800816115944e077fe7c803cfa57f29b36bf87c1d35"_hex};
Coin cc1;
- ss1 >> cc1;
+ SpanReader{"97f23c835800816115944e077fe7c803cfa57f29b36bf87c1d35"_hex} >> cc1;
BOOST_CHECK_EQUAL(cc1.fCoinBase, false);
BOOST_CHECK_EQUAL(cc1.nHeight, 203998U);
BOOST_CHECK_EQUAL(cc1.out.nValue, CAmount{60000000000});
BOOST_CHECK_EQUAL(HexStr(cc1.out.scriptPubKey), HexStr(GetScriptForDestination(PKHash(uint160("816115944e077fe7c803cfa57f29b36bf87c1d35"_hex_u8)))));
// Good example
- DataStream ss2{"8ddf77bbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa4"_hex};
Coin cc2;
- ss2 >> cc2;
+ SpanReader{"8ddf77bbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa4"_hex} >> cc2;
BOOST_CHECK_EQUAL(cc2.fCoinBase, true);
BOOST_CHECK_EQUAL(cc2.nHeight, 120891U);
BOOST_CHECK_EQUAL(cc2.out.nValue, 110397);
BOOST_CHECK_EQUAL(HexStr(cc2.out.scriptPubKey), HexStr(GetScriptForDestination(PKHash(uint160("8c988f1a4a4de2161e0f50aac7f17e7f9555caa4"_hex_u8)))));
// Smallest possible example
- DataStream ss3{"000006"_hex};
Coin cc3;
- ss3 >> cc3;
+ SpanReader{"000006"_hex} >> cc3;
BOOST_CHECK_EQUAL(cc3.fCoinBase, false);
BOOST_CHECK_EQUAL(cc3.nHeight, 0U);
BOOST_CHECK_EQUAL(cc3.out.nValue, 0);
BOOST_CHECK_EQUAL(cc3.out.scriptPubKey.size(), 0U);
// scriptPubKey that ends beyond the end of the stream
- DataStream ss4{"000007"_hex};
try {
Coin cc4;
- ss4 >> cc4;
+ SpanReader{"000007"_hex} >> cc4;
BOOST_CHECK_MESSAGE(false, "We should have thrown");
} catch (const std::ios_base::failure&) {
}
@@ -557,10 +553,9 @@ BOOST_AUTO_TEST_CASE(ccoins_serialization)
uint64_t x = 3000000000ULL;
tmp << VARINT(x);
BOOST_CHECK_EQUAL(HexStr(tmp), "8a95c0bb00");
- DataStream ss5{"00008a95c0bb00"_hex};
try {
Coin cc5;
- ss5 >> cc5;
+ SpanReader{"00008a95c0bb00"_hex} >> cc5;
BOOST_CHECK_MESSAGE(false, "We should have thrown");
} catch (const std::ios_base::failure&) {
}
diff --git a/src/test/fuzz/block.cpp b/src/test/fuzz/block.cpp
index 43e3df36..7b874429 100644
--- a/src/test/fuzz/block.cpp
+++ b/src/test/fuzz/block.cpp
@@ -24,10 +24,9 @@ void initialize_block()
FUZZ_TARGET(block, .init = initialize_block)
{
- DataStream ds{buffer};
CBlock block;
try {
- ds >> TX_WITH_WITNESS(block);
+ SpanReader{buffer} >> TX_WITH_WITNESS(block);
} catch (const std::ios_base::failure&) {
return;
}
diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp
index 97985ef0..70cad07d 100644
--- a/src/test/fuzz/deserialize.cpp
+++ b/src/test/fuzz/deserialize.cpp
@@ -81,9 +81,8 @@ T Deserialize(DataStream&& ds, const P& params)
template <typename T, typename P>
void DeserializeFromFuzzingInput(FuzzBufferType buffer, T&& obj, const P& params)
{
- DataStream ds{buffer};
try {
- ds >> params(obj);
+ SpanReader{buffer} >> params(obj);
} catch (const std::ios_base::failure&) {
throw invalid_fuzzing_input_exception();
}
@@ -109,9 +108,8 @@ T Deserialize(DataStream ds)
template <typename T>
void DeserializeFromFuzzingInput(FuzzBufferType buffer, T&& obj)
{
- DataStream ds{buffer};
try {
- ds >> obj;
+ SpanReader{buffer} >> obj;
} catch (const std::ios_base::failure&) {
throw invalid_fuzzing_input_exception();
}
diff --git a/src/test/fuzz/script_flags.cpp b/src/test/fuzz/script_flags.cpp
index 310f0e86..3ab58800 100644
--- a/src/test/fuzz/script_flags.cpp
+++ b/src/test/fuzz/script_flags.cpp
@@ -15,7 +15,7 @@
#include <utility>
#include <vector>
-static DataStream& operator>>(DataStream& ds, script_verify_flags& f)
+static SpanReader& operator>>(SpanReader& ds, script_verify_flags& f)
{
script_verify_flags::value_type n{0};
ds >> n;
@@ -27,7 +27,7 @@ static DataStream& operator>>(DataStream& ds, script_verify_flags& f)
FUZZ_TARGET(script_flags)
{
if (buffer.size() > 100'000) return;
- DataStream ds{buffer};
+ SpanReader ds{buffer};
try {
const CTransaction tx(deserialize, TX_WITH_WITNESS, ds);
diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp
index da915713..8f9c9426 100644
--- a/src/test/fuzz/transaction.cpp
+++ b/src/test/fuzz/transaction.cpp
@@ -30,7 +30,7 @@ void initialize_transaction()
FUZZ_TARGET(transaction, .init = initialize_transaction)
{
SeedRandomStateForTest(SeedRand::ZEROS);
- DataStream ds{buffer};
+ SpanReader ds{buffer};
bool valid_tx = true;
const CTransaction tx = [&] {
try {
@@ -41,10 +41,9 @@ FUZZ_TARGET(transaction, .init = initialize_transaction)
}
}();
bool valid_mutable_tx = true;
- DataStream ds_mtx{buffer};
CMutableTransaction mutable_tx;
try {
- ds_mtx >> TX_WITH_WITNESS(mutable_tx);
+ SpanReader{buffer} >> TX_WITH_WITNESS(mutable_tx);
} catch (const std::ios_base::failure&) {
valid_mutable_tx = false;
}
diff --git a/src/test/fuzz/tx_in.cpp b/src/test/fuzz/tx_in.cpp
index 932c0e18..10618d60 100644
--- a/src/test/fuzz/tx_in.cpp
+++ b/src/test/fuzz/tx_in.cpp
@@ -13,10 +13,9 @@
FUZZ_TARGET(tx_in)
{
- DataStream ds{buffer};
CTxIn tx_in;
try {
- ds >> tx_in;
+ SpanReader{buffer} >> tx_in;
} catch (const std::ios_base::failure&) {
return;
}
diff --git a/src/test/fuzz/tx_out.cpp b/src/test/fuzz/tx_out.cpp
index 392300ce..ce39d14f 100644
--- a/src/test/fuzz/tx_out.cpp
+++ b/src/test/fuzz/tx_out.cpp
@@ -12,10 +12,9 @@
FUZZ_TARGET(tx_out)
{
- DataStream ds{buffer};
CTxOut tx_out;
try {
- ds >> tx_out;
+ SpanReader{buffer} >> tx_out;
} catch (const std::ios_base::failure&) {
return;
}
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index 3947ee12..ccc9e72f 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -105,7 +105,7 @@ template <typename T, typename P>
[[nodiscard]] std::optional<T> ConsumeDeserializable(FuzzedDataProvider& fuzzed_data_provider, const P& params, const std::optional<size_t>& max_length = std::nullopt) noexcept
{
const std::vector<uint8_t> buffer{ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length)};
- DataStream ds{buffer};
+ SpanReader ds{buffer};
T obj;
try {
ds >> params(obj);
@@ -119,7 +119,7 @@ template <typename T>
[[nodiscard]] inline std::optional<T> ConsumeDeserializable(FuzzedDataProvider& fuzzed_data_provider, const std::optional<size_t>& max_length = std::nullopt) noexcept
{
const std::vector<uint8_t> buffer = ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length);
- DataStream ds{buffer};
+ SpanReader ds{buffer};
T obj;
try {
ds >> obj;
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp
index aea29169..136728a0 100644
--- a/src/test/net_tests.cpp
+++ b/src/test/net_tests.cpp
@@ -872,10 +872,9 @@ BOOST_AUTO_TEST_CASE(initial_advertise_from_version_message)
std::span<const unsigned char> data,
bool is_incoming) -> void {
if (!is_incoming && msg_type == "addr") {
- DataStream s{data};
std::vector<CAddress> addresses;
- s >> CAddress::V1_NETWORK(addresses);
+ SpanReader{data} >> CAddress::V1_NETWORK(addresses);
for (const auto& addr : addresses) {
if (addr == expected) {
diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp
index 722ba2eb..f765c57f 100644
--- a/src/test/netbase_tests.cpp
+++ b/src/test/netbase_tests.cpp
@@ -575,10 +575,9 @@ BOOST_AUTO_TEST_CASE(caddress_serialize_v1)
BOOST_AUTO_TEST_CASE(caddress_unserialize_v1)
{
- DataStream s{ParseHex(stream_addrv1_hex)};
std::vector<CAddress> addresses_unserialized;
- s >> CAddress::V1_NETWORK(addresses_unserialized);
+ SpanReader{ParseHex(stream_addrv1_hex)} >> CAddress::V1_NETWORK(addresses_unserialized);
BOOST_CHECK(fixture_addresses == addresses_unserialized);
}
@@ -592,10 +591,9 @@ BOOST_AUTO_TEST_CASE(caddress_serialize_v2)
BOOST_AUTO_TEST_CASE(caddress_unserialize_v2)
{
- DataStream s{ParseHex(stream_addrv2_hex)};
std::vector<CAddress> addresses_unserialized;
- s >> CAddress::V2_NETWORK(addresses_unserialized);
+ SpanReader{ParseHex(stream_addrv2_hex)} >> CAddress::V2_NETWORK(addresses_unserialized);
BOOST_CHECK(fixture_addresses == addresses_unserialized);
}
diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp
index 42728216..5d65c35a 100644
--- a/src/test/sighash_tests.cpp
+++ b/src/test/sighash_tests.cpp
@@ -189,8 +189,7 @@ BOOST_AUTO_TEST_CASE(sighash_from_data)
nHashType = test[3].getInt<int>();
sigHashHex = test[4].get_str();
- DataStream stream(ParseHex(raw_tx));
- stream >> TX_WITH_WITNESS(tx);
+ SpanReader{ParseHex(raw_tx)} >> TX_WITH_WITNESS(tx);
TxValidationState state;
BOOST_CHECK_MESSAGE(CheckTransaction(*tx, state), strTest);
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 3919f226..d0be15a0 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -377,9 +377,8 @@ BOOST_AUTO_TEST_CASE(basic_transaction_tests)
// Random real transaction (e2769b09e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436)
unsigned char ch[] = {0x01, 0x00, 0x00, 0x00, 0x01, 0x6b, 0xff, 0x7f, 0xcd, 0x4f, 0x85, 0x65, 0xef, 0x40, 0x6d, 0xd5, 0xd6, 0x3d, 0x4f, 0xf9, 0x4f, 0x31, 0x8f, 0xe8, 0x20, 0x27, 0xfd, 0x4d, 0xc4, 0x51, 0xb0, 0x44, 0x74, 0x01, 0x9f, 0x74, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x49, 0x30, 0x46, 0x02, 0x21, 0x00, 0xda, 0x0d, 0xc6, 0xae, 0xce, 0xfe, 0x1e, 0x06, 0xef, 0xdf, 0x05, 0x77, 0x37, 0x57, 0xde, 0xb1, 0x68, 0x82, 0x09, 0x30, 0xe3, 0xb0, 0xd0, 0x3f, 0x46, 0xf5, 0xfc, 0xf1, 0x50, 0xbf, 0x99, 0x0c, 0x02, 0x21, 0x00, 0xd2, 0x5b, 0x5c, 0x87, 0x04, 0x00, 0x76, 0xe4, 0xf2, 0x53, 0xf8, 0x26, 0x2e, 0x76, 0x3e, 0x2d, 0xd5, 0x1e, 0x7f, 0xf0, 0xbe, 0x15, 0x77, 0x27, 0xc4, 0xbc, 0x42, 0x80, 0x7f, 0x17, 0xbd, 0x39, 0x01, 0x41, 0x04, 0xe6, 0xc2, 0x6e, 0xf6, 0x7d, 0xc6, 0x10, 0xd2, 0xcd, 0x19, 0x24, 0x84, 0x78, 0x9a, 0x6c, 0xf9, 0xae, 0xa9, 0x93, 0x0b, 0x94, 0x4b, 0x7e, 0x2d, 0xb5, 0x34, 0x2b, 0x9d, 0x9e, 0x5b, 0x9f, 0xf7, 0x9a, 0xff, 0x9a, 0x2e, 0xe1, 0x97, 0x8d, 0xd7, 0xfd, 0x01, 0xdf, 0xc5, 0x22, 0xee, 0x02, 0x28, 0x3d, 0x3b, 0x06, 0xa9, 0xd0, 0x3a, 0xcf, 0x80, 0x96, 0x96, 0x8d, 0x7d, 0xbb, 0x0f, 0x91, 0x78, 0xff, 0xff, 0xff, 0xff, 0x02, 0x8b, 0xa7, 0x94, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xba, 0xde, 0xec, 0xfd, 0xef, 0x05, 0x07, 0x24, 0x7f, 0xc8, 0xf7, 0x42, 0x41, 0xd7, 0x3b, 0xc0, 0x39, 0x97, 0x2d, 0x7b, 0x88, 0xac, 0x40, 0x94, 0xa8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xc1, 0x09, 0x32, 0x48, 0x3f, 0xec, 0x93, 0xed, 0x51, 0xf5, 0xfe, 0x95, 0xe7, 0x25, 0x59, 0xf2, 0xcc, 0x70, 0x43, 0xf9, 0x88, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00};
std::vector<unsigned char> vch(ch, ch + sizeof(ch) -1);
- DataStream stream(vch);
CMutableTransaction tx;
- stream >> TX_WITH_WITNESS(tx);
+ SpanReader{vch} >> TX_WITH_WITNESS(tx);
TxValidationState state;
BOOST_CHECK_MESSAGE(CheckTransaction(CTransaction(tx), state) && state.IsValid(), "Simple deserialized transaction should be valid.");
diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp
index 2aa1e9f7..9b70f5bb 100644
--- a/src/wallet/rpc/backup.cpp
+++ b/src/wallet/rpc/backup.cpp
@@ -57,9 +57,8 @@ RPCHelpMan importprunedfunds()
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input.");
}
- DataStream ssMB{ParseHexV(request.params[1], "proof")};
CMerkleBlock merkleBlock;
- ssMB >> merkleBlock;
+ SpanReader{ParseHexV(request.params[1], "proof")} >> merkleBlock;
//Search partial merkle tree in proof for our transaction and index in valid block
std::vector<Txid> vMatch;
Why this scored 14/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.