merge bitcoin#23438: Use spans of std::byte in serialize

continuation of de54b878 from dash#5574
This commit is contained in:
Kittywhiskers Van Gogh 2024-02-24 07:36:25 +00:00 committed by pasta
parent d3b282208b
commit e933d78a88
No known key found for this signature in database
GPG Key ID: 52527BEDABE87984
32 changed files with 210 additions and 208 deletions

View File

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

View File

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

View File

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

View File

@ -167,7 +167,7 @@ public:
template <typename Stream>
inline void Serialize(Stream& s, const bool specificLegacyScheme) const
{
s.write(reinterpret_cast<const char*>(ToByteVector(specificLegacyScheme).data()), SerSize);
s.write(AsBytes(Span{ToByteVector(specificLegacyScheme).data(), SerSize}));
}
template <typename Stream>
@ -180,7 +180,7 @@ public:
inline void Unserialize(Stream& s, const bool specificLegacyScheme)
{
std::array<uint8_t, SerSize> vecBytes{};
s.read(reinterpret_cast<char*>(vecBytes.data()), SerSize);
s.read(AsWritableBytes(Span{vecBytes.data(), SerSize}));
SetByteVector(vecBytes, specificLegacyScheme);
if (!CheckMalleable(vecBytes, specificLegacyScheme)) {
@ -456,7 +456,7 @@ public:
bufLegacyScheme = specificLegacyScheme;
hash.SetNull();
}
s.write(reinterpret_cast<const char*>(vecBytes.data()), vecBytes.size());
s.write(MakeByteSpan(vecBytes));
}
template<typename Stream>
@ -469,7 +469,7 @@ public:
inline void Unserialize(Stream& s, const bool specificLegacyScheme) const
{
std::unique_lock<std::mutex> l(mutex);
s.read(reinterpret_cast<char*>(vecBytes.data()), BLSObject::SerSize);
s.read(AsWritableBytes(Span{vecBytes.data(), BLSObject::SerSize}));
bufValid = true;
bufLegacyScheme = specificLegacyScheme;
objInitialized = false;
@ -543,7 +543,7 @@ public:
}
if (hash.IsNull()) {
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
ss.write(reinterpret_cast<const char*>(vecBytes.data()), vecBytes.size());
ss.write(MakeByteSpan(vecBytes));
hash = ss.GetHash();
}
return hash;

View File

@ -109,7 +109,7 @@ public:
ds.clear();
ds << _objects[i];
blobs[i].assign(ds.begin(), ds.end());
blobs[i].assign(UCharCast(ds.data()), UCharCast(ds.data() + ds.size()));
}
} catch (const std::exception&) {
return false;
@ -122,7 +122,7 @@ public:
{
CDataStream ds(SER_NETWORK, nVersion);
ds << obj;
Blob blob(ds.begin(), ds.end());
Blob blob(UCharCast(ds.data()), UCharCast(ds.data() + ds.size()));
return CBLSIESMultiRecipientBlobs::Encrypt(idx, recipient, blob);
}

View File

@ -169,7 +169,7 @@ public:
CDataStream GetKey() {
leveldb::Slice slKey = piter->key();
return CDataStream(MakeUCharSpan(slKey), SER_DISK, CLIENT_VERSION);
return CDataStream{MakeByteSpan(slKey), SER_DISK, CLIENT_VERSION};
}
unsigned int GetKeySize() {
@ -179,7 +179,7 @@ public:
template<typename V> bool GetValue(V& value) {
leveldb::Slice slValue = piter->value();
try {
CDataStream ssValue(MakeUCharSpan(slValue), SER_DISK, CLIENT_VERSION);
CDataStream ssValue{MakeByteSpan(slValue), SER_DISK, CLIENT_VERSION};
ssValue.Xor(dbwrapper_private::GetObfuscateKey(parent));
ssValue >> value;
} catch (const std::exception&) {
@ -269,7 +269,7 @@ public:
LogPrintf("LevelDB read failure: %s\n", status.ToString());
dbwrapper_private::HandleError(status);
}
CDataStream ssValueTmp(MakeUCharSpan(strValue), SER_DISK, CLIENT_VERSION);
CDataStream ssValueTmp{MakeByteSpan(strValue), SER_DISK, CLIENT_VERSION};
ssValueTmp.Xor(obfuscate_key);
ssValue = std::move(ssValueTmp);
return true;

View File

@ -40,7 +40,7 @@ void SetTxPayload(CMutableTransaction& tx, const T& payload)
{
CDataStream ds(SER_NETWORK, PROTOCOL_VERSION);
ds << payload;
tx.vExtraPayload.assign(ds.begin(), ds.end());
tx.vExtraPayload.assign(UCharCast(ds.data()), UCharCast(ds.data() + ds.size()));
}
uint256 CalcTxInputsHash(const CTransaction& tx);

View File

@ -97,7 +97,7 @@ private:
// read data and checksum from file
try {
filein.read((char *)vchData.data(), dataSize);
filein.read(MakeWritableByteSpan(vchData));
filein >> hashIn;
}
catch (std::exception &e) {

View File

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

View File

@ -62,7 +62,7 @@ void CDKGPendingMessages::PushPendingMessage(NodeId from, PeerManager* peerman,
auto pm = std::make_shared<CDataStream>(std::move(vRecv));
CHashWriter hw(SER_GETHASH, 0);
hw.write(reinterpret_cast<const char*>(pm->data()), pm->size());
hw.write(AsWritableBytes(Span{*pm}));
uint256 hash = hw.GetHash();
if (from != -1) {

View File

@ -4289,11 +4289,11 @@ void CaptureMessage(const CAddress& addr, const std::string& msg_type, const Spa
CAutoFile f(fsbridge::fopen(path, "ab"), SER_DISK, CLIENT_VERSION);
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) {
f << uint8_t{'\0'};
}
uint32_t size = data.size();
ser_writedata32(f, size);
f.write((const char*)data.data(), data.size());
f.write(AsBytes(data));
}

View File

@ -318,7 +318,7 @@ bool DecodeBase64PSBT(PartiallySignedTransaction& psbt, const std::string& base6
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 {
ss_data >> psbt;
if (!ss_data.empty()) {

View File

@ -135,14 +135,14 @@ public:
{
unsigned int len = size();
::WriteCompactSize(s, len);
s.write((char*)vch, len);
s.write(AsBytes(Span{vch, len}));
}
template <typename Stream>
void Unserialize(Stream& s)
{
const unsigned int len(::ReadCompactSize(s));
if (len <= SIZE) {
s.read((char*)vch, len);
s.read(AsWritableBytes(Span{vch, len}));
if (len != size()) {
Invalidate();
}
@ -269,7 +269,7 @@ struct CExtPubKey {
::WriteCompactSize(s, len);
unsigned char code[BIP32_EXTKEY_SIZE];
Encode(code);
s.write((const char *)&code[0], len);
s.write(AsBytes(Span{&code[0], len}));
}
template <typename Stream>
void Unserialize(Stream& s)
@ -278,7 +278,7 @@ struct CExtPubKey {
unsigned char code[BIP32_EXTKEY_SIZE];
if (len != BIP32_EXTKEY_SIZE)
throw std::runtime_error("Invalid extended key size\n");
s.read((char *)&code[0], len);
s.read(AsWritableBytes(Span{&code[0], len}));
Decode(code);
}
};

View File

@ -229,7 +229,7 @@ static void FundSpecialTx(CWallet* pwallet, CMutableTransaction& tx, const Speci
CDataStream ds(SER_NETWORK, PROTOCOL_VERSION);
ds << payload;
tx.vExtraPayload.assign(ds.begin(), ds.end());
tx.vExtraPayload.assign(UCharCast(ds.data()), UCharCast(ds.data() + ds.size()));
static const CTxOut dummyTxOut(0, CScript() << OP_RETURN);
std::vector<CRecipient> vecSend;

View File

@ -22,20 +22,23 @@ public:
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");
}
if (pch == nullptr)
if (dst.data() == nullptr) {
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");
}
memcpy(pch, m_data, nSize);
m_remaining -= nSize;
m_data += nSize;
memcpy(dst.data(), m_data, dst.size());
m_remaining -= dst.size();
m_data += dst.size();
}
template<typename T>

View File

@ -1418,12 +1418,12 @@ public:
it = itBegin;
while (scriptCode.GetOp(it, opcode)) {
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;
}
}
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 */

View File

@ -51,79 +51,72 @@ static const unsigned int MAX_VECTOR_ALLOCATE = 5000000;
struct deserialize_type {};
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.
* @note Sizes of these types are verified in the tests
*/
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)
{
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)
{
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)
{
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)
{
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)
{
obj = htole64(obj);
s.write((char*)&obj, 8);
s.write(AsBytes(Span{&obj, 1}));
}
template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
{
uint8_t obj;
s.read((char*)&obj, 1);
s.read(AsWritableBytes(Span{&obj, 1}));
return obj;
}
template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
{
uint16_t obj;
s.read((char*)&obj, 2);
s.read(AsWritableBytes(Span{&obj, 1}));
return le16toh(obj);
}
template<typename Stream> inline uint16_t ser_readdata16be(Stream &s)
{
uint16_t obj;
s.read((char*)&obj, 2);
s.read(AsWritableBytes(Span{&obj, 1}));
return be16toh(obj);
}
template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
{
uint32_t obj;
s.read((char*)&obj, 4);
s.read(AsWritableBytes(Span{&obj, 1}));
return le32toh(obj);
}
template<typename Stream> inline uint32_t ser_readdata32be(Stream &s)
{
uint32_t obj;
s.read((char*)&obj, 4);
s.read(AsWritableBytes(Span{&obj, 1}));
return be32toh(obj);
}
template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
{
uint64_t obj;
s.read((char*)&obj, 8);
s.read(AsWritableBytes(Span{&obj, 1}));
return le64toh(obj);
}
@ -131,7 +124,7 @@ template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
/////////////////////////////////////////////////////////////////
//
// 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;
@ -200,7 +193,7 @@ template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; }
FORMATTER_METHODS(cls, obj)
#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
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); }
@ -210,13 +203,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, 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, 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 unsigned char (&a)[N]) { s.write(CharCast(a), N); }
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<unsigned char>& span) { s.write(CharCast(span.data()), span.size()); }
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(MakeByteSpan(a)); }
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(AsBytes(span)); }
#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
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); }
@ -226,9 +219,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, 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, int N> inline void Unserialize(Stream& s, char (&a)[N]) { s.read(a, N); }
template<typename Stream, int N> inline void Unserialize(Stream& s, unsigned char (&a)[N]) { s.read(CharCast(a), N); }
template<typename Stream> inline void Unserialize(Stream& s, Span<unsigned char>& span) { s.read(CharCast(span.data()), span.size()); }
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(MakeWritableByteSpan(a)); }
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 Unserialize(Stream& s, bool& a) { uint8_t f = ser_readdata8(s); a = f; }
@ -426,11 +419,11 @@ inline unsigned int GetSizeOfFixedBitSet(size_t size)
template<typename Stream>
void WriteFixedBitSet(Stream& s, const std::vector<bool>& vec, size_t size)
{
std::vector<unsigned char> vBytes((size + 7) / 8);
std::vector<uint8_t> vBytes((size + 7) / 8);
size_t ms = std::min(size, vec.size());
for (size_t p = 0; p < ms; p++)
vBytes[p / 8] |= vec[p] << (p % 8);
s.write((char*)vBytes.data(), vBytes.size());
s.write(AsBytes(Span{vBytes}));
}
template<typename Stream>
@ -438,8 +431,8 @@ void ReadFixedBitSet(Stream& s, std::vector<bool>& vec, size_t size)
{
vec.resize(size);
std::vector<unsigned char> vBytes((size + 7) / 8);
s.read((char*)vBytes.data(), vBytes.size());
std::vector<uint8_t> vBytes((size + 7) / 8);
s.read(AsWritableBytes(Span{vBytes}));
for (size_t p = 0; p < size; p++)
vec[p] = (vBytes[p / 8] & (1 << (p % 8))) != 0;
if (vBytes.size() * 8 != size) {
@ -660,10 +653,10 @@ struct CustomUintFormatter
if (v < 0 || v > MAX) throw std::ios_base::failure("CustomUintFormatter value out of range");
if (BigEndian) {
uint64_t raw = htobe64(v);
s.write(((const char*)&raw) + 8 - Bytes, Bytes);
s.write({BytePtr(&raw) + 8 - Bytes, Bytes});
} else {
uint64_t raw = htole64(v);
s.write((const char*)&raw, Bytes);
s.write({BytePtr(&raw), Bytes});
}
}
@ -673,10 +666,10 @@ struct CustomUintFormatter
static_assert(std::numeric_limits<U>::max() >= MAX && std::numeric_limits<U>::min() <= 0, "Assigned type too small");
uint64_t raw = 0;
if (BigEndian) {
s.read(((char*)&raw) + 8 - Bytes, Bytes);
s.read({BytePtr(&raw) + 8 - Bytes, Bytes});
v = static_cast<I>(be64toh(raw));
} else {
s.read((char*)&raw, Bytes);
s.read({BytePtr(&raw), Bytes});
v = static_cast<I>(le64toh(raw));
}
}
@ -719,7 +712,7 @@ struct LimitedStringFormatter
throw std::ios_base::failure("String length limit exceeded");
}
v.resize(size);
if (size != 0) s.read((char*)v.data(), size);
if (size != 0) s.read(MakeWritableByteSpan(v));
}
template<typename Stream>
@ -929,7 +922,7 @@ void Serialize(Stream& os, const std::basic_string<C>& str)
{
WriteCompactSize(os, str.size());
if (!str.empty())
os.write((char*)str.data(), str.size() * sizeof(C));
os.write(MakeByteSpan(str));
}
template<typename Stream, typename C>
@ -938,7 +931,7 @@ void Unserialize(Stream& is, std::basic_string<C>& str)
unsigned int nSize = ReadCompactSize(is);
str.resize(nSize);
if (nSize != 0)
is.read((char*)str.data(), nSize * sizeof(C));
is.read(MakeWritableByteSpan(str));
}
/**
@ -949,7 +942,7 @@ void Serialize(Stream& os, const std::basic_string_view<C>& str)
{
WriteCompactSize(os, str.size());
if (!str.empty())
os.write((char*)str.data(), str.size() * sizeof(C));
os.write(AsBytes(Span{str.data(), str.size() * sizeof(C)}));
}
template<typename Stream, typename C>
@ -958,7 +951,7 @@ void Unserialize(Stream& is, std::basic_string_view<C>& str)
unsigned int nSize = ReadCompactSize(is);
str.resize(nSize);
if (nSize != 0)
is.read((char*)str.data(), nSize * sizeof(C));
is.read(AsWritableBytes(Span{str.data(), nSize * sizeof(C)}));
}
@ -970,7 +963,7 @@ void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&)
{
WriteCompactSize(os, v.size());
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>
@ -997,7 +990,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)));
v.resize_uninitialized(i + blk);
is.read((char*)&v[i], blk * sizeof(T));
is.read(AsWritableBytes(Span{&v[i], blk}));
i += blk;
}
}
@ -1024,7 +1017,7 @@ void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&
{
WriteCompactSize(os, v.size());
if (!v.empty())
os.write((char*)v.data(), v.size() * sizeof(T));
os.write(MakeByteSpan(v));
}
template<typename Stream, typename T, typename A>
@ -1063,7 +1056,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)));
v.resize(i + blk);
is.read((char*)&v[i], blk * sizeof(T));
is.read(AsWritableBytes(Span{&v[i], blk}));
i += blk;
}
}
@ -1365,9 +1358,9 @@ protected:
public:
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. */

View File

@ -49,14 +49,14 @@ public:
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; }
@ -94,17 +94,17 @@ class CVectorWriter
{
::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());
size_t nOverwrite = std::min(nSize, vchData.size() - nPos);
size_t nOverwrite = std::min(src.size(), vchData.size() - nPos);
if (nOverwrite) {
memcpy(vchData.data() + nPos, reinterpret_cast<const unsigned char*>(pch), nOverwrite);
memcpy(vchData.data() + nPos, src.data(), nOverwrite);
}
if (nOverwrite < nSize) {
vchData.insert(vchData.end(), reinterpret_cast<const unsigned char*>(pch) + nOverwrite, reinterpret_cast<const unsigned char*>(pch) + nSize);
if (nOverwrite < src.size()) {
vchData.insert(vchData.end(), UCharCast(src.data()) + nOverwrite, UCharCast(src.end()));
}
nPos += nSize;
nPos += src.size();
}
template<typename T>
CVectorWriter& operator<<(const T& obj)
@ -184,18 +184,18 @@ public:
size_t size() const { return m_data.size(); }
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;
}
// 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");
}
memcpy(dst, m_data.data(), n);
m_data = m_data.subspan(n);
memcpy(dst.data(), m_data.data(), dst.size());
m_data = m_data.subspan(dst.size());
}
};
@ -229,6 +229,7 @@ public:
: nType{nTypeIn},
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)
: vch(sp.data(), sp.data() + sp.size()),
nType{nTypeIn},
@ -244,7 +245,7 @@ public:
std::string str() const
{
return (std::string(begin(), end()));
return std::string{UCharCast(data()), UCharCast(data() + size())};
}
@ -365,16 +366,16 @@ public:
void SetVersion(int n) { nVersion = n; }
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
unsigned int nReadPosNext = nReadPos + nSize;
unsigned int nReadPosNext = nReadPos + dst.size();
if (nReadPosNext > vch.size()) {
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())
{
nReadPos = 0;
@ -402,10 +403,10 @@ public:
nReadPos = nReadPosNext;
}
void write(const char* pch, size_t nSize)
void write(Span<const value_type> src)
{
// 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>
@ -413,7 +414,7 @@ public:
{
// Special case: stream << stream concatenates like stream += stream
if (!vch.empty())
s.write((char*)vch.data(), vch.size() * sizeof(value_type));
s.write(MakeByteSpan(vch));
}
template<typename T>
@ -444,7 +445,7 @@ public:
}
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
// important that we calculate `j`, i.e. the `key` index in this
@ -617,12 +618,13 @@ public:
int GetType() const { return nType; }
int GetVersion() const { return nVersion; }
void read(char* pch, size_t nSize)
void read(Span<std::byte> dst)
{
if (!file)
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");
}
}
void ignore(size_t nSize)
@ -638,12 +640,13 @@ public:
}
}
void write(const char* pch, size_t nSize)
void write(Span<const std::byte> src)
{
if (!file)
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");
}
}
template<typename T>
@ -684,7 +687,7 @@ private:
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 nRewind; //!< how many bytes we guarantee to rewind
std::vector<char> vchBuf; //!< the buffer
std::vector<std::byte> vchBuf; //!< the buffer
protected:
//! read data from the source to fill the buffer
@ -705,8 +708,8 @@ protected:
}
public:
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)
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, std::byte{0})
{
if (nRewindIn >= nBufSize)
throw std::ios_base::failure("Rewind limit must be less than buffer size");
@ -739,22 +742,23 @@ public:
}
//! read a number of bytes
void read(char *pch, size_t nSize) {
if (nSize + nReadPos > nReadLimit)
void read(Span<std::byte> dst)
{
if (dst.size() + nReadPos > nReadLimit) {
throw std::ios_base::failure("Read attempted past buffer limit");
while (nSize > 0) {
}
while (dst.size() > 0) {
if (nReadPos == nSrcPos)
Fill();
unsigned int pos = nReadPos % vchBuf.size();
size_t nNow = nSize;
size_t nNow = dst.size();
if (nNow + pos > vchBuf.size())
nNow = vchBuf.size() - pos;
if (nNow + nReadPos > nSrcPos)
nNow = nSrcPos - nReadPos;
memcpy(pch, &vchBuf[pos], nNow);
memcpy(dst.data(), &vchBuf[pos], nNow);
nReadPos += nNow;
pch += nNow;
nSize -= nNow;
dst = dst.subspan(nNow);
}
}
@ -797,12 +801,14 @@ public:
}
//! search for a given byte in the stream, and remain positioned on it
void FindByte(char ch) {
void FindByte(uint8_t ch)
{
while (true) {
if (nReadPos == nSrcPos)
Fill();
if (vchBuf[nReadPos % vchBuf.size()] == ch)
if (vchBuf[nReadPos % vchBuf.size()] == std::byte{ch}) {
break;
}
nReadPos++;
}
}

View File

@ -41,6 +41,6 @@ struct zero_after_free_allocator : public std::allocator<T> {
};
/** 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

View File

@ -41,8 +41,9 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize)
stream << filter;
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!");
}
@ -67,8 +68,9 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize_with_tweak)
stream << filter;
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)
@ -87,8 +89,9 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_key)
stream << filter;
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)
@ -443,8 +446,9 @@ BOOST_AUTO_TEST_CASE(merkle_block_3_and_serialize)
merkleStream << merkleBlock;
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)

View File

@ -22,16 +22,16 @@ FUZZ_TARGET(autofile)
CallOneOf(
fuzzed_data_provider,
[&] {
std::array<uint8_t, 4096> arr{};
std::array<std::byte, 4096> arr{};
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&) {
}
},
[&] {
const std::array<uint8_t, 4096> arr{};
const std::array<std::byte, 4096> arr{};
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&) {
}
},

View File

@ -33,9 +33,9 @@ FUZZ_TARGET(buffered_file)
CallOneOf(
fuzzed_data_provider,
[&] {
std::array<uint8_t, 4096> arr{};
std::array<std::byte, 4096> arr{};
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&) {
}
},
@ -53,7 +53,7 @@ FUZZ_TARGET(buffered_file)
return;
}
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&) {
}
},

View File

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

View File

@ -498,7 +498,6 @@ void WriteToStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) noe
CallOneOf(
fuzzed_data_provider,
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(uint8_t, fuzzed_data_provider.ConsumeIntegral<uint8_t>()),
WRITE_TO_STREAM_CASE(int16_t, fuzzed_data_provider.ConsumeIntegral<int16_t>()),
@ -508,7 +507,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(uint64_t, fuzzed_data_provider.ConsumeIntegral<uint64_t>()),
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&) {
break;
}
@ -528,7 +527,6 @@ void ReadFromStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) no
CallOneOf(
fuzzed_data_provider,
READ_FROM_STREAM_CASE(bool),
READ_FROM_STREAM_CASE(char),
READ_FROM_STREAM_CASE(int8_t),
READ_FROM_STREAM_CASE(uint8_t),
READ_FROM_STREAM_CASE(int16_t),
@ -538,7 +536,7 @@ void ReadFromStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) no
READ_FROM_STREAM_CASE(int64_t),
READ_FROM_STREAM_CASE(uint64_t),
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&) {
break;
}

View File

@ -147,7 +147,7 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, uint32_t flag
uint32_t libconsensus_flags{flags & dashconsensus_SCRIPT_FLAGS_VERIFY_ALL};
if (libconsensus_flags == flags) {
int expectedSuccessCode = expect ? 1 : 0;
BOOST_CHECK_MESSAGE(dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
BOOST_CHECK_MESSAGE(dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
}
#endif
}
@ -1421,7 +1421,7 @@ BOOST_AUTO_TEST_CASE(dashconsensus_verify_script_returns_true)
stream << spendTx;
dashconsensus_error err;
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err);
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 1);
BOOST_CHECK_EQUAL(err, dashconsensus_ERR_OK);
}
@ -1443,7 +1443,7 @@ BOOST_AUTO_TEST_CASE(dashconsensus_verify_script_tx_index_err)
stream << spendTx;
dashconsensus_error err;
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err);
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, dashconsensus_ERR_TX_INDEX);
}
@ -1465,7 +1465,7 @@ BOOST_AUTO_TEST_CASE(dashconsensus_verify_script_tx_size)
stream << spendTx;
dashconsensus_error err;
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size() * 2, nIn, libconsensus_flags, &err);
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size() * 2, nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, dashconsensus_ERR_TX_SIZE_MISMATCH);
}
@ -1487,7 +1487,7 @@ BOOST_AUTO_TEST_CASE(dashconsensus_verify_script_tx_serialization)
stream << 0xffffffff;
dashconsensus_error err;
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err);
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, dashconsensus_ERR_TX_DESERIALIZE);
}
@ -1509,7 +1509,7 @@ BOOST_AUTO_TEST_CASE(dashconsensus_verify_script_invalid_flags)
stream << spendTx;
dashconsensus_error err;
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), stream.data(), stream.size(), nIn, libconsensus_flags, &err);
int result = dashconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
BOOST_CHECK_EQUAL(result, 0);
BOOST_CHECK_EQUAL(err, dashconsensus_ERR_INVALID_FLAGS);
}

View File

@ -61,7 +61,7 @@ public:
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(uint8_t), GetSerializeSize(uint8_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));
// 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(uint8_t(0), 0), 1U);
BOOST_CHECK_EQUAL(GetSerializeSize(int16_t(0), 0), 2U);
@ -186,76 +186,78 @@ BOOST_AUTO_TEST_CASE(noncanonical)
std::vector<char>::size_type n;
// 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);
// 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);
// 0xfd encoded with three bytes is OK:
ss.write("\xfd\xfd\x00", 3);
ss.write(MakeByteSpan("\xfd\xfd\x00").first(3));
n = ReadCompactSize(ss);
BOOST_CHECK(n == 0xfd);
// 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);
// 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);
// 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);
// 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_AUTO_TEST_CASE(insert_delete)
{
constexpr auto B2I{[](std::byte b) { return std::to_integer<uint8_t>(b); }};
// Test inserting/deleting bytes.
CDataStream ss(SER_DISK, 0);
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);
char c = (char)11;
uint8_t c{11};
// 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[0], c);
BOOST_CHECK_EQUAL(ss[1], 0);
BOOST_CHECK_EQUAL(B2I(ss[0]), c);
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[4], 0xff);
BOOST_CHECK_EQUAL(ss[5], c);
BOOST_CHECK_EQUAL(B2I(ss[4]), 0xff);
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[2], c);
BOOST_CHECK_EQUAL(B2I(ss[2]), c);
// Delete at beginning/end/middle
ss.erase(ss.begin());
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);
BOOST_CHECK_EQUAL(ss.size(), 5U);
BOOST_CHECK_EQUAL(ss[4], 0xff);
BOOST_CHECK_EQUAL(B2I(ss[4]), 0xff);
ss.erase(ss.begin()+1);
BOOST_CHECK_EQUAL(ss.size(), 4U);
BOOST_CHECK_EQUAL(ss[0], 0);
BOOST_CHECK_EQUAL(ss[1], 1);
BOOST_CHECK_EQUAL(ss[2], 2);
BOOST_CHECK_EQUAL(ss[3], 0xff);
BOOST_CHECK_EQUAL(B2I(ss[0]), 0);
BOOST_CHECK_EQUAL(B2I(ss[1]), 1);
BOOST_CHECK_EQUAL(B2I(ss[2]), 2);
BOOST_CHECK_EQUAL(B2I(ss[3]), 0xff);
}
// Change struct size and check if it can be deserialized

View File

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

View File

@ -191,7 +191,7 @@ public:
private:
std::unique_ptr<CDBIterator> pcursor;
std::pair<char, COutPoint> keyTmp;
std::pair<uint8_t, COutPoint> keyTmp;
friend class CCoinsViewDB;
};
@ -299,7 +299,7 @@ bool CBlockTreeDB::ReadAddressUnspentIndex(uint160 addressHash, AddressType type
pcursor->Seek(std::make_pair(DB_ADDRESSUNSPENTINDEX, CAddressIndexIteratorKey(type, addressHash)));
while (pcursor->Valid()) {
std::pair<char,CAddressUnspentKey> key;
std::pair<uint8_t, CAddressUnspentKey> key;
if (pcursor->GetKey(key) && key.first == DB_ADDRESSUNSPENTINDEX && key.second.m_address_bytes == addressHash) {
CAddressUnspentValue nValue;
if (pcursor->GetValue(nValue)) {
@ -343,7 +343,7 @@ bool CBlockTreeDB::ReadAddressIndex(uint160 addressHash, AddressType type,
}
while (pcursor->Valid()) {
std::pair<char,CAddressIndexKey> key;
std::pair<uint8_t, CAddressIndexKey> key;
if (pcursor->GetKey(key) && key.first == DB_ADDRESSINDEX && key.second.m_address_bytes == addressHash) {
if (end > 0 && key.second.m_block_height > end) {
break;
@ -383,7 +383,7 @@ bool CBlockTreeDB::ReadTimestampIndex(const unsigned int &high, const unsigned i
pcursor->Seek(std::make_pair(DB_TIMESTAMPINDEX, CTimestampIndexIteratorKey(low)));
while (pcursor->Valid()) {
std::pair<char, CTimestampIndexKey> key;
std::pair<uint8_t, CTimestampIndexKey> key;
if (pcursor->GetKey(key) && key.first == DB_TIMESTAMPINDEX && key.second.m_block_time <= high) {
hashes.push_back(key.second.m_block_hash);
pcursor->Next();

View File

@ -78,13 +78,13 @@ public:
template<typename Stream>
void Serialize(Stream& s) const
{
s.write((char*)m_data.data(), sizeof(m_data));
s.write(MakeByteSpan(m_data));
}
template<typename Stream>
void Unserialize(Stream& s)
{
s.read((char*)m_data.data(), sizeof(m_data));
s.read(MakeWritableByteSpan(m_data));
}
};

View File

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

View File

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

View File

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