diff options
-rw-r--r-- | src/addrdb.cpp | 4 | ||||
-rw-r--r-- | src/net_processing.cpp | 6 | ||||
-rw-r--r-- | src/netaddress.h | 1 | ||||
-rw-r--r-- | src/protocol.h | 1 | ||||
-rw-r--r-- | src/serialize.h | 126 | ||||
-rw-r--r-- | src/test/addrman_tests.cpp | 2 | ||||
-rw-r--r-- | src/test/fuzz/addrman.cpp | 2 | ||||
-rw-r--r-- | src/test/net_tests.cpp | 4 | ||||
-rw-r--r-- | src/test/netbase_tests.cpp | 8 | ||||
-rw-r--r-- | src/test/util/net.cpp | 4 |
10 files changed, 87 insertions, 71 deletions
diff --git a/src/addrdb.cpp b/src/addrdb.cpp index 50f576624c..8b85b77e2b 100644 --- a/src/addrdb.cpp +++ b/src/addrdb.cpp @@ -216,14 +216,14 @@ util::Result<std::unique_ptr<AddrMan>> LoadAddrman(const NetGroupManager& netgro void DumpAnchors(const fs::path& anchors_db_path, const std::vector<CAddress>& anchors) { LOG_TIME_SECONDS(strprintf("Flush %d outbound block-relay-only peer addresses to anchors.dat", anchors.size())); - SerializeFileDB("anchors", anchors_db_path, WithParams(CAddress::V2_DISK, anchors)); + SerializeFileDB("anchors", anchors_db_path, CAddress::V2_DISK(anchors)); } std::vector<CAddress> ReadAnchors(const fs::path& anchors_db_path) { std::vector<CAddress> anchors; try { - DeserializeFileDB(anchors_db_path, WithParams(CAddress::V2_DISK, anchors)); + DeserializeFileDB(anchors_db_path, CAddress::V2_DISK(anchors)); LogPrintf("Loaded %i addresses from %s\n", anchors.size(), fs::quoted(fs::PathToString(anchors_db_path.filename()))); } catch (const std::exception&) { anchors.clear(); diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 6b415b3a1e..b046b3ac16 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1415,8 +1415,8 @@ void PeerManagerImpl::PushNodeVersion(CNode& pnode, const Peer& peer) const bool tx_relay{!RejectIncomingTxs(pnode)}; m_connman.PushMessage(&pnode, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERSION, PROTOCOL_VERSION, my_services, nTime, - your_services, WithParams(CNetAddr::V1, addr_you), // Together the pre-version-31402 serialization of CAddress "addrYou" (without nTime) - my_services, WithParams(CNetAddr::V1, CService{}), // Together the pre-version-31402 serialization of CAddress "addrMe" (without nTime) + your_services, CNetAddr::V1(addr_you), // Together the pre-version-31402 serialization of CAddress "addrYou" (without nTime) + my_services, CNetAddr::V1(CService{}), // Together the pre-version-31402 serialization of CAddress "addrMe" (without nTime) nonce, strSubVersion, nNodeStartingHeight, tx_relay)); if (fLogIPs) { @@ -3293,7 +3293,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, nTime = 0; } vRecv.ignore(8); // Ignore the addrMe service bits sent by the peer - vRecv >> WithParams(CNetAddr::V1, addrMe); + vRecv >> CNetAddr::V1(addrMe); if (!pfrom.IsInboundConn()) { m_addrman.SetServices(pfrom.addr, nServices); diff --git a/src/netaddress.h b/src/netaddress.h index a0944c886f..7d3659a11a 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -218,6 +218,7 @@ public: }; struct SerParams { const Encoding enc; + SER_PARAMS_OPFUNC }; static constexpr SerParams V1{Encoding::V1}; static constexpr SerParams V2{Encoding::V2}; diff --git a/src/protocol.h b/src/protocol.h index 22e2108afb..56668898e4 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -396,6 +396,7 @@ public: }; struct SerParams : CNetAddr::SerParams { const Format fmt; + SER_PARAMS_OPFUNC }; static constexpr SerParams V1_NETWORK{{CNetAddr::Encoding::V1}, Format::Network}; static constexpr SerParams V2_NETWORK{{CNetAddr::Encoding::V2}, Format::Network}; diff --git a/src/serialize.h b/src/serialize.h index f1595077e9..1ad8ac4373 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -167,9 +167,9 @@ const Out& AsBase(const In& x) return x; } -#define READWRITE(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__)) -#define SER_READ(obj, code) ::SerRead(s, ser_action, obj, [&](Stream& s, typename std::remove_const<Type>::type& obj) { code; }) -#define SER_WRITE(obj, code) ::SerWrite(s, ser_action, obj, [&](Stream& s, const Type& obj) { code; }) +#define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) +#define SER_READ(obj, code) ser_action.SerRead(s, obj, [&](Stream& s, typename std::remove_const<Type>::type& obj) { code; }) +#define SER_WRITE(obj, code) ser_action.SerWrite(s, obj, [&](Stream& s, const Type& obj) { code; }) /** * Implement the Ser and Unser methods needed for implementing a formatter (see Using below). @@ -1008,17 +1008,65 @@ void Unserialize(Stream& is, std::shared_ptr<const T>& p) p = std::make_shared<const T>(deserialize, is); } +/** + * Support for (un)serializing many things at once + */ + +template <typename Stream, typename... Args> +void SerializeMany(Stream& s, const Args&... args) +{ + (::Serialize(s, args), ...); +} + +template <typename Stream, typename... Args> +inline void UnserializeMany(Stream& s, Args&&... args) +{ + (::Unserialize(s, args), ...); +} /** * Support for all macros providing or using the ser_action parameter of the SerializationOps method. */ struct ActionSerialize { - constexpr bool ForRead() const { return false; } + static constexpr bool ForRead() { return false; } + + template<typename Stream, typename... Args> + static void SerReadWriteMany(Stream& s, const Args&... args) + { + ::SerializeMany(s, args...); + } + + template<typename Stream, typename Type, typename Fn> + static void SerRead(Stream& s, Type&&, Fn&&) + { + } + + template<typename Stream, typename Type, typename Fn> + static void SerWrite(Stream& s, Type&& obj, Fn&& fn) + { + fn(s, std::forward<Type>(obj)); + } }; struct ActionUnserialize { - constexpr bool ForRead() const { return true; } -}; + static constexpr bool ForRead() { return true; } + template<typename Stream, typename... Args> + static void SerReadWriteMany(Stream& s, Args&&... args) + { + ::UnserializeMany(s, args...); + } + + template<typename Stream, typename Type, typename Fn> + static void SerRead(Stream& s, Type&& obj, Fn&& fn) + { + fn(s, std::forward<Type>(obj)); + } + + template<typename Stream, typename Type, typename Fn> + static void SerWrite(Stream& s, Type&&, Fn&&) + { + } +}; /* ::GetSerializeSize implementations * @@ -1065,52 +1113,6 @@ public: int GetVersion() const { return nVersion; } }; -template <typename Stream, typename... Args> -void SerializeMany(Stream& s, const Args&... args) -{ - (::Serialize(s, args), ...); -} - -template <typename Stream, typename... Args> -inline void UnserializeMany(Stream& s, Args&&... args) -{ - (::Unserialize(s, args), ...); -} - -template<typename Stream, typename... Args> -inline void SerReadWriteMany(Stream& s, ActionSerialize ser_action, const Args&... args) -{ - ::SerializeMany(s, args...); -} - -template<typename Stream, typename... Args> -inline void SerReadWriteMany(Stream& s, ActionUnserialize ser_action, Args&&... args) -{ - ::UnserializeMany(s, args...); -} - -template<typename Stream, typename Type, typename Fn> -inline void SerRead(Stream& s, ActionSerialize ser_action, Type&&, Fn&&) -{ -} - -template<typename Stream, typename Type, typename Fn> -inline void SerRead(Stream& s, ActionUnserialize ser_action, Type&& obj, Fn&& fn) -{ - fn(s, std::forward<Type>(obj)); -} - -template<typename Stream, typename Type, typename Fn> -inline void SerWrite(Stream& s, ActionSerialize ser_action, Type&& obj, Fn&& fn) -{ - fn(s, std::forward<Type>(obj)); -} - -template<typename Stream, typename Type, typename Fn> -inline void SerWrite(Stream& s, ActionUnserialize ser_action, Type&&, Fn&&) -{ -} - template<typename I> inline void WriteVarInt(CSizeComputer &s, I n) { @@ -1161,12 +1163,11 @@ public: template <typename Params, typename T> class ParamsWrapper { - static_assert(std::is_lvalue_reference<T>::value, "ParamsWrapper needs an lvalue reference type T"); const Params& m_params; - T m_object; + T& m_object; public: - explicit ParamsWrapper(const Params& params, T obj) : m_params{params}, m_object{obj} {} + explicit ParamsWrapper(const Params& params, T& obj) : m_params{params}, m_object{obj} {} template <typename Stream> void Serialize(Stream& s) const @@ -1190,7 +1191,20 @@ public: template <typename Params, typename T> static auto WithParams(const Params& params, T&& t) { - return ParamsWrapper<Params, T&>{params, t}; + return ParamsWrapper<Params, T>{params, t}; } +/** + * Helper macro for SerParams structs + * + * Allows you define SerParams instances and then apply them directly + * to an object via function call syntax, eg: + * + * constexpr SerParams FOO{....}; + * ss << FOO(obj); + */ +#define SER_PARAMS_OPFUNC \ + template <typename T> \ + auto operator()(T&& t) const { return WithParams(*this, t); } + #endif // BITCOIN_SERIALIZE_H diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index 941018a820..b01ba81c5f 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -1019,7 +1019,7 @@ static auto MakeCorruptPeersDat() std::optional<CNetAddr> resolved{LookupHost("252.2.2.2", false)}; BOOST_REQUIRE(resolved.has_value()); AddrInfo info = AddrInfo(addr, resolved.value()); - s << WithParams(CAddress::V1_DISK, info); + s << CAddress::V1_DISK(info); return s; } diff --git a/src/test/fuzz/addrman.cpp b/src/test/fuzz/addrman.cpp index 9611a872ec..1b11ff6fdf 100644 --- a/src/test/fuzz/addrman.cpp +++ b/src/test/fuzz/addrman.cpp @@ -83,7 +83,7 @@ CNetAddr RandAddr(FuzzedDataProvider& fuzzed_data_provider, FastRandomContext& f s << net; s << fast_random_context.randbytes(net_len_map.at(net)); - s >> WithParams(CAddress::V2_NETWORK, addr); + s >> CAddress::V2_NETWORK(addr); } // Return a dummy IPv4 5.5.5.5 if we generated an invalid address. diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 34d7867079..a29d96dc76 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -850,7 +850,7 @@ BOOST_AUTO_TEST_CASE(initial_advertise_from_version_message) std::chrono::microseconds time_received_dummy{0}; const auto msg_version = - msg_maker.Make(NetMsgType::VERSION, PROTOCOL_VERSION, services, time, services, WithParams(CAddress::V1_NETWORK, peer_us)); + msg_maker.Make(NetMsgType::VERSION, PROTOCOL_VERSION, services, time, services, CAddress::V1_NETWORK(peer_us)); CDataStream msg_version_stream{msg_version.data, SER_NETWORK, PROTOCOL_VERSION}; m_node.peerman->ProcessMessage( @@ -876,7 +876,7 @@ BOOST_AUTO_TEST_CASE(initial_advertise_from_version_message) DataStream s{data}; std::vector<CAddress> addresses; - s >> WithParams(CAddress::V1_NETWORK, addresses); + s >> CAddress::V1_NETWORK(addresses); for (const auto& addr : addresses) { if (addr == expected) { diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index e22bf7e7c0..74ff531cd9 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -561,7 +561,7 @@ BOOST_AUTO_TEST_CASE(caddress_serialize_v1) { DataStream s{}; - s << WithParams(CAddress::V1_NETWORK, fixture_addresses); + s << CAddress::V1_NETWORK(fixture_addresses); BOOST_CHECK_EQUAL(HexStr(s), stream_addrv1_hex); } @@ -570,7 +570,7 @@ BOOST_AUTO_TEST_CASE(caddress_unserialize_v1) DataStream s{ParseHex(stream_addrv1_hex)}; std::vector<CAddress> addresses_unserialized; - s >> WithParams(CAddress::V1_NETWORK, addresses_unserialized); + s >> CAddress::V1_NETWORK(addresses_unserialized); BOOST_CHECK(fixture_addresses == addresses_unserialized); } @@ -578,7 +578,7 @@ BOOST_AUTO_TEST_CASE(caddress_serialize_v2) { DataStream s{}; - s << WithParams(CAddress::V2_NETWORK, fixture_addresses); + s << CAddress::V2_NETWORK(fixture_addresses); BOOST_CHECK_EQUAL(HexStr(s), stream_addrv2_hex); } @@ -587,7 +587,7 @@ BOOST_AUTO_TEST_CASE(caddress_unserialize_v2) DataStream s{ParseHex(stream_addrv2_hex)}; std::vector<CAddress> addresses_unserialized; - s >> WithParams(CAddress::V2_NETWORK, addresses_unserialized); + s >> CAddress::V2_NETWORK(addresses_unserialized); BOOST_CHECK(fixture_addresses == addresses_unserialized); } diff --git a/src/test/util/net.cpp b/src/test/util/net.cpp index dc64c0b4c1..bf5a653090 100644 --- a/src/test/util/net.cpp +++ b/src/test/util/net.cpp @@ -33,9 +33,9 @@ void ConnmanTestMsg::Handshake(CNode& node, Using<CustomUintFormatter<8>>(remote_services), // int64_t{}, // dummy time int64_t{}, // ignored service bits - WithParams(CNetAddr::V1, CService{}), // dummy + CNetAddr::V1(CService{}), // dummy int64_t{}, // ignored service bits - WithParams(CNetAddr::V1, CService{}), // ignored + CNetAddr::V1(CService{}), // ignored uint64_t{1}, // dummy nonce std::string{}, // dummy subver int32_t{}, // dummy starting_height |