0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-09 10:43:19 -05:00

Merge bitcoin/bitcoin#23438: refactor: Use spans of std::byte in serialize

fa5d2e678c Remove unused char serialize (MarcoFalke)
fa24493d63 Use spans of std::byte in serialize (MarcoFalke)
fa65bbf217 span: Add BytePtr helper (MarcoFalke)

Pull request description:

  This changes the serialize code (`.read()` and `.write()` functions) to take a `Span` instead of a pointer and size. This is a breaking change for the serialize interface, so at no additional cost we can also switch to `std::byte` (instead of using `char`).

  The benefits of using `Span`:
  * Less verbose and less fragile code when passing an already existing `Span`(-like) object to or from serialization

  The benefits of using `std::byte`:
  * `std::byte` can't accidentally be mistaken for an integer

  The goal here is to only change serialize to use spans of `std::byte`. If needed, `AsBytes`,  `MakeUCharSpan`, ... can be used (temporarily) to pass spans of the right type.

  Other changes that are included here:

  * [#22167](https://github.com/bitcoin/bitcoin/pull/22167) (refactor: Remove char serialize by MarcoFalke)
  * [#21906](https://github.com/bitcoin/bitcoin/pull/21906) (Preserve const in cast on CTransactionSignatureSerializer by promag)

ACKs for top commit:
  laanwj:
    Concept and code review ACK fa5d2e678c
  sipa:
    re-utACK fa5d2e678c

Tree-SHA512: 08ee9eced5fb777cedae593b11e33660bed9a3e1711a7451a87b835089a96c99ce0632918bb4666a4e859c4d020f88fb50f2dd734216b0c3d1a9a704967ece6f
This commit is contained in:
laanwj 2022-01-27 18:53:31 +01:00
commit 196b459920
No known key found for this signature in database
GPG key ID: 1E4AED62986CD25D
29 changed files with 208 additions and 199 deletions

View file

@ -17,8 +17,8 @@
static void DeserializeBlockTest(benchmark::Bench& bench) static void DeserializeBlockTest(benchmark::Bench& bench)
{ {
CDataStream stream(benchmark::data::block413567, SER_NETWORK, PROTOCOL_VERSION); CDataStream stream(benchmark::data::block413567, SER_NETWORK, PROTOCOL_VERSION);
char a = '\0'; std::byte a{0};
stream.write(&a, 1); // Prevent compaction stream.write({&a, 1}); // Prevent compaction
bench.unit("block").run([&] { bench.unit("block").run([&] {
CBlock block; CBlock block;
@ -31,8 +31,8 @@ static void DeserializeBlockTest(benchmark::Bench& bench)
static void DeserializeAndCheckBlockTest(benchmark::Bench& bench) static void DeserializeAndCheckBlockTest(benchmark::Bench& bench)
{ {
CDataStream stream(benchmark::data::block413567, SER_NETWORK, PROTOCOL_VERSION); CDataStream stream(benchmark::data::block413567, SER_NETWORK, PROTOCOL_VERSION);
char a = '\0'; std::byte a{0};
stream.write(&a, 1); // Prevent compaction stream.write({&a, 1}); // Prevent compaction
ArgsManager bench_args; ArgsManager bench_args;
const auto chainParams = CreateChainParams(bench_args, CBaseChainParams::MAIN); const auto chainParams = CreateChainParams(bench_args, CBaseChainParams::MAIN);

View file

@ -23,8 +23,8 @@ struct TestBlockAndIndex {
TestBlockAndIndex() TestBlockAndIndex()
{ {
CDataStream stream(benchmark::data::block413567, SER_NETWORK, PROTOCOL_VERSION); CDataStream stream(benchmark::data::block413567, SER_NETWORK, PROTOCOL_VERSION);
char a = '\0'; std::byte a{0};
stream.write(&a, 1); // Prevent compaction stream.write({&a, 1}); // Prevent compaction
stream >> block; stream >> block;

View file

@ -62,7 +62,7 @@ void CBloomFilter::insert(const COutPoint& outpoint)
{ {
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
stream << outpoint; stream << outpoint;
insert(stream); insert(MakeUCharSpan(stream));
} }
bool CBloomFilter::contains(Span<const unsigned char> vKey) const bool CBloomFilter::contains(Span<const unsigned char> vKey) const
@ -83,7 +83,7 @@ bool CBloomFilter::contains(const COutPoint& outpoint) const
{ {
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
stream << outpoint; stream << outpoint;
return contains(stream); return contains(MakeUCharSpan(stream));
} }
bool CBloomFilter::IsWithinSizeConstraints() const bool CBloomFilter::IsWithinSizeConstraints() const

View file

@ -147,7 +147,7 @@ public:
template<typename K> bool GetKey(K& key) { template<typename K> bool GetKey(K& key) {
leveldb::Slice slKey = piter->key(); leveldb::Slice slKey = piter->key();
try { try {
CDataStream ssKey(MakeUCharSpan(slKey), SER_DISK, CLIENT_VERSION); CDataStream ssKey{MakeByteSpan(slKey), SER_DISK, CLIENT_VERSION};
ssKey >> key; ssKey >> key;
} catch (const std::exception&) { } catch (const std::exception&) {
return false; return false;
@ -158,7 +158,7 @@ public:
template<typename V> bool GetValue(V& value) { template<typename V> bool GetValue(V& value) {
leveldb::Slice slValue = piter->value(); leveldb::Slice slValue = piter->value();
try { try {
CDataStream ssValue(MakeUCharSpan(slValue), SER_DISK, CLIENT_VERSION); CDataStream ssValue{MakeByteSpan(slValue), SER_DISK, CLIENT_VERSION};
ssValue.Xor(dbwrapper_private::GetObfuscateKey(parent)); ssValue.Xor(dbwrapper_private::GetObfuscateKey(parent));
ssValue >> value; ssValue >> value;
} catch (const std::exception&) { } catch (const std::exception&) {
@ -244,7 +244,7 @@ public:
dbwrapper_private::HandleError(status); dbwrapper_private::HandleError(status);
} }
try { try {
CDataStream ssValue(MakeUCharSpan(strValue), SER_DISK, CLIENT_VERSION); CDataStream ssValue{MakeByteSpan(strValue), SER_DISK, CLIENT_VERSION};
ssValue.Xor(obfuscate_key); ssValue.Xor(obfuscate_key);
ssValue >> value; ssValue >> value;
} catch (const std::exception&) { } catch (const std::exception&) {

View file

@ -111,8 +111,9 @@ public:
int GetType() const { return nType; } int GetType() const { return nType; }
int GetVersion() const { return nVersion; } int GetVersion() const { return nVersion; }
void write(const char *pch, size_t size) { void write(Span<const std::byte> src)
ctx.Write((const unsigned char*)pch, size); {
ctx.Write(UCharCast(src.data()), src.size());
} }
/** Compute the double-SHA256 hash of all data written to this object. /** Compute the double-SHA256 hash of all data written to this object.
@ -162,18 +163,18 @@ private:
public: public:
explicit CHashVerifier(Source* source_) : CHashWriter(source_->GetType(), source_->GetVersion()), source(source_) {} explicit CHashVerifier(Source* source_) : CHashWriter(source_->GetType(), source_->GetVersion()), source(source_) {}
void read(char* pch, size_t nSize) void read(Span<std::byte> dst)
{ {
source->read(pch, nSize); source->read(dst);
this->write(pch, nSize); this->write(dst);
} }
void ignore(size_t nSize) void ignore(size_t nSize)
{ {
char data[1024]; std::byte data[1024];
while (nSize > 0) { while (nSize > 0) {
size_t now = std::min<size_t>(nSize, 1024); size_t now = std::min<size_t>(nSize, 1024);
read(data, now); read({data, now});
nSize -= now; nSize -= now;
} }
} }

View file

@ -3091,11 +3091,11 @@ void CaptureMessage(const CAddress& addr, const std::string& msg_type, const Spa
CAutoFile f(fsbridge::fopen(path, "ab"), SER_DISK, CLIENT_VERSION); CAutoFile f(fsbridge::fopen(path, "ab"), SER_DISK, CLIENT_VERSION);
ser_writedata64(f, now.count()); ser_writedata64(f, now.count());
f.write(msg_type.data(), msg_type.length()); f.write(MakeByteSpan(msg_type));
for (auto i = msg_type.length(); i < CMessageHeader::COMMAND_SIZE; ++i) { for (auto i = msg_type.length(); i < CMessageHeader::COMMAND_SIZE; ++i) {
f << uint8_t{'\0'}; f << uint8_t{'\0'};
} }
uint32_t size = data.size(); uint32_t size = data.size();
ser_writedata32(f, size); ser_writedata32(f, size);
f.write((const char*)data.data(), data.size()); f.write(AsBytes(data));
} }

View file

@ -813,7 +813,7 @@ bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, c
} }
block.resize(blk_size); // Zeroing of memory is intentional here block.resize(blk_size); // Zeroing of memory is intentional here
filein.read((char*)block.data(), blk_size); filein.read(MakeWritableByteSpan(block));
} catch (const std::exception& e) { } catch (const std::exception& e) {
return error("%s: Read from block file failed: %s for %s", __func__, e.what(), pos.ToString()); return error("%s: Read from block file failed: %s for %s", __func__, e.what(), pos.ToString());
} }

View file

@ -399,7 +399,7 @@ bool DecodeBase64PSBT(PartiallySignedTransaction& psbt, const std::string& base6
bool DecodeRawPSBT(PartiallySignedTransaction& psbt, const std::string& tx_data, std::string& error) bool DecodeRawPSBT(PartiallySignedTransaction& psbt, const std::string& tx_data, std::string& error)
{ {
CDataStream ss_data(MakeUCharSpan(tx_data), SER_NETWORK, PROTOCOL_VERSION); CDataStream ss_data(MakeByteSpan(tx_data), SER_NETWORK, PROTOCOL_VERSION);
try { try {
ss_data >> psbt; ss_data >> psbt;
if (!ss_data.empty()) { if (!ss_data.empty()) {

View file

@ -142,14 +142,14 @@ public:
{ {
unsigned int len = size(); unsigned int len = size();
::WriteCompactSize(s, len); ::WriteCompactSize(s, len);
s.write((char*)vch, len); s.write(AsBytes(Span{vch, len}));
} }
template <typename Stream> template <typename Stream>
void Unserialize(Stream& s) void Unserialize(Stream& s)
{ {
const unsigned int len(::ReadCompactSize(s)); const unsigned int len(::ReadCompactSize(s));
if (len <= SIZE) { if (len <= SIZE) {
s.read((char*)vch, len); s.read(AsWritableBytes(Span{vch, len}));
if (len != size()) { if (len != size()) {
Invalidate(); Invalidate();
} }

View file

@ -22,20 +22,23 @@ public:
m_remaining(txToLen) m_remaining(txToLen)
{} {}
void read(char* pch, size_t nSize) void read(Span<std::byte> dst)
{ {
if (nSize > m_remaining) if (dst.size() > m_remaining) {
throw std::ios_base::failure(std::string(__func__) + ": end of data"); throw std::ios_base::failure(std::string(__func__) + ": end of data");
}
if (pch == nullptr) if (dst.data() == nullptr) {
throw std::ios_base::failure(std::string(__func__) + ": bad destination buffer"); throw std::ios_base::failure(std::string(__func__) + ": bad destination buffer");
}
if (m_data == nullptr) if (m_data == nullptr) {
throw std::ios_base::failure(std::string(__func__) + ": bad source buffer"); throw std::ios_base::failure(std::string(__func__) + ": bad source buffer");
}
memcpy(pch, m_data, nSize); memcpy(dst.data(), m_data, dst.size());
m_remaining -= nSize; m_remaining -= dst.size();
m_data += nSize; m_data += dst.size();
} }
template<typename T> template<typename T>

View file

@ -1303,12 +1303,12 @@ public:
it = itBegin; it = itBegin;
while (scriptCode.GetOp(it, opcode)) { while (scriptCode.GetOp(it, opcode)) {
if (opcode == OP_CODESEPARATOR) { if (opcode == OP_CODESEPARATOR) {
s.write((char*)&itBegin[0], it-itBegin-1); s.write(AsBytes(Span{&itBegin[0], size_t(it - itBegin - 1)}));
itBegin = it; itBegin = it;
} }
} }
if (itBegin != scriptCode.end()) if (itBegin != scriptCode.end())
s.write((char*)&itBegin[0], it-itBegin); s.write(AsBytes(Span{&itBegin[0], size_t(it - itBegin)}));
} }
/** Serialize an input of txTo */ /** Serialize an input of txTo */

View file

@ -47,79 +47,72 @@ static const unsigned int MAX_VECTOR_ALLOCATE = 5000000;
struct deserialize_type {}; struct deserialize_type {};
constexpr deserialize_type deserialize {}; constexpr deserialize_type deserialize {};
//! Safely convert odd char pointer types to standard ones.
inline char* CharCast(char* c) { return c; }
inline char* CharCast(unsigned char* c) { return (char*)c; }
inline const char* CharCast(const char* c) { return c; }
inline const char* CharCast(const unsigned char* c) { return (const char*)c; }
/* /*
* Lowest-level serialization and conversion. * Lowest-level serialization and conversion.
* @note Sizes of these types are verified in the tests
*/ */
template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj) template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
{ {
s.write((char*)&obj, 1); s.write(AsBytes(Span{&obj, 1}));
} }
template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj) template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
{ {
obj = htole16(obj); obj = htole16(obj);
s.write((char*)&obj, 2); s.write(AsBytes(Span{&obj, 1}));
} }
template<typename Stream> inline void ser_writedata16be(Stream &s, uint16_t obj) template<typename Stream> inline void ser_writedata16be(Stream &s, uint16_t obj)
{ {
obj = htobe16(obj); obj = htobe16(obj);
s.write((char*)&obj, 2); s.write(AsBytes(Span{&obj, 1}));
} }
template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj) template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
{ {
obj = htole32(obj); obj = htole32(obj);
s.write((char*)&obj, 4); s.write(AsBytes(Span{&obj, 1}));
} }
template<typename Stream> inline void ser_writedata32be(Stream &s, uint32_t obj) template<typename Stream> inline void ser_writedata32be(Stream &s, uint32_t obj)
{ {
obj = htobe32(obj); obj = htobe32(obj);
s.write((char*)&obj, 4); s.write(AsBytes(Span{&obj, 1}));
} }
template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj) template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
{ {
obj = htole64(obj); obj = htole64(obj);
s.write((char*)&obj, 8); s.write(AsBytes(Span{&obj, 1}));
} }
template<typename Stream> inline uint8_t ser_readdata8(Stream &s) template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
{ {
uint8_t obj; uint8_t obj;
s.read((char*)&obj, 1); s.read(AsWritableBytes(Span{&obj, 1}));
return obj; return obj;
} }
template<typename Stream> inline uint16_t ser_readdata16(Stream &s) template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
{ {
uint16_t obj; uint16_t obj;
s.read((char*)&obj, 2); s.read(AsWritableBytes(Span{&obj, 1}));
return le16toh(obj); return le16toh(obj);
} }
template<typename Stream> inline uint16_t ser_readdata16be(Stream &s) template<typename Stream> inline uint16_t ser_readdata16be(Stream &s)
{ {
uint16_t obj; uint16_t obj;
s.read((char*)&obj, 2); s.read(AsWritableBytes(Span{&obj, 1}));
return be16toh(obj); return be16toh(obj);
} }
template<typename Stream> inline uint32_t ser_readdata32(Stream &s) template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
{ {
uint32_t obj; uint32_t obj;
s.read((char*)&obj, 4); s.read(AsWritableBytes(Span{&obj, 1}));
return le32toh(obj); return le32toh(obj);
} }
template<typename Stream> inline uint32_t ser_readdata32be(Stream &s) template<typename Stream> inline uint32_t ser_readdata32be(Stream &s)
{ {
uint32_t obj; uint32_t obj;
s.read((char*)&obj, 4); s.read(AsWritableBytes(Span{&obj, 1}));
return be32toh(obj); return be32toh(obj);
} }
template<typename Stream> inline uint64_t ser_readdata64(Stream &s) template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
{ {
uint64_t obj; uint64_t obj;
s.read((char*)&obj, 8); s.read(AsWritableBytes(Span{&obj, 1}));
return le64toh(obj); return le64toh(obj);
} }
@ -127,7 +120,7 @@ template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// //
// Templates for serializing to anything that looks like a stream, // Templates for serializing to anything that looks like a stream,
// i.e. anything that supports .read(char*, size_t) and .write(char*, size_t) // i.e. anything that supports .read(Span<std::byte>) and .write(Span<const std::byte>)
// //
class CSizeComputer; class CSizeComputer;
@ -196,7 +189,7 @@ template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; }
FORMATTER_METHODS(cls, obj) FORMATTER_METHODS(cls, obj)
#ifndef CHAR_EQUALS_INT8 #ifndef CHAR_EQUALS_INT8
template<typename Stream> inline void Serialize(Stream& s, char a ) { ser_writedata8(s, a); } // TODO Get rid of bare char template <typename Stream> void Serialize(Stream&, char) = delete; // char serialization forbidden. Use uint8_t or int8_t
#endif #endif
template<typename Stream> inline void Serialize(Stream& s, int8_t a ) { ser_writedata8(s, a); } template<typename Stream> inline void Serialize(Stream& s, int8_t a ) { ser_writedata8(s, a); }
template<typename Stream> inline void Serialize(Stream& s, uint8_t a ) { ser_writedata8(s, a); } template<typename Stream> inline void Serialize(Stream& s, uint8_t a ) { ser_writedata8(s, a); }
@ -206,13 +199,13 @@ template<typename Stream> inline void Serialize(Stream& s, int32_t a ) { ser_wri
template<typename Stream> inline void Serialize(Stream& s, uint32_t a) { ser_writedata32(s, a); } template<typename Stream> inline void Serialize(Stream& s, uint32_t a) { ser_writedata32(s, a); }
template<typename Stream> inline void Serialize(Stream& s, int64_t a ) { ser_writedata64(s, a); } template<typename Stream> inline void Serialize(Stream& s, int64_t a ) { ser_writedata64(s, a); }
template<typename Stream> inline void Serialize(Stream& s, uint64_t a) { ser_writedata64(s, a); } template<typename Stream> inline void Serialize(Stream& s, uint64_t a) { ser_writedata64(s, a); }
template<typename Stream, int N> inline void Serialize(Stream& s, const char (&a)[N]) { s.write(a, N); } template<typename Stream, int N> inline void Serialize(Stream& s, const char (&a)[N]) { s.write(MakeByteSpan(a)); }
template<typename Stream, int N> inline void Serialize(Stream& s, const unsigned char (&a)[N]) { s.write(CharCast(a), N); } template<typename Stream, int N> inline void Serialize(Stream& s, const unsigned char (&a)[N]) { s.write(MakeByteSpan(a)); }
template<typename Stream> inline void Serialize(Stream& s, const Span<const unsigned char>& span) { s.write(CharCast(span.data()), span.size()); } template<typename Stream> inline void Serialize(Stream& s, const Span<const unsigned char>& span) { s.write(AsBytes(span)); }
template<typename Stream> inline void Serialize(Stream& s, const Span<unsigned char>& span) { s.write(CharCast(span.data()), span.size()); } template<typename Stream> inline void Serialize(Stream& s, const Span<unsigned char>& span) { s.write(AsBytes(span)); }
#ifndef CHAR_EQUALS_INT8 #ifndef CHAR_EQUALS_INT8
template<typename Stream> inline void Unserialize(Stream& s, char& a ) { a = ser_readdata8(s); } // TODO Get rid of bare char template <typename Stream> void Unserialize(Stream&, char) = delete; // char serialization forbidden. Use uint8_t or int8_t
#endif #endif
template<typename Stream> inline void Unserialize(Stream& s, int8_t& a ) { a = ser_readdata8(s); } template<typename Stream> inline void Unserialize(Stream& s, int8_t& a ) { a = ser_readdata8(s); }
template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a ) { a = ser_readdata8(s); } template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a ) { a = ser_readdata8(s); }
@ -222,9 +215,9 @@ template<typename Stream> inline void Unserialize(Stream& s, int32_t& a ) { a =
template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a) { a = ser_readdata32(s); } template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a) { a = ser_readdata32(s); }
template<typename Stream> inline void Unserialize(Stream& s, int64_t& a ) { a = ser_readdata64(s); } template<typename Stream> inline void Unserialize(Stream& s, int64_t& a ) { a = ser_readdata64(s); }
template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a) { a = ser_readdata64(s); } template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a) { a = ser_readdata64(s); }
template<typename Stream, int N> inline void Unserialize(Stream& s, char (&a)[N]) { s.read(a, N); } template<typename Stream, int N> inline void Unserialize(Stream& s, char (&a)[N]) { s.read(MakeWritableByteSpan(a)); }
template<typename Stream, int N> inline void Unserialize(Stream& s, unsigned char (&a)[N]) { s.read(CharCast(a), N); } template<typename Stream, int N> inline void Unserialize(Stream& s, unsigned char (&a)[N]) { s.read(MakeWritableByteSpan(a)); }
template<typename Stream> inline void Unserialize(Stream& s, Span<unsigned char>& span) { s.read(CharCast(span.data()), span.size()); } template<typename Stream> inline void Unserialize(Stream& s, Span<unsigned char>& span) { s.read(AsWritableBytes(span)); }
template <typename Stream> inline void Serialize(Stream& s, bool a) { uint8_t f = a; ser_writedata8(s, f); } template <typename Stream> inline void Serialize(Stream& s, bool a) { uint8_t f = a; ser_writedata8(s, f); }
template <typename Stream> inline void Unserialize(Stream& s, bool& a) { uint8_t f = ser_readdata8(s); a = f; } template <typename Stream> inline void Unserialize(Stream& s, bool& a) { uint8_t f = ser_readdata8(s); a = f; }
@ -479,10 +472,10 @@ struct CustomUintFormatter
if (v < 0 || v > MAX) throw std::ios_base::failure("CustomUintFormatter value out of range"); if (v < 0 || v > MAX) throw std::ios_base::failure("CustomUintFormatter value out of range");
if (BigEndian) { if (BigEndian) {
uint64_t raw = htobe64(v); uint64_t raw = htobe64(v);
s.write(((const char*)&raw) + 8 - Bytes, Bytes); s.write({BytePtr(&raw) + 8 - Bytes, Bytes});
} else { } else {
uint64_t raw = htole64(v); uint64_t raw = htole64(v);
s.write((const char*)&raw, Bytes); s.write({BytePtr(&raw), Bytes});
} }
} }
@ -492,10 +485,10 @@ struct CustomUintFormatter
static_assert(std::numeric_limits<U>::max() >= MAX && std::numeric_limits<U>::min() <= 0, "Assigned type too small"); static_assert(std::numeric_limits<U>::max() >= MAX && std::numeric_limits<U>::min() <= 0, "Assigned type too small");
uint64_t raw = 0; uint64_t raw = 0;
if (BigEndian) { if (BigEndian) {
s.read(((char*)&raw) + 8 - Bytes, Bytes); s.read({BytePtr(&raw) + 8 - Bytes, Bytes});
v = static_cast<I>(be64toh(raw)); v = static_cast<I>(be64toh(raw));
} else { } else {
s.read((char*)&raw, Bytes); s.read({BytePtr(&raw), Bytes});
v = static_cast<I>(le64toh(raw)); v = static_cast<I>(le64toh(raw));
} }
} }
@ -551,7 +544,7 @@ struct LimitedStringFormatter
throw std::ios_base::failure("String length limit exceeded"); throw std::ios_base::failure("String length limit exceeded");
} }
v.resize(size); v.resize(size);
if (size != 0) s.read((char*)v.data(), size); if (size != 0) s.read(MakeWritableByteSpan(v));
} }
template<typename Stream> template<typename Stream>
@ -715,7 +708,7 @@ void Serialize(Stream& os, const std::basic_string<C>& str)
{ {
WriteCompactSize(os, str.size()); WriteCompactSize(os, str.size());
if (!str.empty()) if (!str.empty())
os.write((char*)str.data(), str.size() * sizeof(C)); os.write(MakeByteSpan(str));
} }
template<typename Stream, typename C> template<typename Stream, typename C>
@ -724,7 +717,7 @@ void Unserialize(Stream& is, std::basic_string<C>& str)
unsigned int nSize = ReadCompactSize(is); unsigned int nSize = ReadCompactSize(is);
str.resize(nSize); str.resize(nSize);
if (nSize != 0) if (nSize != 0)
is.read((char*)str.data(), nSize * sizeof(C)); is.read(MakeWritableByteSpan(str));
} }
@ -737,7 +730,7 @@ void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&)
{ {
WriteCompactSize(os, v.size()); WriteCompactSize(os, v.size());
if (!v.empty()) if (!v.empty())
os.write((char*)v.data(), v.size() * sizeof(T)); os.write(MakeByteSpan(v));
} }
template<typename Stream, unsigned int N, typename T, typename V> template<typename Stream, unsigned int N, typename T, typename V>
@ -764,7 +757,7 @@ void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&)
{ {
unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T))); unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
v.resize_uninitialized(i + blk); v.resize_uninitialized(i + blk);
is.read((char*)&v[i], blk * sizeof(T)); is.read(AsWritableBytes(Span{&v[i], blk}));
i += blk; i += blk;
} }
} }
@ -791,7 +784,7 @@ void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&
{ {
WriteCompactSize(os, v.size()); WriteCompactSize(os, v.size());
if (!v.empty()) if (!v.empty())
os.write((char*)v.data(), v.size() * sizeof(T)); os.write(MakeByteSpan(v));
} }
template<typename Stream, typename T, typename A> template<typename Stream, typename T, typename A>
@ -830,7 +823,7 @@ void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&)
{ {
unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T))); unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
v.resize(i + blk); v.resize(i + blk);
is.read((char*)&v[i], blk * sizeof(T)); is.read(AsWritableBytes(Span{&v[i], blk}));
i += blk; i += blk;
} }
} }
@ -995,9 +988,9 @@ protected:
public: public:
explicit CSizeComputer(int nVersionIn) : nSize(0), nVersion(nVersionIn) {} explicit CSizeComputer(int nVersionIn) : nSize(0), nVersion(nVersionIn) {}
void write(const char *psz, size_t _nSize) void write(Span<const std::byte> src)
{ {
this->nSize += _nSize; this->nSize += src.size();
} }
/** Pretend _nSize bytes are written, without specifying them. */ /** Pretend _nSize bytes are written, without specifying them. */

View file

@ -243,16 +243,21 @@ T& SpanPopBack(Span<T>& span)
return back; return back;
} }
//! Convert a data pointer to a std::byte data pointer.
//! Where possible, please use the safer AsBytes helpers.
inline const std::byte* BytePtr(const void* data) { return reinterpret_cast<const std::byte*>(data); }
inline std::byte* BytePtr(void* data) { return reinterpret_cast<std::byte*>(data); }
// From C++20 as_bytes and as_writeable_bytes // From C++20 as_bytes and as_writeable_bytes
template <typename T> template <typename T>
Span<const std::byte> AsBytes(Span<T> s) noexcept Span<const std::byte> AsBytes(Span<T> s) noexcept
{ {
return {reinterpret_cast<const std::byte*>(s.data()), s.size_bytes()}; return {BytePtr(s.data()), s.size_bytes()};
} }
template <typename T> template <typename T>
Span<std::byte> AsWritableBytes(Span<T> s) noexcept Span<std::byte> AsWritableBytes(Span<T> s) noexcept
{ {
return {reinterpret_cast<std::byte*>(s.data()), s.size_bytes()}; return {BytePtr(s.data()), s.size_bytes()};
} }
template <typename V> template <typename V>

View file

@ -49,14 +49,14 @@ public:
return (*this); return (*this);
} }
void write(const char* pch, size_t nSize) void write(Span<const std::byte> src)
{ {
stream->write(pch, nSize); stream->write(src);
} }
void read(char* pch, size_t nSize) void read(Span<std::byte> dst)
{ {
stream->read(pch, nSize); stream->read(dst);
} }
int GetVersion() const { return nVersion; } int GetVersion() const { return nVersion; }
@ -94,17 +94,17 @@ class CVectorWriter
{ {
::SerializeMany(*this, std::forward<Args>(args)...); ::SerializeMany(*this, std::forward<Args>(args)...);
} }
void write(const char* pch, size_t nSize) void write(Span<const std::byte> src)
{ {
assert(nPos <= vchData.size()); assert(nPos <= vchData.size());
size_t nOverwrite = std::min(nSize, vchData.size() - nPos); size_t nOverwrite = std::min(src.size(), vchData.size() - nPos);
if (nOverwrite) { if (nOverwrite) {
memcpy(vchData.data() + nPos, reinterpret_cast<const unsigned char*>(pch), nOverwrite); memcpy(vchData.data() + nPos, src.data(), nOverwrite);
} }
if (nOverwrite < nSize) { if (nOverwrite < src.size()) {
vchData.insert(vchData.end(), reinterpret_cast<const unsigned char*>(pch) + nOverwrite, reinterpret_cast<const unsigned char*>(pch) + nSize); vchData.insert(vchData.end(), UCharCast(src.data()) + nOverwrite, UCharCast(src.end()));
} }
nPos += nSize; nPos += src.size();
} }
template<typename T> template<typename T>
CVectorWriter& operator<<(const T& obj) CVectorWriter& operator<<(const T& obj)
@ -161,18 +161,18 @@ public:
size_t size() const { return m_data.size(); } size_t size() const { return m_data.size(); }
bool empty() const { return m_data.empty(); } bool empty() const { return m_data.empty(); }
void read(char* dst, size_t n) void read(Span<std::byte> dst)
{ {
if (n == 0) { if (dst.size() == 0) {
return; return;
} }
// Read from the beginning of the buffer // Read from the beginning of the buffer
if (n > m_data.size()) { if (dst.size() > m_data.size()) {
throw std::ios_base::failure("SpanReader::read(): end of data"); throw std::ios_base::failure("SpanReader::read(): end of data");
} }
memcpy(dst, m_data.data(), n); memcpy(dst.data(), m_data.data(), dst.size());
m_data = m_data.subspan(n); m_data = m_data.subspan(dst.size());
} }
}; };
@ -206,6 +206,7 @@ public:
: nType{nTypeIn}, : nType{nTypeIn},
nVersion{nVersionIn} {} nVersion{nVersionIn} {}
explicit CDataStream(Span<const uint8_t> sp, int type, int version) : CDataStream{AsBytes(sp), type, version} {}
explicit CDataStream(Span<const value_type> sp, int nTypeIn, int nVersionIn) explicit CDataStream(Span<const value_type> sp, int nTypeIn, int nVersionIn)
: vch(sp.data(), sp.data() + sp.size()), : vch(sp.data(), sp.data() + sp.size()),
nType{nTypeIn}, nType{nTypeIn},
@ -221,7 +222,7 @@ public:
std::string str() const std::string str() const
{ {
return (std::string(begin(), end())); return std::string{UCharCast(data()), UCharCast(data() + size())};
} }
@ -342,16 +343,16 @@ public:
void SetVersion(int n) { nVersion = n; } void SetVersion(int n) { nVersion = n; }
int GetVersion() const { return nVersion; } int GetVersion() const { return nVersion; }
void read(char* pch, size_t nSize) void read(Span<value_type> dst)
{ {
if (nSize == 0) return; if (dst.size() == 0) return;
// Read from the beginning of the buffer // Read from the beginning of the buffer
unsigned int nReadPosNext = nReadPos + nSize; unsigned int nReadPosNext = nReadPos + dst.size();
if (nReadPosNext > vch.size()) { if (nReadPosNext > vch.size()) {
throw std::ios_base::failure("CDataStream::read(): end of data"); throw std::ios_base::failure("CDataStream::read(): end of data");
} }
memcpy(pch, &vch[nReadPos], nSize); memcpy(dst.data(), &vch[nReadPos], dst.size());
if (nReadPosNext == vch.size()) if (nReadPosNext == vch.size())
{ {
nReadPos = 0; nReadPos = 0;
@ -379,10 +380,10 @@ public:
nReadPos = nReadPosNext; nReadPos = nReadPosNext;
} }
void write(const char* pch, size_t nSize) void write(Span<const value_type> src)
{ {
// Write to the end of the buffer // Write to the end of the buffer
vch.insert(vch.end(), pch, pch + nSize); vch.insert(vch.end(), src.begin(), src.end());
} }
template<typename Stream> template<typename Stream>
@ -390,7 +391,7 @@ public:
{ {
// Special case: stream << stream concatenates like stream += stream // Special case: stream << stream concatenates like stream += stream
if (!vch.empty()) if (!vch.empty())
s.write((char*)vch.data(), vch.size() * sizeof(value_type)); s.write(MakeByteSpan(vch));
} }
template<typename T> template<typename T>
@ -421,7 +422,7 @@ public:
} }
for (size_type i = 0, j = 0; i != size(); i++) { for (size_type i = 0, j = 0; i != size(); i++) {
vch[i] ^= key[j++]; vch[i] ^= std::byte{key[j++]};
// This potentially acts on very many bytes of data, so it's // This potentially acts on very many bytes of data, so it's
// important that we calculate `j`, i.e. the `key` index in this // important that we calculate `j`, i.e. the `key` index in this
@ -594,12 +595,13 @@ public:
int GetType() const { return nType; } int GetType() const { return nType; }
int GetVersion() const { return nVersion; } int GetVersion() const { return nVersion; }
void read(char* pch, size_t nSize) void read(Span<std::byte> dst)
{ {
if (!file) if (!file)
throw std::ios_base::failure("CAutoFile::read: file handle is nullptr"); throw std::ios_base::failure("CAutoFile::read: file handle is nullptr");
if (fread(pch, 1, nSize, file) != nSize) if (fread(dst.data(), 1, dst.size(), file) != dst.size()) {
throw std::ios_base::failure(feof(file) ? "CAutoFile::read: end of file" : "CAutoFile::read: fread failed"); throw std::ios_base::failure(feof(file) ? "CAutoFile::read: end of file" : "CAutoFile::read: fread failed");
}
} }
void ignore(size_t nSize) void ignore(size_t nSize)
@ -615,12 +617,13 @@ public:
} }
} }
void write(const char* pch, size_t nSize) void write(Span<const std::byte> src)
{ {
if (!file) if (!file)
throw std::ios_base::failure("CAutoFile::write: file handle is nullptr"); throw std::ios_base::failure("CAutoFile::write: file handle is nullptr");
if (fwrite(pch, 1, nSize, file) != nSize) if (fwrite(src.data(), 1, src.size(), file) != src.size()) {
throw std::ios_base::failure("CAutoFile::write: write failed"); throw std::ios_base::failure("CAutoFile::write: write failed");
}
} }
template<typename T> template<typename T>
@ -661,7 +664,7 @@ private:
uint64_t nReadPos; //!< how many bytes have been read from this uint64_t nReadPos; //!< how many bytes have been read from this
uint64_t nReadLimit; //!< up to which position we're allowed to read uint64_t nReadLimit; //!< up to which position we're allowed to read
uint64_t nRewind; //!< how many bytes we guarantee to rewind uint64_t nRewind; //!< how many bytes we guarantee to rewind
std::vector<char> vchBuf; //!< the buffer std::vector<std::byte> vchBuf; //!< the buffer
protected: protected:
//! read data from the source to fill the buffer //! read data from the source to fill the buffer
@ -682,8 +685,8 @@ protected:
} }
public: public:
CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn) : CBufferedFile(FILE* fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn)
nType(nTypeIn), nVersion(nVersionIn), nSrcPos(0), nReadPos(0), nReadLimit(std::numeric_limits<uint64_t>::max()), nRewind(nRewindIn), vchBuf(nBufSize, 0) : nType(nTypeIn), nVersion(nVersionIn), nSrcPos(0), nReadPos(0), nReadLimit(std::numeric_limits<uint64_t>::max()), nRewind(nRewindIn), vchBuf(nBufSize, std::byte{0})
{ {
if (nRewindIn >= nBufSize) if (nRewindIn >= nBufSize)
throw std::ios_base::failure("Rewind limit must be less than buffer size"); throw std::ios_base::failure("Rewind limit must be less than buffer size");
@ -716,22 +719,23 @@ public:
} }
//! read a number of bytes //! read a number of bytes
void read(char *pch, size_t nSize) { void read(Span<std::byte> dst)
if (nSize + nReadPos > nReadLimit) {
if (dst.size() + nReadPos > nReadLimit) {
throw std::ios_base::failure("Read attempted past buffer limit"); throw std::ios_base::failure("Read attempted past buffer limit");
while (nSize > 0) { }
while (dst.size() > 0) {
if (nReadPos == nSrcPos) if (nReadPos == nSrcPos)
Fill(); Fill();
unsigned int pos = nReadPos % vchBuf.size(); unsigned int pos = nReadPos % vchBuf.size();
size_t nNow = nSize; size_t nNow = dst.size();
if (nNow + pos > vchBuf.size()) if (nNow + pos > vchBuf.size())
nNow = vchBuf.size() - pos; nNow = vchBuf.size() - pos;
if (nNow + nReadPos > nSrcPos) if (nNow + nReadPos > nSrcPos)
nNow = nSrcPos - nReadPos; nNow = nSrcPos - nReadPos;
memcpy(pch, &vchBuf[pos], nNow); memcpy(dst.data(), &vchBuf[pos], nNow);
nReadPos += nNow; nReadPos += nNow;
pch += nNow; dst = dst.subspan(nNow);
nSize -= nNow;
} }
} }
@ -774,12 +778,14 @@ public:
} }
//! search for a given byte in the stream, and remain positioned on it //! search for a given byte in the stream, and remain positioned on it
void FindByte(char ch) { void FindByte(uint8_t ch)
{
while (true) { while (true) {
if (nReadPos == nSrcPos) if (nReadPos == nSrcPos)
Fill(); Fill();
if (vchBuf[nReadPos % vchBuf.size()] == ch) if (vchBuf[nReadPos % vchBuf.size()] == std::byte{ch}) {
break; break;
}
nReadPos++; nReadPos++;
} }
} }

View file

@ -41,6 +41,6 @@ struct zero_after_free_allocator : public std::allocator<T> {
}; };
/** Byte-vector that clears its contents before deletion. */ /** Byte-vector that clears its contents before deletion. */
using SerializeData = std::vector<uint8_t, zero_after_free_allocator<uint8_t>>; using SerializeData = std::vector<std::byte, zero_after_free_allocator<std::byte>>;
#endif // BITCOIN_SUPPORT_ALLOCATORS_ZEROAFTERFREE_H #endif // BITCOIN_SUPPORT_ALLOCATORS_ZEROAFTERFREE_H

View file

@ -43,8 +43,9 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize)
stream << filter; stream << filter;
std::vector<uint8_t> expected = ParseHex("03614e9b050000000000000001"); std::vector<uint8_t> expected = ParseHex("03614e9b050000000000000001");
auto result{MakeUCharSpan(stream)};
BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end()); BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
BOOST_CHECK_MESSAGE( filter.contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")), "Bloom filter doesn't contain just-inserted object!"); BOOST_CHECK_MESSAGE( filter.contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")), "Bloom filter doesn't contain just-inserted object!");
} }
@ -69,8 +70,9 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize_with_tweak)
stream << filter; stream << filter;
std::vector<uint8_t> expected = ParseHex("03ce4299050000000100008001"); std::vector<uint8_t> expected = ParseHex("03ce4299050000000100008001");
auto result{MakeUCharSpan(stream)};
BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end()); BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
} }
BOOST_AUTO_TEST_CASE(bloom_create_insert_key) BOOST_AUTO_TEST_CASE(bloom_create_insert_key)
@ -89,8 +91,9 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_key)
stream << filter; stream << filter;
std::vector<unsigned char> expected = ParseHex("038fc16b080000000000000001"); std::vector<unsigned char> expected = ParseHex("038fc16b080000000000000001");
auto result{MakeUCharSpan(stream)};
BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end()); BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
} }
BOOST_AUTO_TEST_CASE(bloom_match) BOOST_AUTO_TEST_CASE(bloom_match)
@ -341,8 +344,9 @@ BOOST_AUTO_TEST_CASE(merkle_block_3_and_serialize)
merkleStream << merkleBlock; merkleStream << merkleBlock;
std::vector<uint8_t> expected = ParseHex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101"); std::vector<uint8_t> expected = ParseHex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101");
auto result{MakeUCharSpan(merkleStream)};
BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), merkleStream.begin(), merkleStream.end()); BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), result.begin(), result.end());
} }
BOOST_AUTO_TEST_CASE(merkle_block_4) BOOST_AUTO_TEST_CASE(merkle_block_4)

View file

@ -23,16 +23,16 @@ FUZZ_TARGET(autofile)
CallOneOf( CallOneOf(
fuzzed_data_provider, fuzzed_data_provider,
[&] { [&] {
std::array<uint8_t, 4096> arr{}; std::array<std::byte, 4096> arr{};
try { try {
auto_file.read((char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)); auto_file.read({arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)});
} catch (const std::ios_base::failure&) { } catch (const std::ios_base::failure&) {
} }
}, },
[&] { [&] {
const std::array<uint8_t, 4096> arr{}; const std::array<std::byte, 4096> arr{};
try { try {
auto_file.write((const char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)); auto_file.write({arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)});
} catch (const std::ios_base::failure&) { } catch (const std::ios_base::failure&) {
} }
}, },

View file

@ -33,9 +33,9 @@ FUZZ_TARGET(buffered_file)
CallOneOf( CallOneOf(
fuzzed_data_provider, fuzzed_data_provider,
[&] { [&] {
std::array<uint8_t, 4096> arr{}; std::array<std::byte, 4096> arr{};
try { try {
opt_buffered_file->read((char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)); opt_buffered_file->read({arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)});
} catch (const std::ios_base::failure&) { } catch (const std::ios_base::failure&) {
} }
}, },
@ -53,7 +53,7 @@ FUZZ_TARGET(buffered_file)
return; return;
} }
try { try {
opt_buffered_file->FindByte(fuzzed_data_provider.ConsumeIntegral<char>()); opt_buffered_file->FindByte(fuzzed_data_provider.ConsumeIntegral<uint8_t>());
} catch (const std::ios_base::failure&) { } catch (const std::ios_base::failure&) {
} }
}, },

View file

@ -206,11 +206,6 @@ FUZZ_TARGET_INIT(integer, initialize_integer)
stream >> deserialized_i8; stream >> deserialized_i8;
assert(i8 == deserialized_i8 && stream.empty()); assert(i8 == deserialized_i8 && stream.empty());
char deserialized_ch;
stream << ch;
stream >> deserialized_ch;
assert(ch == deserialized_ch && stream.empty());
bool deserialized_b; bool deserialized_b;
stream << b; stream << b;
stream >> deserialized_b; stream >> deserialized_b;

View file

@ -271,7 +271,7 @@ std::string ConsumeScalarRPCArgument(FuzzedDataProvider& fuzzed_data_provider)
} }
CDataStream data_stream{SER_NETWORK, PROTOCOL_VERSION}; CDataStream data_stream{SER_NETWORK, PROTOCOL_VERSION};
data_stream << *opt_psbt; data_stream << *opt_psbt;
r = EncodeBase64({data_stream.begin(), data_stream.end()}); r = EncodeBase64(data_stream);
}, },
[&] { [&] {
// base58 encoded key // base58 encoded key

View file

@ -328,7 +328,6 @@ void WriteToStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) noe
CallOneOf( CallOneOf(
fuzzed_data_provider, fuzzed_data_provider,
WRITE_TO_STREAM_CASE(bool, fuzzed_data_provider.ConsumeBool()), WRITE_TO_STREAM_CASE(bool, fuzzed_data_provider.ConsumeBool()),
WRITE_TO_STREAM_CASE(char, fuzzed_data_provider.ConsumeIntegral<char>()),
WRITE_TO_STREAM_CASE(int8_t, fuzzed_data_provider.ConsumeIntegral<int8_t>()), WRITE_TO_STREAM_CASE(int8_t, fuzzed_data_provider.ConsumeIntegral<int8_t>()),
WRITE_TO_STREAM_CASE(uint8_t, fuzzed_data_provider.ConsumeIntegral<uint8_t>()), WRITE_TO_STREAM_CASE(uint8_t, fuzzed_data_provider.ConsumeIntegral<uint8_t>()),
WRITE_TO_STREAM_CASE(int16_t, fuzzed_data_provider.ConsumeIntegral<int16_t>()), WRITE_TO_STREAM_CASE(int16_t, fuzzed_data_provider.ConsumeIntegral<int16_t>()),
@ -338,7 +337,7 @@ void WriteToStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) noe
WRITE_TO_STREAM_CASE(int64_t, fuzzed_data_provider.ConsumeIntegral<int64_t>()), WRITE_TO_STREAM_CASE(int64_t, fuzzed_data_provider.ConsumeIntegral<int64_t>()),
WRITE_TO_STREAM_CASE(uint64_t, fuzzed_data_provider.ConsumeIntegral<uint64_t>()), WRITE_TO_STREAM_CASE(uint64_t, fuzzed_data_provider.ConsumeIntegral<uint64_t>()),
WRITE_TO_STREAM_CASE(std::string, fuzzed_data_provider.ConsumeRandomLengthString(32)), WRITE_TO_STREAM_CASE(std::string, fuzzed_data_provider.ConsumeRandomLengthString(32)),
WRITE_TO_STREAM_CASE(std::vector<char>, ConsumeRandomLengthIntegralVector<char>(fuzzed_data_provider))); WRITE_TO_STREAM_CASE(std::vector<uint8_t>, ConsumeRandomLengthIntegralVector<uint8_t>(fuzzed_data_provider)));
} catch (const std::ios_base::failure&) { } catch (const std::ios_base::failure&) {
break; break;
} }
@ -358,7 +357,6 @@ void ReadFromStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) no
CallOneOf( CallOneOf(
fuzzed_data_provider, fuzzed_data_provider,
READ_FROM_STREAM_CASE(bool), READ_FROM_STREAM_CASE(bool),
READ_FROM_STREAM_CASE(char),
READ_FROM_STREAM_CASE(int8_t), READ_FROM_STREAM_CASE(int8_t),
READ_FROM_STREAM_CASE(uint8_t), READ_FROM_STREAM_CASE(uint8_t),
READ_FROM_STREAM_CASE(int16_t), READ_FROM_STREAM_CASE(int16_t),
@ -368,7 +366,7 @@ void ReadFromStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) no
READ_FROM_STREAM_CASE(int64_t), READ_FROM_STREAM_CASE(int64_t),
READ_FROM_STREAM_CASE(uint64_t), READ_FROM_STREAM_CASE(uint64_t),
READ_FROM_STREAM_CASE(std::string), READ_FROM_STREAM_CASE(std::string),
READ_FROM_STREAM_CASE(std::vector<char>)); READ_FROM_STREAM_CASE(std::vector<uint8_t>));
} catch (const std::ios_base::failure&) { } catch (const std::ios_base::failure&) {
break; break;
} }

View file

@ -155,10 +155,10 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript
if (libconsensus_flags == flags) { if (libconsensus_flags == flags) {
int expectedSuccessCode = expect ? 1 : 0; int expectedSuccessCode = expect ? 1 : 0;
if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) { if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) {
BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), txCredit.vout[0].nValue, stream.data(), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), txCredit.vout[0].nValue, UCharCast(stream.data()), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
} else { } else {
BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), 0, stream.data(), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), 0, UCharCast(stream.data()), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message); BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
} }
} }
#endif #endif
@ -1520,7 +1520,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_returns_true)
stream << spendTx; stream << spendTx;
bitcoinconsensus_error err; bitcoinconsensus_error err;
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err); int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 1); BOOST_CHECK_EQUAL(result, 1);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_OK); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_OK);
} }
@ -1543,7 +1543,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_index_err)
stream << spendTx; stream << spendTx;
bitcoinconsensus_error err; bitcoinconsensus_error err;
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err); int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0); BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_INDEX); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_INDEX);
} }
@ -1566,7 +1566,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_size)
stream << spendTx; stream << spendTx;
bitcoinconsensus_error err; bitcoinconsensus_error err;
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size() * 2, nIn, libconsensus_flags, &err); int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size() * 2, nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0); BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH);
} }
@ -1589,7 +1589,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_serialization)
stream << 0xffffffff; stream << 0xffffffff;
bitcoinconsensus_error err; bitcoinconsensus_error err;
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err); int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0); BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_DESERIALIZE); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_DESERIALIZE);
} }
@ -1612,7 +1612,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_amount_required_err)
stream << spendTx; stream << spendTx;
bitcoinconsensus_error err; bitcoinconsensus_error err;
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err); int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0); BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_AMOUNT_REQUIRED); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_AMOUNT_REQUIRED);
} }
@ -1635,7 +1635,7 @@ BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_invalid_flags)
stream << spendTx; stream << spendTx;
bitcoinconsensus_error err; bitcoinconsensus_error err;
int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err); int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0); BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_INVALID_FLAGS); BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_INVALID_FLAGS);
} }

View file

@ -61,7 +61,7 @@ public:
BOOST_AUTO_TEST_CASE(sizes) BOOST_AUTO_TEST_CASE(sizes)
{ {
BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(char(0), 0)); BOOST_CHECK_EQUAL(sizeof(unsigned char), GetSerializeSize((unsigned char)0, 0));
BOOST_CHECK_EQUAL(sizeof(int8_t), GetSerializeSize(int8_t(0), 0)); BOOST_CHECK_EQUAL(sizeof(int8_t), GetSerializeSize(int8_t(0), 0));
BOOST_CHECK_EQUAL(sizeof(uint8_t), GetSerializeSize(uint8_t(0), 0)); BOOST_CHECK_EQUAL(sizeof(uint8_t), GetSerializeSize(uint8_t(0), 0));
BOOST_CHECK_EQUAL(sizeof(int16_t), GetSerializeSize(int16_t(0), 0)); BOOST_CHECK_EQUAL(sizeof(int16_t), GetSerializeSize(int16_t(0), 0));
@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE(sizes)
BOOST_CHECK_EQUAL(sizeof(uint8_t), GetSerializeSize(bool(0), 0)); BOOST_CHECK_EQUAL(sizeof(uint8_t), GetSerializeSize(bool(0), 0));
// Sanity-check GetSerializeSize and c++ type matching // Sanity-check GetSerializeSize and c++ type matching
BOOST_CHECK_EQUAL(GetSerializeSize(char(0), 0), 1U); BOOST_CHECK_EQUAL(GetSerializeSize((unsigned char)0, 0), 1U);
BOOST_CHECK_EQUAL(GetSerializeSize(int8_t(0), 0), 1U); BOOST_CHECK_EQUAL(GetSerializeSize(int8_t(0), 0), 1U);
BOOST_CHECK_EQUAL(GetSerializeSize(uint8_t(0), 0), 1U); BOOST_CHECK_EQUAL(GetSerializeSize(uint8_t(0), 0), 1U);
BOOST_CHECK_EQUAL(GetSerializeSize(int16_t(0), 0), 2U); BOOST_CHECK_EQUAL(GetSerializeSize(int16_t(0), 0), 2U);
@ -186,76 +186,78 @@ BOOST_AUTO_TEST_CASE(noncanonical)
std::vector<char>::size_type n; std::vector<char>::size_type n;
// zero encoded with three bytes: // zero encoded with three bytes:
ss.write("\xfd\x00\x00", 3); ss.write(MakeByteSpan("\xfd\x00\x00").first(3));
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
// 0xfc encoded with three bytes: // 0xfc encoded with three bytes:
ss.write("\xfd\xfc\x00", 3); ss.write(MakeByteSpan("\xfd\xfc\x00").first(3));
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
// 0xfd encoded with three bytes is OK: // 0xfd encoded with three bytes is OK:
ss.write("\xfd\xfd\x00", 3); ss.write(MakeByteSpan("\xfd\xfd\x00").first(3));
n = ReadCompactSize(ss); n = ReadCompactSize(ss);
BOOST_CHECK(n == 0xfd); BOOST_CHECK(n == 0xfd);
// zero encoded with five bytes: // zero encoded with five bytes:
ss.write("\xfe\x00\x00\x00\x00", 5); ss.write(MakeByteSpan("\xfe\x00\x00\x00\x00").first(5));
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
// 0xffff encoded with five bytes: // 0xffff encoded with five bytes:
ss.write("\xfe\xff\xff\x00\x00", 5); ss.write(MakeByteSpan("\xfe\xff\xff\x00\x00").first(5));
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
// zero encoded with nine bytes: // zero encoded with nine bytes:
ss.write("\xff\x00\x00\x00\x00\x00\x00\x00\x00", 9); ss.write(MakeByteSpan("\xff\x00\x00\x00\x00\x00\x00\x00\x00").first(9));
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
// 0x01ffffff encoded with nine bytes: // 0x01ffffff encoded with nine bytes:
ss.write("\xff\xff\xff\xff\x01\x00\x00\x00\x00", 9); ss.write(MakeByteSpan("\xff\xff\xff\xff\x01\x00\x00\x00\x00").first(9));
BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
} }
BOOST_AUTO_TEST_CASE(insert_delete) BOOST_AUTO_TEST_CASE(insert_delete)
{ {
constexpr auto B2I{[](std::byte b) { return std::to_integer<uint8_t>(b); }};
// Test inserting/deleting bytes. // Test inserting/deleting bytes.
CDataStream ss(SER_DISK, 0); CDataStream ss(SER_DISK, 0);
BOOST_CHECK_EQUAL(ss.size(), 0U); BOOST_CHECK_EQUAL(ss.size(), 0U);
ss.write("\x00\x01\x02\xff", 4); ss.write(MakeByteSpan("\x00\x01\x02\xff").first(4));
BOOST_CHECK_EQUAL(ss.size(), 4U); BOOST_CHECK_EQUAL(ss.size(), 4U);
char c = (char)11; uint8_t c{11};
// Inserting at beginning/end/middle: // Inserting at beginning/end/middle:
ss.insert(ss.begin(), c); ss.insert(ss.begin(), std::byte{c});
BOOST_CHECK_EQUAL(ss.size(), 5U); BOOST_CHECK_EQUAL(ss.size(), 5U);
BOOST_CHECK_EQUAL(ss[0], c); BOOST_CHECK_EQUAL(B2I(ss[0]), c);
BOOST_CHECK_EQUAL(ss[1], 0); BOOST_CHECK_EQUAL(B2I(ss[1]), 0);
ss.insert(ss.end(), c); ss.insert(ss.end(), std::byte{c});
BOOST_CHECK_EQUAL(ss.size(), 6U); BOOST_CHECK_EQUAL(ss.size(), 6U);
BOOST_CHECK_EQUAL(ss[4], 0xff); BOOST_CHECK_EQUAL(B2I(ss[4]), 0xff);
BOOST_CHECK_EQUAL(ss[5], c); BOOST_CHECK_EQUAL(B2I(ss[5]), c);
ss.insert(ss.begin()+2, c); ss.insert(ss.begin() + 2, std::byte{c});
BOOST_CHECK_EQUAL(ss.size(), 7U); BOOST_CHECK_EQUAL(ss.size(), 7U);
BOOST_CHECK_EQUAL(ss[2], c); BOOST_CHECK_EQUAL(B2I(ss[2]), c);
// Delete at beginning/end/middle // Delete at beginning/end/middle
ss.erase(ss.begin()); ss.erase(ss.begin());
BOOST_CHECK_EQUAL(ss.size(), 6U); BOOST_CHECK_EQUAL(ss.size(), 6U);
BOOST_CHECK_EQUAL(ss[0], 0); BOOST_CHECK_EQUAL(B2I(ss[0]), 0);
ss.erase(ss.begin()+ss.size()-1); ss.erase(ss.begin()+ss.size()-1);
BOOST_CHECK_EQUAL(ss.size(), 5U); BOOST_CHECK_EQUAL(ss.size(), 5U);
BOOST_CHECK_EQUAL(ss[4], 0xff); BOOST_CHECK_EQUAL(B2I(ss[4]), 0xff);
ss.erase(ss.begin()+1); ss.erase(ss.begin()+1);
BOOST_CHECK_EQUAL(ss.size(), 4U); BOOST_CHECK_EQUAL(ss.size(), 4U);
BOOST_CHECK_EQUAL(ss[0], 0); BOOST_CHECK_EQUAL(B2I(ss[0]), 0);
BOOST_CHECK_EQUAL(ss[1], 1); BOOST_CHECK_EQUAL(B2I(ss[1]), 1);
BOOST_CHECK_EQUAL(ss[2], 2); BOOST_CHECK_EQUAL(B2I(ss[2]), 2);
BOOST_CHECK_EQUAL(ss[3], 0xff); BOOST_CHECK_EQUAL(B2I(ss[3]), 0xff);
} }
BOOST_AUTO_TEST_CASE(class_methods) BOOST_AUTO_TEST_CASE(class_methods)

View file

@ -160,7 +160,7 @@ BOOST_AUTO_TEST_CASE(bitstream_reader_writer)
BOOST_AUTO_TEST_CASE(streams_serializedata_xor) BOOST_AUTO_TEST_CASE(streams_serializedata_xor)
{ {
std::vector<uint8_t> in; std::vector<std::byte> in;
std::vector<char> expected_xor; std::vector<char> expected_xor;
std::vector<unsigned char> key; std::vector<unsigned char> key;
CDataStream ds(in, 0, 0); CDataStream ds(in, 0, 0);
@ -174,8 +174,8 @@ BOOST_AUTO_TEST_CASE(streams_serializedata_xor)
std::string(expected_xor.begin(), expected_xor.end()), std::string(expected_xor.begin(), expected_xor.end()),
ds.str()); ds.str());
in.push_back('\x0f'); in.push_back(std::byte{0x0f});
in.push_back('\xf0'); in.push_back(std::byte{0xf0});
expected_xor.push_back('\xf0'); expected_xor.push_back('\xf0');
expected_xor.push_back('\x0f'); expected_xor.push_back('\x0f');
@ -195,8 +195,8 @@ BOOST_AUTO_TEST_CASE(streams_serializedata_xor)
in.clear(); in.clear();
expected_xor.clear(); expected_xor.clear();
in.push_back('\xf0'); in.push_back(std::byte{0xf0});
in.push_back('\x0f'); in.push_back(std::byte{0x0f});
expected_xor.push_back('\x0f'); expected_xor.push_back('\x0f');
expected_xor.push_back('\x00'); expected_xor.push_back('\x00');

View file

@ -6,6 +6,8 @@
#ifndef BITCOIN_UINT256_H #ifndef BITCOIN_UINT256_H
#define BITCOIN_UINT256_H #define BITCOIN_UINT256_H
#include <span.h>
#include <assert.h> #include <assert.h>
#include <cstring> #include <cstring>
#include <stdint.h> #include <stdint.h>
@ -96,13 +98,13 @@ public:
template<typename Stream> template<typename Stream>
void Serialize(Stream& s) const void Serialize(Stream& s) const
{ {
s.write((char*)m_data, sizeof(m_data)); s.write(MakeByteSpan(m_data));
} }
template<typename Stream> template<typename Stream>
void Unserialize(Stream& s) void Unserialize(Stream& s)
{ {
s.read((char*)m_data, sizeof(m_data)); s.read(MakeWritableByteSpan(m_data));
} }
}; };

View file

@ -4104,7 +4104,7 @@ void CChainState::LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp)
try { try {
// locate a header // locate a header
unsigned char buf[CMessageHeader::MESSAGE_START_SIZE]; unsigned char buf[CMessageHeader::MESSAGE_START_SIZE];
blkdat.FindByte(char(m_params.MessageStart()[0])); blkdat.FindByte(m_params.MessageStart()[0]);
nRewind = blkdat.GetPos() + 1; nRewind = blkdat.GetPos() + 1;
blkdat >> buf; blkdat >> buf;
if (memcmp(buf, m_params.MessageStart(), CMessageHeader::MESSAGE_START_SIZE)) { if (memcmp(buf, m_params.MessageStart(), CMessageHeader::MESSAGE_START_SIZE)) {

View file

@ -681,10 +681,10 @@ bool BerkeleyBatch::ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool&
// Convert to streams // Convert to streams
ssKey.SetType(SER_DISK); ssKey.SetType(SER_DISK);
ssKey.clear(); ssKey.clear();
ssKey.write((char*)datKey.get_data(), datKey.get_size()); ssKey.write({BytePtr(datKey.get_data()), datKey.get_size()});
ssValue.SetType(SER_DISK); ssValue.SetType(SER_DISK);
ssValue.clear(); ssValue.clear();
ssValue.write((char*)datValue.get_data(), datValue.get_size()); ssValue.write({BytePtr(datValue.get_data()), datValue.get_size()});
return true; return true;
} }
@ -756,7 +756,7 @@ bool BerkeleyBatch::ReadKey(CDataStream&& key, CDataStream& value)
SafeDbt datValue; SafeDbt datValue;
int ret = pdb->get(activeTxn, datKey, datValue, 0); int ret = pdb->get(activeTxn, datKey, datValue, 0);
if (ret == 0 && datValue.get_data() != nullptr) { if (ret == 0 && datValue.get_data() != nullptr) {
value.write((char*)datValue.get_data(), datValue.get_size()); value.write({BytePtr(datValue.get_data()), datValue.get_size()});
return true; return true;
} }
return false; return false;

View file

@ -47,12 +47,12 @@ bool DumpWallet(CWallet& wallet, bilingual_str& error)
// Write out a magic string with version // Write out a magic string with version
std::string line = strprintf("%s,%u\n", DUMP_MAGIC, DUMP_VERSION); std::string line = strprintf("%s,%u\n", DUMP_MAGIC, DUMP_VERSION);
dump_file.write(line.data(), line.size()); dump_file.write(line.data(), line.size());
hasher.write(line.data(), line.size()); hasher.write(MakeByteSpan(line));
// Write out the file format // Write out the file format
line = strprintf("%s,%s\n", "format", db.Format()); line = strprintf("%s,%s\n", "format", db.Format());
dump_file.write(line.data(), line.size()); dump_file.write(line.data(), line.size());
hasher.write(line.data(), line.size()); hasher.write(MakeByteSpan(line));
if (ret) { if (ret) {
@ -73,7 +73,7 @@ bool DumpWallet(CWallet& wallet, bilingual_str& error)
std::string value_str = HexStr(ss_value); std::string value_str = HexStr(ss_value);
line = strprintf("%s,%s\n", key_str, value_str); line = strprintf("%s,%s\n", key_str, value_str);
dump_file.write(line.data(), line.size()); dump_file.write(line.data(), line.size());
hasher.write(line.data(), line.size()); hasher.write(MakeByteSpan(line));
} }
} }
@ -150,7 +150,7 @@ bool CreateFromDump(const std::string& name, const fs::path& wallet_path, biling
return false; return false;
} }
std::string magic_hasher_line = strprintf("%s,%s\n", magic_key, version_value); std::string magic_hasher_line = strprintf("%s,%s\n", magic_key, version_value);
hasher.write(magic_hasher_line.data(), magic_hasher_line.size()); hasher.write(MakeByteSpan(magic_hasher_line));
// Get the stored file format // Get the stored file format
std::string format_key; std::string format_key;
@ -181,7 +181,7 @@ bool CreateFromDump(const std::string& name, const fs::path& wallet_path, biling
warnings.push_back(strprintf(_("Warning: Dumpfile wallet format \"%s\" does not match command line specified format \"%s\"."), format_value, file_format)); warnings.push_back(strprintf(_("Warning: Dumpfile wallet format \"%s\" does not match command line specified format \"%s\"."), format_value, file_format));
} }
std::string format_hasher_line = strprintf("%s,%s\n", format_key, format_value); std::string format_hasher_line = strprintf("%s,%s\n", format_key, format_value);
hasher.write(format_hasher_line.data(), format_hasher_line.size()); hasher.write(MakeByteSpan(format_hasher_line));
DatabaseOptions options; DatabaseOptions options;
DatabaseStatus status; DatabaseStatus status;
@ -225,7 +225,7 @@ bool CreateFromDump(const std::string& name, const fs::path& wallet_path, biling
} }
std::string line = strprintf("%s,%s\n", key, value); std::string line = strprintf("%s,%s\n", key, value);
hasher.write(line.data(), line.size()); hasher.write(MakeByteSpan(line));
if (key.empty() || value.empty()) { if (key.empty() || value.empty()) {
continue; continue;

View file

@ -395,9 +395,9 @@ bool SQLiteBatch::ReadKey(CDataStream&& key, CDataStream& value)
return false; return false;
} }
// Leftmost column in result is index 0 // Leftmost column in result is index 0
const char* data = reinterpret_cast<const char*>(sqlite3_column_blob(m_read_stmt, 0)); const std::byte* data{BytePtr(sqlite3_column_blob(m_read_stmt, 0))};
int data_size = sqlite3_column_bytes(m_read_stmt, 0); size_t data_size(sqlite3_column_bytes(m_read_stmt, 0));
value.write(data, data_size); value.write({data, data_size});
sqlite3_clear_bindings(m_read_stmt); sqlite3_clear_bindings(m_read_stmt);
sqlite3_reset(m_read_stmt); sqlite3_reset(m_read_stmt);
@ -512,12 +512,12 @@ bool SQLiteBatch::ReadAtCursor(CDataStream& key, CDataStream& value, bool& compl
} }
// Leftmost column in result is index 0 // Leftmost column in result is index 0
const char* key_data = reinterpret_cast<const char*>(sqlite3_column_blob(m_cursor_stmt, 0)); const std::byte* key_data{BytePtr(sqlite3_column_blob(m_cursor_stmt, 0))};
int key_data_size = sqlite3_column_bytes(m_cursor_stmt, 0); size_t key_data_size(sqlite3_column_bytes(m_cursor_stmt, 0));
key.write(key_data, key_data_size); key.write({key_data, key_data_size});
const char* value_data = reinterpret_cast<const char*>(sqlite3_column_blob(m_cursor_stmt, 1)); const std::byte* value_data{BytePtr(sqlite3_column_blob(m_cursor_stmt, 1))};
int value_data_size = sqlite3_column_bytes(m_cursor_stmt, 1); size_t value_data_size(sqlite3_column_bytes(m_cursor_stmt, 1));
value.write(value_data, value_data_size); value.write({value_data, value_data_size});
return true; return true;
} }