0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-15 11:36:00 -05:00

Merge bitcoin/bitcoin#28503: refactor: Remove WithParams serialization helper, use SER_PARAMS_OPFUNC

99990194ce Remove WithParams serialization helper (MarcoFalke)
ffffb4af83 scripted-diff: Use ser params operator (MarcoFalke)
fae9054793 test: Use SER_PARAMS_OPFUNC in serialize_tests.cpp (MarcoFalke)

Pull request description:

  Every serialization parameter struct already has the `SER_PARAMS_OPFUNC`, except for one in the tests.

  For consistency, and to remove verbose code, convert the test to `SER_PARAMS_OPFUNC`, and use it everywhere, then remove the `WithParams` helper.

ACKs for top commit:
  ajtowns:
    reACK 99990194ce
  TheCharlatan:
    Re-ACK 99990194ce

Tree-SHA512: be9cae4225a502486fe8d552aaf4b2cd2904a9f73cce9d931c6b7c757594ff1982fcc2c30d00d012cd12b0a9531fd609f8bcd7c94b811e965ac087eb8a3589d3
This commit is contained in:
fanquake 2023-10-31 10:51:37 +00:00
commit d51fb9caa6
No known key found for this signature in database
GPG key ID: 2EEB9F5CC09526C1
7 changed files with 79 additions and 82 deletions

View file

@ -3770,7 +3770,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
std::vector<CAddress> vAddr; std::vector<CAddress> vAddr;
vRecv >> WithParams(ser_params, vAddr); vRecv >> ser_params(vAddr);
if (!SetupAddressRelay(pfrom, *peer)) { if (!SetupAddressRelay(pfrom, *peer)) {
LogPrint(BCLog::NET, "ignoring %s message from %s peer=%d\n", msg_type, pfrom.ConnectionTypeAsString(), pfrom.GetId()); LogPrint(BCLog::NET, "ignoring %s message from %s peer=%d\n", msg_type, pfrom.ConnectionTypeAsString(), pfrom.GetId());
@ -5375,16 +5375,12 @@ void PeerManagerImpl::MaybeSendAddr(CNode& node, Peer& peer, std::chrono::micros
// No addr messages to send // No addr messages to send
if (peer.m_addrs_to_send.empty()) return; if (peer.m_addrs_to_send.empty()) return;
const char* msg_type; CNetMsgMaker mm(node.GetCommonVersion());
CNetAddr::Encoding ser_enc;
if (peer.m_wants_addrv2) { if (peer.m_wants_addrv2) {
msg_type = NetMsgType::ADDRV2; m_connman.PushMessage(&node, mm.Make(NetMsgType::ADDRV2, CAddress::V2_NETWORK(peer.m_addrs_to_send)));
ser_enc = CNetAddr::Encoding::V2;
} else { } else {
msg_type = NetMsgType::ADDR; m_connman.PushMessage(&node, mm.Make(NetMsgType::ADDR, CAddress::V1_NETWORK(peer.m_addrs_to_send)));
ser_enc = CNetAddr::Encoding::V1;
} }
m_connman.PushMessage(&node, CNetMsgMaker(node.GetCommonVersion()).Make(msg_type, WithParams(CAddress::SerParams{{ser_enc}, CAddress::Format::Network}, peer.m_addrs_to_send)));
peer.m_addrs_to_send.clear(); peer.m_addrs_to_send.clear();
// we only send the big addr message once // we only send the big addr message once

View file

@ -445,7 +445,7 @@ public:
} }
// Invoke V1/V2 serializer for CService parent object. // Invoke V1/V2 serializer for CService parent object.
const auto ser_params{use_v2 ? CNetAddr::V2 : CNetAddr::V1}; const auto ser_params{use_v2 ? CNetAddr::V2 : CNetAddr::V1};
READWRITE(WithParams(ser_params, AsBase<CService>(obj))); READWRITE(ser_params(AsBase<CService>(obj)));
} }
//! Always included in serialization. The behavior is unspecified if the value is not representable as uint32_t. //! Always included in serialization. The behavior is unspecified if the value is not representable as uint32_t.

View file

@ -214,11 +214,11 @@ const Out& AsBase(const In& x)
* } * }
* }; * };
* which would then be invoked as * which would then be invoked as
* READWRITE(WithParams(BarParameter{...}, Using<FooFormatter>(obj.foo))) * READWRITE(BarParameter{...}(Using<FooFormatter>(obj.foo)))
* *
* WithParams(parameter, obj) can be invoked anywhere in the call stack; it is * parameter(obj) can be invoked anywhere in the call stack; it is
* passed down recursively into all serialization code, until another * passed down recursively into all serialization code, until another
* WithParams overrides it. * serialization parameter overrides it.
* *
* Parameters will be implicitly converted where appropriate. This means that * Parameters will be implicitly converted where appropriate. This means that
* "parent" serialization code can use a parameter that derives from, or is * "parent" serialization code can use a parameter that derives from, or is
@ -1182,17 +1182,6 @@ public:
} }
}; };
/**
* Return a wrapper around t that (de)serializes it with specified parameter params.
*
* See FORMATTER_METHODS_PARAMS for more information on serialization parameters.
*/
template <typename Params, typename T>
static auto WithParams(const Params& params, T&& t)
{
return ParamsWrapper<Params, T>{params, t};
}
/** /**
* Helper macro for SerParams structs * Helper macro for SerParams structs
* *
@ -1202,8 +1191,16 @@ static auto WithParams(const Params& params, T&& t)
* constexpr SerParams FOO{....}; * constexpr SerParams FOO{....};
* ss << FOO(obj); * ss << FOO(obj);
*/ */
#define SER_PARAMS_OPFUNC \ #define SER_PARAMS_OPFUNC \
template <typename T> \ /** \
auto operator()(T&& t) const { return WithParams(*this, t); } * Return a wrapper around t that (de)serializes it with specified parameter params. \
* \
* See FORMATTER_METHODS_PARAMS for more information on serialization parameters. \
*/ \
template <typename T> \
auto operator()(T&& t) const \
{ \
return ParamsWrapper{*this, t}; \
}
#endif // BITCOIN_SERIALIZE_H #endif // BITCOIN_SERIALIZE_H

View file

@ -66,7 +66,7 @@ template <typename T, typename P>
DataStream Serialize(const T& obj, const P& params) DataStream Serialize(const T& obj, const P& params)
{ {
DataStream ds{}; DataStream ds{};
ds << WithParams(params, obj); ds << params(obj);
return ds; return ds;
} }
@ -74,7 +74,7 @@ template <typename T, typename P>
T Deserialize(DataStream&& ds, const P& params) T Deserialize(DataStream&& ds, const P& params)
{ {
T obj; T obj;
ds >> WithParams(params, obj); ds >> params(obj);
return obj; return obj;
} }
@ -83,7 +83,7 @@ void DeserializeFromFuzzingInput(FuzzBufferType buffer, T&& obj, const P& params
{ {
DataStream ds{buffer}; DataStream ds{buffer};
try { try {
ds >> WithParams(params, obj); ds >> params(obj);
} catch (const std::ios_base::failure&) { } catch (const std::ios_base::failure&) {
throw invalid_fuzzing_input_exception(); throw invalid_fuzzing_input_exception();
} }

View file

@ -107,7 +107,7 @@ template <typename T, typename P>
DataStream ds{buffer}; DataStream ds{buffer};
T obj; T obj;
try { try {
ds >> WithParams(params, obj); ds >> params(obj);
} catch (const std::ios_base::failure&) { } catch (const std::ios_base::failure&) {
return std::nullopt; return std::nullopt;
} }

View file

@ -331,17 +331,17 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v1)
DataStream s{}; DataStream s{};
const auto ser_params{CAddress::V1_NETWORK}; const auto ser_params{CAddress::V1_NETWORK};
s << WithParams(ser_params, addr); s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000"); BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000");
s.clear(); s.clear();
addr = LookupHost("1.2.3.4", false).value(); addr = LookupHost("1.2.3.4", false).value();
s << WithParams(ser_params, addr); s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000ffff01020304"); BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000ffff01020304");
s.clear(); s.clear();
addr = LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", false).value(); addr = LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", false).value();
s << WithParams(ser_params, addr); s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "1a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b"); BOOST_CHECK_EQUAL(HexStr(s), "1a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b");
s.clear(); s.clear();
@ -349,12 +349,12 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v1)
BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion")); BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion"));
BOOST_REQUIRE(addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion")); BOOST_REQUIRE(addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion"));
s << WithParams(ser_params, addr); s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000"); BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000");
s.clear(); s.clear();
addr.SetInternal("a"); addr.SetInternal("a");
s << WithParams(ser_params, addr); s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "fd6b88c08724ca978112ca1bbdcafac2"); BOOST_CHECK_EQUAL(HexStr(s), "fd6b88c08724ca978112ca1bbdcafac2");
s.clear(); s.clear();
} }
@ -365,17 +365,17 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v2)
DataStream s{}; DataStream s{};
const auto ser_params{CAddress::V2_NETWORK}; const auto ser_params{CAddress::V2_NETWORK};
s << WithParams(ser_params, addr); s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "021000000000000000000000000000000000"); BOOST_CHECK_EQUAL(HexStr(s), "021000000000000000000000000000000000");
s.clear(); s.clear();
addr = LookupHost("1.2.3.4", false).value(); addr = LookupHost("1.2.3.4", false).value();
s << WithParams(ser_params, addr); s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "010401020304"); BOOST_CHECK_EQUAL(HexStr(s), "010401020304");
s.clear(); s.clear();
addr = LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", false).value(); addr = LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", false).value();
s << WithParams(ser_params, addr); s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "02101a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b"); BOOST_CHECK_EQUAL(HexStr(s), "02101a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b");
s.clear(); s.clear();
@ -383,12 +383,12 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v2)
BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion")); BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion"));
BOOST_REQUIRE(addr.SetSpecial("kpgvmscirrdqpekbqjsvw5teanhatztpp2gl6eee4zkowvwfxwenqaid.onion")); BOOST_REQUIRE(addr.SetSpecial("kpgvmscirrdqpekbqjsvw5teanhatztpp2gl6eee4zkowvwfxwenqaid.onion"));
s << WithParams(ser_params, addr); s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "042053cd5648488c4707914182655b7664034e09e66f7e8cbf1084e654eb56c5bd88"); BOOST_CHECK_EQUAL(HexStr(s), "042053cd5648488c4707914182655b7664034e09e66f7e8cbf1084e654eb56c5bd88");
s.clear(); s.clear();
BOOST_REQUIRE(addr.SetInternal("a")); BOOST_REQUIRE(addr.SetInternal("a"));
s << WithParams(ser_params, addr); s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "0210fd6b88c08724ca978112ca1bbdcafac2"); BOOST_CHECK_EQUAL(HexStr(s), "0210fd6b88c08724ca978112ca1bbdcafac2");
s.clear(); s.clear();
} }
@ -403,7 +403,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("01" // network type (IPv4) s << Span{ParseHex("01" // network type (IPv4)
"04" // address length "04" // address length
"01020304")}; // address "01020304")}; // address
s >> WithParams(ser_params, addr); s >> ser_params(addr);
BOOST_CHECK(addr.IsValid()); BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsIPv4()); BOOST_CHECK(addr.IsIPv4());
BOOST_CHECK(addr.IsAddrV1Compatible()); BOOST_CHECK(addr.IsAddrV1Compatible());
@ -414,7 +414,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("01" // network type (IPv4) s << Span{ParseHex("01" // network type (IPv4)
"04" // address length "04" // address length
"0102")}; // address "0102")}; // address
BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure, HasReason("end of data")); BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure, HasReason("end of data"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear(); s.clear();
@ -422,7 +422,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("01" // network type (IPv4) s << Span{ParseHex("01" // network type (IPv4)
"05" // address length "05" // address length
"01020304")}; // address "01020304")}; // address
BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure, BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,
HasReason("BIP155 IPv4 address with length 5 (should be 4)")); HasReason("BIP155 IPv4 address with length 5 (should be 4)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear(); s.clear();
@ -431,7 +431,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("01" // network type (IPv4) s << Span{ParseHex("01" // network type (IPv4)
"fd0102" // address length (513 as CompactSize) "fd0102" // address length (513 as CompactSize)
"01020304")}; // address "01020304")}; // address
BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure, BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,
HasReason("Address too long: 513 > 512")); HasReason("Address too long: 513 > 512"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear(); s.clear();
@ -440,7 +440,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("02" // network type (IPv6) s << Span{ParseHex("02" // network type (IPv6)
"10" // address length "10" // address length
"0102030405060708090a0b0c0d0e0f10")}; // address "0102030405060708090a0b0c0d0e0f10")}; // address
s >> WithParams(ser_params, addr); s >> ser_params(addr);
BOOST_CHECK(addr.IsValid()); BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsIPv6()); BOOST_CHECK(addr.IsIPv6());
BOOST_CHECK(addr.IsAddrV1Compatible()); BOOST_CHECK(addr.IsAddrV1Compatible());
@ -453,7 +453,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"10" // address length "10" // address length
"fd6b88c08724ca978112ca1bbdcafac2")}; // address: 0xfd + sha256("bitcoin")[0:5] + "fd6b88c08724ca978112ca1bbdcafac2")}; // address: 0xfd + sha256("bitcoin")[0:5] +
// sha256(name)[0:10] // sha256(name)[0:10]
s >> WithParams(ser_params, addr); s >> ser_params(addr);
BOOST_CHECK(addr.IsInternal()); BOOST_CHECK(addr.IsInternal());
BOOST_CHECK(addr.IsAddrV1Compatible()); BOOST_CHECK(addr.IsAddrV1Compatible());
BOOST_CHECK_EQUAL(addr.ToStringAddr(), "zklycewkdo64v6wc.internal"); BOOST_CHECK_EQUAL(addr.ToStringAddr(), "zklycewkdo64v6wc.internal");
@ -463,7 +463,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("02" // network type (IPv6) s << Span{ParseHex("02" // network type (IPv6)
"04" // address length "04" // address length
"00")}; // address "00")}; // address
BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure, BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,
HasReason("BIP155 IPv6 address with length 4 (should be 16)")); HasReason("BIP155 IPv6 address with length 4 (should be 16)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear(); s.clear();
@ -472,7 +472,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("02" // network type (IPv6) s << Span{ParseHex("02" // network type (IPv6)
"10" // address length "10" // address length
"00000000000000000000ffff01020304")}; // address "00000000000000000000ffff01020304")}; // address
s >> WithParams(ser_params, addr); s >> ser_params(addr);
BOOST_CHECK(!addr.IsValid()); BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty()); BOOST_REQUIRE(s.empty());
@ -480,7 +480,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("02" // network type (IPv6) s << Span{ParseHex("02" // network type (IPv6)
"10" // address length "10" // address length
"fd87d87eeb430102030405060708090a")}; // address "fd87d87eeb430102030405060708090a")}; // address
s >> WithParams(ser_params, addr); s >> ser_params(addr);
BOOST_CHECK(!addr.IsValid()); BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty()); BOOST_REQUIRE(s.empty());
@ -488,7 +488,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("03" // network type (TORv2) s << Span{ParseHex("03" // network type (TORv2)
"0a" // address length "0a" // address length
"f1f2f3f4f5f6f7f8f9fa")}; // address "f1f2f3f4f5f6f7f8f9fa")}; // address
s >> WithParams(ser_params, addr); s >> ser_params(addr);
BOOST_CHECK(!addr.IsValid()); BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty()); BOOST_REQUIRE(s.empty());
@ -498,7 +498,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"79bcc625184b05194975c28b66b66b04" // address "79bcc625184b05194975c28b66b66b04" // address
"69f7f6556fb1ac3189a79b40dda32f1f" "69f7f6556fb1ac3189a79b40dda32f1f"
)}; )};
s >> WithParams(ser_params, addr); s >> ser_params(addr);
BOOST_CHECK(addr.IsValid()); BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsTor()); BOOST_CHECK(addr.IsTor());
BOOST_CHECK(!addr.IsAddrV1Compatible()); BOOST_CHECK(!addr.IsAddrV1Compatible());
@ -511,7 +511,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"00" // address length "00" // address length
"00" // address "00" // address
)}; )};
BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure, BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,
HasReason("BIP155 TORv3 address with length 0 (should be 32)")); HasReason("BIP155 TORv3 address with length 0 (should be 32)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear(); s.clear();
@ -521,7 +521,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"20" // address length "20" // address length
"a2894dabaec08c0051a481a6dac88b64" // address "a2894dabaec08c0051a481a6dac88b64" // address
"f98232ae42d4b6fd2fa81952dfe36a87")}; "f98232ae42d4b6fd2fa81952dfe36a87")};
s >> WithParams(ser_params, addr); s >> ser_params(addr);
BOOST_CHECK(addr.IsValid()); BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsI2P()); BOOST_CHECK(addr.IsI2P());
BOOST_CHECK(!addr.IsAddrV1Compatible()); BOOST_CHECK(!addr.IsAddrV1Compatible());
@ -534,7 +534,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"03" // address length "03" // address length
"00" // address "00" // address
)}; )};
BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure, BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,
HasReason("BIP155 I2P address with length 3 (should be 32)")); HasReason("BIP155 I2P address with length 3 (should be 32)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear(); s.clear();
@ -544,7 +544,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"10" // address length "10" // address length
"fc000001000200030004000500060007" // address "fc000001000200030004000500060007" // address
)}; )};
s >> WithParams(ser_params, addr); s >> ser_params(addr);
BOOST_CHECK(addr.IsValid()); BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsCJDNS()); BOOST_CHECK(addr.IsCJDNS());
BOOST_CHECK(!addr.IsAddrV1Compatible()); BOOST_CHECK(!addr.IsAddrV1Compatible());
@ -556,7 +556,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"10" // address length "10" // address length
"aa000001000200030004000500060007" // address "aa000001000200030004000500060007" // address
)}; )};
s >> WithParams(ser_params, addr); s >> ser_params(addr);
BOOST_CHECK(addr.IsCJDNS()); BOOST_CHECK(addr.IsCJDNS());
BOOST_CHECK(!addr.IsValid()); BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty()); BOOST_REQUIRE(s.empty());
@ -566,7 +566,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"01" // address length "01" // address length
"00" // address "00" // address
)}; )};
BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure, BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,
HasReason("BIP155 CJDNS address with length 1 (should be 16)")); HasReason("BIP155 CJDNS address with length 1 (should be 16)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear(); s.clear();
@ -576,7 +576,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"fe00000002" // address length (CompactSize's MAX_SIZE) "fe00000002" // address length (CompactSize's MAX_SIZE)
"01020304050607" // address "01020304050607" // address
)}; )};
BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure, BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,
HasReason("Address too long: 33554432 > 512")); HasReason("Address too long: 33554432 > 512"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear(); s.clear();
@ -586,7 +586,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"04" // address length "04" // address length
"01020304" // address "01020304" // address
)}; )};
s >> WithParams(ser_params, addr); s >> ser_params(addr);
BOOST_CHECK(!addr.IsValid()); BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty()); BOOST_REQUIRE(s.empty());
@ -595,7 +595,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"00" // address length "00" // address length
"" // address "" // address
)}; )};
s >> WithParams(ser_params, addr); s >> ser_params(addr);
BOOST_CHECK(!addr.IsValid()); BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty()); BOOST_REQUIRE(s.empty());
} }

View file

@ -255,10 +255,15 @@ BOOST_AUTO_TEST_CASE(class_methods)
} }
} }
enum class BaseFormat { struct BaseFormat {
RAW, const enum {
HEX, RAW,
HEX,
} m_base_format;
SER_PARAMS_OPFUNC
}; };
constexpr BaseFormat RAW{BaseFormat::RAW};
constexpr BaseFormat HEX{BaseFormat::HEX};
/// (Un)serialize a number as raw byte or 2 hexadecimal chars. /// (Un)serialize a number as raw byte or 2 hexadecimal chars.
class Base class Base
@ -272,7 +277,7 @@ public:
template <typename Stream> template <typename Stream>
void Serialize(Stream& s) const void Serialize(Stream& s) const
{ {
if (s.GetParams() == BaseFormat::RAW) { if (s.GetParams().m_base_format == BaseFormat::RAW) {
s << m_base_data; s << m_base_data;
} else { } else {
s << Span{HexStr(Span{&m_base_data, 1})}; s << Span{HexStr(Span{&m_base_data, 1})};
@ -282,7 +287,7 @@ public:
template <typename Stream> template <typename Stream>
void Unserialize(Stream& s) void Unserialize(Stream& s)
{ {
if (s.GetParams() == BaseFormat::RAW) { if (s.GetParams().m_base_format == BaseFormat::RAW) {
s >> m_base_data; s >> m_base_data;
} else { } else {
std::string hex{"aa"}; std::string hex{"aa"};
@ -301,6 +306,8 @@ public:
LOWER, LOWER,
UPPER, UPPER,
} m_derived_format; } m_derived_format;
SER_PARAMS_OPFUNC
}; };
class Derived : public Base class Derived : public Base
@ -310,7 +317,7 @@ public:
SERIALIZE_METHODS_PARAMS(Derived, obj, DerivedAndBaseFormat, fmt) SERIALIZE_METHODS_PARAMS(Derived, obj, DerivedAndBaseFormat, fmt)
{ {
READWRITE(WithParams(fmt.m_base_format, AsBase<Base>(obj))); READWRITE(fmt.m_base_format(AsBase<Base>(obj)));
if (ser_action.ForRead()) { if (ser_action.ForRead()) {
std::string str; std::string str;
@ -330,20 +337,20 @@ BOOST_AUTO_TEST_CASE(with_params_base)
DataStream stream; DataStream stream;
stream << WithParams(BaseFormat::RAW, b); stream << RAW(b);
BOOST_CHECK_EQUAL(stream.str(), "\x0F"); BOOST_CHECK_EQUAL(stream.str(), "\x0F");
b.m_base_data = 0; b.m_base_data = 0;
stream >> WithParams(BaseFormat::RAW, b); stream >> RAW(b);
BOOST_CHECK_EQUAL(b.m_base_data, 0x0F); BOOST_CHECK_EQUAL(b.m_base_data, 0x0F);
stream.clear(); stream.clear();
stream << WithParams(BaseFormat::HEX, b); stream << HEX(b);
BOOST_CHECK_EQUAL(stream.str(), "0f"); BOOST_CHECK_EQUAL(stream.str(), "0f");
b.m_base_data = 0; b.m_base_data = 0;
stream >> WithParams(BaseFormat::HEX, b); stream >> HEX(b);
BOOST_CHECK_EQUAL(b.m_base_data, 0x0F); BOOST_CHECK_EQUAL(b.m_base_data, 0x0F);
} }
@ -353,45 +360,42 @@ BOOST_AUTO_TEST_CASE(with_params_vector_of_base)
DataStream stream; DataStream stream;
stream << WithParams(BaseFormat::RAW, v); stream << RAW(v);
BOOST_CHECK_EQUAL(stream.str(), "\x02\x0F\xFF"); BOOST_CHECK_EQUAL(stream.str(), "\x02\x0F\xFF");
v[0].m_base_data = 0; v[0].m_base_data = 0;
v[1].m_base_data = 0; v[1].m_base_data = 0;
stream >> WithParams(BaseFormat::RAW, v); stream >> RAW(v);
BOOST_CHECK_EQUAL(v[0].m_base_data, 0x0F); BOOST_CHECK_EQUAL(v[0].m_base_data, 0x0F);
BOOST_CHECK_EQUAL(v[1].m_base_data, 0xFF); BOOST_CHECK_EQUAL(v[1].m_base_data, 0xFF);
stream.clear(); stream.clear();
stream << WithParams(BaseFormat::HEX, v); stream << HEX(v);
BOOST_CHECK_EQUAL(stream.str(), "\x02" BOOST_CHECK_EQUAL(stream.str(), "\x02"
"0fff"); "0fff");
v[0].m_base_data = 0; v[0].m_base_data = 0;
v[1].m_base_data = 0; v[1].m_base_data = 0;
stream >> WithParams(BaseFormat::HEX, v); stream >> HEX(v);
BOOST_CHECK_EQUAL(v[0].m_base_data, 0x0F); BOOST_CHECK_EQUAL(v[0].m_base_data, 0x0F);
BOOST_CHECK_EQUAL(v[1].m_base_data, 0xFF); BOOST_CHECK_EQUAL(v[1].m_base_data, 0xFF);
} }
constexpr DerivedAndBaseFormat RAW_LOWER{{BaseFormat::RAW}, DerivedAndBaseFormat::DerivedFormat::LOWER};
constexpr DerivedAndBaseFormat HEX_UPPER{{BaseFormat::HEX}, DerivedAndBaseFormat::DerivedFormat::UPPER};
BOOST_AUTO_TEST_CASE(with_params_derived) BOOST_AUTO_TEST_CASE(with_params_derived)
{ {
Derived d; Derived d;
d.m_base_data = 0x0F; d.m_base_data = 0x0F;
d.m_derived_data = "xY"; d.m_derived_data = "xY";
DerivedAndBaseFormat fmt;
DataStream stream; DataStream stream;
fmt.m_base_format = BaseFormat::RAW; stream << RAW_LOWER(d);
fmt.m_derived_format = DerivedAndBaseFormat::DerivedFormat::LOWER;
stream << WithParams(fmt, d);
fmt.m_base_format = BaseFormat::HEX; stream << HEX_UPPER(d);
fmt.m_derived_format = DerivedAndBaseFormat::DerivedFormat::UPPER;
stream << WithParams(fmt, d);
BOOST_CHECK_EQUAL(stream.str(), "\x0F\x02xy" BOOST_CHECK_EQUAL(stream.str(), "\x0F\x02xy"
"0f\x02XY"); "0f\x02XY");