From 2525200185e6b470c6e6cec3c3c8044a0eb0ecc0 Mon Sep 17 00:00:00 2001 From: jeffro256 Date: Mon, 27 Nov 2023 19:28:08 -0600 Subject: [PATCH] serialization: remove container wrappers and serialize directly Some downstream code (most notably PR https://github.com/UkoeHB/monero/pull/25) wants to use the src/serialization lib for storing information persistently. When one builds classes/machines wishing to serialize containers, they must use the `serializable_*` container classes. In this case, this makes the Seraphis library code unnecessarily tightly coupled with the src/serialization code since one cannot swap out their type of storage format without major refactoring of class field types. By serializing STL containers directly, we can abstract the serialization details away, making for much cleaner design. Also small bonus side effect of this change is that STL containers with custom Comparators, Allocators, and Hashers are serializable. `std::multimap` is added to the list of serializable containers. Depends upon https://github.com/monero-project/monero/pull/9069. --- src/rpc/rpc_payment.h | 8 +-- src/serialization/container.h | 29 ++++++++-- src/serialization/containers.h | 99 ++++++---------------------------- src/wallet/wallet2.cpp | 10 ++-- src/wallet/wallet2.h | 60 ++++++++++----------- 5 files changed, 81 insertions(+), 125 deletions(-) diff --git a/src/rpc/rpc_payment.h b/src/rpc/rpc_payment.h index 4ead5a344..a4cc6db57 100644 --- a/src/rpc/rpc_payment.h +++ b/src/rpc/rpc_payment.h @@ -148,8 +148,8 @@ namespace cryptonote template inline void serialize(t_archive &a, const unsigned int ver) { - a & m_client_info.parent(); - a & m_hashrate.parent(); + a & m_client_info; + a & m_hashrate; a & m_credits_total; a & m_credits_used; a & m_nonces_good; @@ -177,9 +177,9 @@ namespace cryptonote cryptonote::account_public_address m_address; uint64_t m_diff; uint64_t m_credits_per_hash_found; - serializable_unordered_map m_client_info; + std::unordered_map m_client_info; std::string m_directory; - serializable_map m_hashrate; + std::map m_hashrate; uint64_t m_credits_total; uint64_t m_credits_used; uint64_t m_nonces_good; diff --git a/src/serialization/container.h b/src/serialization/container.h index 393c66399..6f0c48069 100644 --- a/src/serialization/container.h +++ b/src/serialization/container.h @@ -57,8 +57,28 @@ namespace serialization return true; } - template - void do_reserve(C &c, size_t N) {} + //! @brief Add an element to a container, inserting at the back if applicable. + template + auto do_add(Container &c, typename Container::value_type &&e) -> decltype(c.emplace_back(e)) + { return c.emplace_back(e); } + template + auto do_add(Container &c, typename Container::value_type &&e) -> decltype(c.emplace(e)) + { return c.emplace(e); } + + //! @brief Reserve space for N elements if applicable for container. + template + void do_reserve(const C&...) {} + template + auto do_reserve(C &c, std::size_t N) -> decltype(c.reserve(N)) { return c.reserve(N); } + + // The value_type of STL map-like containers come in the form std::pair. + // Since we can't {de}serialize const types in this lib, we must convert this to std::pair + template + struct serializable_value_type + { using type = typename Container::value_type; }; + template + struct serializable_value_type> + { using type = std::pair; }; } } @@ -82,7 +102,7 @@ bool do_serialize_container(Archive &ar, C &v) for (size_t i = 0; i < cnt; i++) { if (i > 0) ar.delimit_array(); - typename C::value_type e; + typename ::serialization::detail::serializable_value_type::type e; if (!::serialization::detail::serialize_container_element(ar, e)) return false; ::serialization::detail::do_add(v, std::move(e)); @@ -104,7 +124,8 @@ bool do_serialize_container(Archive &ar, C &v) return false; if (i != v.begin()) ar.delimit_array(); - if(!::serialization::detail::serialize_container_element(ar, (typename C::value_type&)*i)) + using serializable_value_type = typename ::serialization::detail::serializable_value_type::type; + if(!::serialization::detail::serialize_container_element(ar, (serializable_value_type&)*i)) return false; if (!ar.good()) return false; diff --git a/src/serialization/containers.h b/src/serialization/containers.h index 65e6359b2..28eaa50fb 100644 --- a/src/serialization/containers.h +++ b/src/serialization/containers.h @@ -38,91 +38,26 @@ #include #include "serialization.h" -template