Skip to content

Commit 8203c4c

Browse files
committed
Merge #12740: Add native support for serializing char arrays without FLATDATA
a7c45bc Add native support for serializing char arrays without FLATDATA (Pieter Wuille) Pull request description: Support is added to serialize arrays of type `char` or `unsigned char` directly, without any wrappers. All invocations of the `FLATDATA` wrappers that are obsoleted by this are removed. This includes a patch by @ryanofsky to make `char` casting type safe. The serialization of `CSubNet` is changed to serialize a `bool` directly rather than though `FLATDATA`. This makes the serialization independent of the size of the bool type (and will use 1 byte everywhere). This is a small change taken from #10785. Tree-SHA512: a41f61ca5fdc2fadb2d0e1702351a58a23841d551f505292a9542602cdb19f90d8944b8df14b872810a56bd201648fa4c0e958f3e9427fe829886284e85b9bfd
2 parents d2d7267 + a7c45bc commit 8203c4c

File tree

8 files changed

+40
-26
lines changed

8 files changed

+40
-26
lines changed

src/addrdb.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ bool SerializeDB(Stream& stream, const Data& data)
2222
// Write and commit header, data
2323
try {
2424
CHashWriter hasher(SER_DISK, CLIENT_VERSION);
25-
stream << FLATDATA(Params().MessageStart()) << data;
26-
hasher << FLATDATA(Params().MessageStart()) << data;
25+
stream << Params().MessageStart() << data;
26+
hasher << Params().MessageStart() << data;
2727
stream << hasher.GetHash();
2828
} catch (const std::exception& e) {
2929
return error("%s: Serialize or I/O error - %s", __func__, e.what());
@@ -66,7 +66,7 @@ bool DeserializeDB(Stream& stream, Data& data, bool fCheckSum = true)
6666
CHashVerifier<Stream> verifier(&stream);
6767
// de-serialize file header (network specific magic number) and ..
6868
unsigned char pchMsgTmp[4];
69-
verifier >> FLATDATA(pchMsgTmp);
69+
verifier >> pchMsgTmp;
7070
// ... verify the network matches ours
7171
if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
7272
return error("%s: Invalid network magic number", __func__);

src/netaddress.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class CNetAddr
9393

9494
template <typename Stream, typename Operation>
9595
inline void SerializationOp(Stream& s, Operation ser_action) {
96-
READWRITE(FLATDATA(ip));
96+
READWRITE(ip);
9797
}
9898

9999
friend class CSubNet;
@@ -131,8 +131,8 @@ class CSubNet
131131
template <typename Stream, typename Operation>
132132
inline void SerializationOp(Stream& s, Operation ser_action) {
133133
READWRITE(network);
134-
READWRITE(FLATDATA(netmask));
135-
READWRITE(FLATDATA(valid));
134+
READWRITE(netmask);
135+
READWRITE(valid);
136136
}
137137
};
138138

@@ -166,7 +166,7 @@ class CService : public CNetAddr
166166

167167
template <typename Stream, typename Operation>
168168
inline void SerializationOp(Stream& s, Operation ser_action) {
169-
READWRITE(FLATDATA(ip));
169+
READWRITE(ip);
170170
unsigned short portN = htons(port);
171171
READWRITE(FLATDATA(portN));
172172
if (ser_action.ForRead())

src/protocol.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ class CMessageHeader
4848
template <typename Stream, typename Operation>
4949
inline void SerializationOp(Stream& s, Operation ser_action)
5050
{
51-
READWRITE(FLATDATA(pchMessageStart));
52-
READWRITE(FLATDATA(pchCommand));
51+
READWRITE(pchMessageStart);
52+
READWRITE(pchCommand);
5353
READWRITE(nMessageSize);
54-
READWRITE(FLATDATA(pchChecksum));
54+
READWRITE(pchChecksum);
5555
}
5656

5757
char pchMessageStart[MESSAGE_START_SIZE];

src/serialize.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ inline T* NCONST_PTR(const T* val)
5959
return const_cast<T*>(val);
6060
}
6161

62+
//! Safely convert odd char pointer types to standard ones.
63+
inline char* CharCast(char* c) { return c; }
64+
inline char* CharCast(unsigned char* c) { return (char*)c; }
65+
inline const char* CharCast(const char* c) { return c; }
66+
inline const char* CharCast(const unsigned char* c) { return (const char*)c; }
67+
6268
/*
6369
* Lowest-level serialization and conversion.
6470
* @note Sizes of these types are verified in the tests
@@ -177,6 +183,8 @@ template<typename Stream> inline void Serialize(Stream& s, int64_t a ) { ser_wri
177183
template<typename Stream> inline void Serialize(Stream& s, uint64_t a) { ser_writedata64(s, a); }
178184
template<typename Stream> inline void Serialize(Stream& s, float a ) { ser_writedata32(s, ser_float_to_uint32(a)); }
179185
template<typename Stream> inline void Serialize(Stream& s, double a ) { ser_writedata64(s, ser_double_to_uint64(a)); }
186+
template<typename Stream, int N> inline void Serialize(Stream& s, const char (&a)[N]) { s.write(a, N); }
187+
template<typename Stream, int N> inline void Serialize(Stream& s, const unsigned char (&a)[N]) { s.write(CharCast(a), N); }
180188

181189
template<typename Stream> inline void Unserialize(Stream& s, char& a ) { a = ser_readdata8(s); } // TODO Get rid of bare char
182190
template<typename Stream> inline void Unserialize(Stream& s, int8_t& a ) { a = ser_readdata8(s); }
@@ -189,6 +197,8 @@ template<typename Stream> inline void Unserialize(Stream& s, int64_t& a ) { a =
189197
template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a) { a = ser_readdata64(s); }
190198
template<typename Stream> inline void Unserialize(Stream& s, float& a ) { a = ser_uint32_to_float(ser_readdata32(s)); }
191199
template<typename Stream> inline void Unserialize(Stream& s, double& a ) { a = ser_uint64_to_double(ser_readdata64(s)); }
200+
template<typename Stream, int N> inline void Unserialize(Stream& s, char (&a)[N]) { s.read(a, N); }
201+
template<typename Stream, int N> inline void Unserialize(Stream& s, unsigned char (&a)[N]) { s.read(CharCast(a), N); }
192202

193203
template<typename Stream> inline void Serialize(Stream& s, bool a) { char f=a; ser_writedata8(s, f); }
194204
template<typename Stream> inline void Unserialize(Stream& s, bool& a) { char f=ser_readdata8(s); a=f; }

src/test/net_tests.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class CAddrManCorrupted : public CAddrManSerializationMock
6464
CDataStream AddrmanToStream(CAddrManSerializationMock& _addrman)
6565
{
6666
CDataStream ssPeersIn(SER_DISK, CLIENT_VERSION);
67-
ssPeersIn << FLATDATA(Params().MessageStart());
67+
ssPeersIn << Params().MessageStart();
6868
ssPeersIn << _addrman;
6969
std::string str = ssPeersIn.str();
7070
std::vector<unsigned char> vchData(str.begin(), str.end());
@@ -110,7 +110,7 @@ BOOST_AUTO_TEST_CASE(caddrdb_read)
110110
BOOST_CHECK(addrman1.size() == 0);
111111
try {
112112
unsigned char pchMsgTmp[4];
113-
ssPeers1 >> FLATDATA(pchMsgTmp);
113+
ssPeers1 >> pchMsgTmp;
114114
ssPeers1 >> addrman1;
115115
} catch (const std::exception& e) {
116116
exceptionThrown = true;
@@ -142,7 +142,7 @@ BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted)
142142
BOOST_CHECK(addrman1.size() == 0);
143143
try {
144144
unsigned char pchMsgTmp[4];
145-
ssPeers1 >> FLATDATA(pchMsgTmp);
145+
ssPeers1 >> pchMsgTmp;
146146
ssPeers1 >> addrman1;
147147
} catch (const std::exception& e) {
148148
exceptionThrown = true;

src/test/serialize_tests.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,23 @@ class CSerializeMethodsTestSingle
1919
int intval;
2020
bool boolval;
2121
std::string stringval;
22-
const char* charstrval;
22+
char charstrval[16];
2323
CTransactionRef txval;
2424
public:
2525
CSerializeMethodsTestSingle() = default;
26-
CSerializeMethodsTestSingle(int intvalin, bool boolvalin, std::string stringvalin, const char* charstrvalin, CTransaction txvalin) : intval(intvalin), boolval(boolvalin), stringval(std::move(stringvalin)), charstrval(charstrvalin), txval(MakeTransactionRef(txvalin)){}
26+
CSerializeMethodsTestSingle(int intvalin, bool boolvalin, std::string stringvalin, const char* charstrvalin, CTransaction txvalin) : intval(intvalin), boolval(boolvalin), stringval(std::move(stringvalin)), txval(MakeTransactionRef(txvalin))
27+
{
28+
memcpy(charstrval, charstrvalin, sizeof(charstrval));
29+
}
30+
2731
ADD_SERIALIZE_METHODS;
2832

2933
template <typename Stream, typename Operation>
3034
inline void SerializationOp(Stream& s, Operation ser_action) {
3135
READWRITE(intval);
3236
READWRITE(boolval);
3337
READWRITE(stringval);
34-
READWRITE(FLATDATA(charstrval));
38+
READWRITE(charstrval);
3539
READWRITE(txval);
3640
}
3741

@@ -53,7 +57,7 @@ class CSerializeMethodsTestMany : public CSerializeMethodsTestSingle
5357

5458
template <typename Stream, typename Operation>
5559
inline void SerializationOp(Stream& s, Operation ser_action) {
56-
READWRITE(intval, boolval, stringval, FLATDATA(charstrval), txval);
60+
READWRITE(intval, boolval, stringval, charstrval, txval);
5761
}
5862
};
5963

@@ -344,7 +348,7 @@ BOOST_AUTO_TEST_CASE(class_methods)
344348
int intval(100);
345349
bool boolval(true);
346350
std::string stringval("testing");
347-
const char* charstrval("testing charstr");
351+
const char charstrval[16] = "testing charstr";
348352
CMutableTransaction txval;
349353
CSerializeMethodsTestSingle methodtest1(intval, boolval, stringval, charstrval, txval);
350354
CSerializeMethodsTestMany methodtest2(intval, boolval, stringval, charstrval, txval);
@@ -360,7 +364,7 @@ BOOST_AUTO_TEST_CASE(class_methods)
360364
BOOST_CHECK(methodtest2 == methodtest3);
361365
BOOST_CHECK(methodtest3 == methodtest4);
362366

363-
CDataStream ss2(SER_DISK, PROTOCOL_VERSION, intval, boolval, stringval, FLATDATA(charstrval), txval);
367+
CDataStream ss2(SER_DISK, PROTOCOL_VERSION, intval, boolval, stringval, charstrval, txval);
364368
ss2 >> methodtest3;
365369
BOOST_CHECK(methodtest3 == methodtest4);
366370
}

src/test/streams_tests.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,16 @@ BOOST_AUTO_TEST_CASE(streams_vector_writer)
5757
BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 0, 1, 2}}));
5858
vch.clear();
5959

60-
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, FLATDATA(bytes));
60+
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, bytes);
6161
BOOST_CHECK((vch == std::vector<unsigned char>{{3, 4, 5, 6}}));
62-
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, FLATDATA(bytes));
62+
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, bytes);
6363
BOOST_CHECK((vch == std::vector<unsigned char>{{3, 4, 5, 6}}));
6464
vch.clear();
6565

6666
vch.resize(4, 8);
67-
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, FLATDATA(bytes), b);
67+
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, bytes, b);
6868
BOOST_CHECK((vch == std::vector<unsigned char>{{8, 8, 1, 3, 4, 5, 6, 2}}));
69-
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, FLATDATA(bytes), b);
69+
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, bytes, b);
7070
BOOST_CHECK((vch == std::vector<unsigned char>{{8, 8, 1, 3, 4, 5, 6, 2}}));
7171
vch.clear();
7272
}

src/validation.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,7 +1078,7 @@ static bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMes
10781078

10791079
// Write index header
10801080
unsigned int nSize = GetSerializeSize(fileout, block);
1081-
fileout << FLATDATA(messageStart) << nSize;
1081+
fileout << messageStart << nSize;
10821082

10831083
// Write block
10841084
long fileOutPos = ftell(fileout.Get());
@@ -1442,7 +1442,7 @@ bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint
14421442

14431443
// Write index header
14441444
unsigned int nSize = GetSerializeSize(fileout, blockundo);
1445-
fileout << FLATDATA(messageStart) << nSize;
1445+
fileout << messageStart << nSize;
14461446

14471447
// Write undo data
14481448
long fileOutPos = ftell(fileout.Get());
@@ -4284,7 +4284,7 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB
42844284
unsigned char buf[CMessageHeader::MESSAGE_START_SIZE];
42854285
blkdat.FindByte(chainparams.MessageStart()[0]);
42864286
nRewind = blkdat.GetPos()+1;
4287-
blkdat >> FLATDATA(buf);
4287+
blkdat >> buf;
42884288
if (memcmp(buf, chainparams.MessageStart(), CMessageHeader::MESSAGE_START_SIZE))
42894289
continue;
42904290
// read size

0 commit comments

Comments
 (0)