Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/evo/deterministicmns.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ class CDeterministicMNList
// an invalid entry and subsequent attempts at registering ADDRv2 entries get blocked. We cannot
// apply this treatment ADDRv1 compatible addresses for backwards compatibility with the existing map.
const auto& ser_params{v.IsAddrV1Compatible() ? CNetAddr::V1 : CNetAddr::V2};
return ::SerializeHash(WithParams(ser_params, v), /*nType=*/SER_GETHASH, /*nVersion=*/PROTOCOL_VERSION);
return ::SerializeHash(ser_params(v), /*nType=*/SER_GETHASH, /*nVersion=*/PROTOCOL_VERSION);
} else {
return ::SerializeHash(v, /*nType=*/SER_GETHASH, /*nVersion=*/PROTOCOL_VERSION);
}
Expand Down
12 changes: 4 additions & 8 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4441,7 +4441,7 @@ void PeerManagerImpl::ProcessMessage(

std::vector<CAddress> vAddr;

vRecv >> WithParams(ser_params, vAddr);
vRecv >> ser_params(vAddr);

if (!SetupAddressRelay(pfrom, *peer)) {
LogPrint(BCLog::NET, "ignoring %s message from %s peer=%d\n", msg_type, pfrom.ConnectionTypeAsString(), pfrom.GetId());
Expand Down Expand Up @@ -6309,16 +6309,12 @@ void PeerManagerImpl::MaybeSendAddr(CNode& node, Peer& peer, std::chrono::micros
// No addr messages to send
if (peer.m_addrs_to_send.empty()) return;

const char* msg_type;
CNetAddr::Encoding ser_enc;
CNetMsgMaker mm(node.GetCommonVersion());
if (peer.m_wants_addrv2) {
msg_type = NetMsgType::ADDRV2;
ser_enc = CNetAddr::Encoding::V2;
m_connman.PushMessage(&node, mm.Make(NetMsgType::ADDRV2, CAddress::V2_NETWORK(peer.m_addrs_to_send)));
} else {
msg_type = NetMsgType::ADDR;
ser_enc = CNetAddr::Encoding::V1;
m_connman.PushMessage(&node, mm.Make(NetMsgType::ADDR, CAddress::V1_NETWORK(peer.m_addrs_to_send)));
}
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();

// we only send the big addr message once
Expand Down
2 changes: 1 addition & 1 deletion src/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ class CAddress : public CService
}
// Invoke V1/V2 serializer for CService parent object.
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.
Expand Down
31 changes: 14 additions & 17 deletions src/serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,11 @@ const Out& AsBase(const In& x)
* }
* };
* 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
* WithParams overrides it.
* serialization parameter overrides it.
*
* Parameters will be implicitly converted where appropriate. This means that
* "parent" serialization code can use a parameter that derives from, or is
Expand Down Expand Up @@ -1650,17 +1650,6 @@ class ParamsWrapper
}
};

/**
* 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
*
Expand All @@ -1670,8 +1659,16 @@ static auto WithParams(const Params& params, T&& t)
* constexpr SerParams FOO{....};
* ss << FOO(obj);
*/
#define SER_PARAMS_OPFUNC \
template <typename T> \
auto operator()(T&& t) const { return WithParams(*this, t); }
#define SER_PARAMS_OPFUNC \
/** \
* 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
6 changes: 3 additions & 3 deletions src/test/fuzz/deserialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,15 @@ template <typename T, typename P>
DataStream Serialize(const T& obj, const P& params)
{
DataStream ds{};
ds << WithParams(params, obj);
ds << params(obj);
return ds;
}

template <typename T, typename P>
T Deserialize(DataStream&& ds, const P& params)
{
T obj;
ds >> WithParams(params, obj);
ds >> params(obj);
return obj;
}

Expand All @@ -82,7 +82,7 @@ void DeserializeFromFuzzingInput(FuzzBufferType buffer, T&& obj, const P& params
{
DataStream ds{buffer};
try {
ds >> WithParams(params, obj);
ds >> params(obj);
} catch (const std::ios_base::failure&) {
throw invalid_fuzzing_input_exception();
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/fuzz/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ template <typename T, typename P>
DataStream ds{buffer};
T obj;
try {
ds >> WithParams(params, obj);
ds >> params(obj);
} catch (const std::ios_base::failure&) {
return std::nullopt;
}
Expand Down
60 changes: 30 additions & 30 deletions src/test/net_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,30 +708,30 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v1)
DataStream s{};
const auto ser_params{CAddress::V1_NETWORK};

s << WithParams(ser_params, addr);
s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000");
s.clear();

addr = LookupHost("1.2.3.4", false).value();
s << WithParams(ser_params, addr);
s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000ffff01020304");
s.clear();

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");
s.clear();

// TORv2, no longer supported
BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion"));

BOOST_REQUIRE(addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion"));
s << WithParams(ser_params, addr);
s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000");
s.clear();

addr.SetInternal("a");
s << WithParams(ser_params, addr);
s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "fd6b88c08724ca978112ca1bbdcafac2");
s.clear();
}
Expand All @@ -742,30 +742,30 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v2)
DataStream s{};
const auto ser_params{CAddress::V2_NETWORK};

s << WithParams(ser_params, addr);
s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "021000000000000000000000000000000000");
s.clear();

addr = LookupHost("1.2.3.4", false).value();
s << WithParams(ser_params, addr);
s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "010401020304");
s.clear();

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");
s.clear();

// TORv2, no longer supported
BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion"));

BOOST_REQUIRE(addr.SetSpecial("kpgvmscirrdqpekbqjsvw5teanhatztpp2gl6eee4zkowvwfxwenqaid.onion"));
s << WithParams(ser_params, addr);
s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "042053cd5648488c4707914182655b7664034e09e66f7e8cbf1084e654eb56c5bd88");
s.clear();

BOOST_REQUIRE(addr.SetInternal("a"));
s << WithParams(ser_params, addr);
s << ser_params(addr);
BOOST_CHECK_EQUAL(HexStr(s), "0210fd6b88c08724ca978112ca1bbdcafac2");
s.clear();
}
Expand All @@ -780,7 +780,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("01" // network type (IPv4)
"04" // address length
"01020304")}; // address
s >> WithParams(ser_params, addr);
s >> ser_params(addr);
BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsIPv4());
BOOST_CHECK(addr.IsAddrV1Compatible());
Expand All @@ -791,15 +791,15 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("01" // network type (IPv4)
"04" // address length
"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.
s.clear();

// Invalid IPv4, with bogus length.
s << Span{ParseHex("01" // network type (IPv4)
"05" // address length
"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)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
Expand All @@ -808,7 +808,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("01" // network type (IPv4)
"fd0102" // address length (513 as CompactSize)
"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"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
Expand All @@ -817,7 +817,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("02" // network type (IPv6)
"10" // address length
"0102030405060708090a0b0c0d0e0f10")}; // address
s >> WithParams(ser_params, addr);
s >> ser_params(addr);
BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsIPv6());
BOOST_CHECK(addr.IsAddrV1Compatible());
Expand All @@ -830,7 +830,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"10" // address length
"fd6b88c08724ca978112ca1bbdcafac2")}; // address: 0xfd + sha256("bitcoin")[0:5] +
// sha256(name)[0:10]
s >> WithParams(ser_params, addr);
s >> ser_params(addr);
BOOST_CHECK(addr.IsInternal());
BOOST_CHECK(addr.IsAddrV1Compatible());
BOOST_CHECK_EQUAL(addr.ToStringAddr(), "zklycewkdo64v6wc.internal");
Expand All @@ -840,7 +840,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("02" // network type (IPv6)
"04" // address length
"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)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
Expand All @@ -849,23 +849,23 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
s << Span{ParseHex("02" // network type (IPv6)
"10" // address length
"00000000000000000000ffff01020304")}; // address
s >> WithParams(ser_params, addr);
s >> ser_params(addr);
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());

// Invalid IPv6, contains embedded TORv2.
s << Span{ParseHex("02" // network type (IPv6)
"10" // address length
"fd87d87eeb430102030405060708090a")}; // address
s >> WithParams(ser_params, addr);
s >> ser_params(addr);
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());

// TORv2, no longer supported.
s << Span{ParseHex("03" // network type (TORv2)
"0a" // address length
"f1f2f3f4f5f6f7f8f9fa")}; // address
s >> WithParams(ser_params, addr);
s >> ser_params(addr);
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());

Expand All @@ -875,7 +875,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"79bcc625184b05194975c28b66b66b04" // address
"69f7f6556fb1ac3189a79b40dda32f1f"
)};
s >> WithParams(ser_params, addr);
s >> ser_params(addr);
BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsTor());
BOOST_CHECK(!addr.IsAddrV1Compatible());
Expand All @@ -888,7 +888,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"00" // address length
"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)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
Expand All @@ -898,7 +898,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"20" // address length
"a2894dabaec08c0051a481a6dac88b64" // address
"f98232ae42d4b6fd2fa81952dfe36a87")};
s >> WithParams(ser_params, addr);
s >> ser_params(addr);
BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsI2P());
BOOST_CHECK(!addr.IsAddrV1Compatible());
Expand All @@ -911,7 +911,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"03" // address length
"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)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
Expand All @@ -921,7 +921,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"10" // address length
"fc000001000200030004000500060007" // address
)};
s >> WithParams(ser_params, addr);
s >> ser_params(addr);
BOOST_CHECK(addr.IsValid());
BOOST_CHECK(addr.IsCJDNS());
BOOST_CHECK(!addr.IsAddrV1Compatible());
Expand All @@ -933,7 +933,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"10" // address length
"aa000001000200030004000500060007" // address
)};
s >> WithParams(ser_params, addr);
s >> ser_params(addr);
BOOST_CHECK(addr.IsCJDNS());
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());
Expand All @@ -943,7 +943,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"01" // address length
"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)"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
Expand All @@ -953,7 +953,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"fe00000002" // address length (CompactSize's MAX_SIZE)
"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"));
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
s.clear();
Expand All @@ -963,7 +963,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"04" // address length
"01020304" // address
)};
s >> WithParams(ser_params, addr);
s >> ser_params(addr);
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());

Expand All @@ -972,7 +972,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
"00" // address length
"" // address
)};
s >> WithParams(ser_params, addr);
s >> ser_params(addr);
BOOST_CHECK(!addr.IsValid());
BOOST_REQUIRE(s.empty());
}
Expand Down
Loading
Loading