fix serialization being different on mac

On Mac, size_t is a distinct type from uint64_t, and some
types (in wallet cache as well as cold/hot wallet transfer
data) use pairs/containers with size_t as fields. Mac would
save those as full size, while other platforms would save
them as varints. Might apply to other platforms where the
types are distinct.

There's a nasty hack for backward compatibility, which can
go after a couple forks.
This commit is contained in:
moneromooo-monero 2021-01-12 18:24:55 +00:00
parent b8f3e44a3f
commit f9b5b521e8
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
9 changed files with 64 additions and 27 deletions

View file

@ -30,21 +30,34 @@
#pragma once
#include <memory>
#include <boost/type_traits/make_unsigned.hpp>
#include "serialization.h"
namespace serialization
{
namespace detail
{
template<typename T>
inline constexpr bool use_pair_varint() noexcept
{
return std::is_integral<T>::value && std::is_unsigned<T>::value && sizeof(T) > 1;
}
template <typename Archive, class T>
bool serialize_pair_element(Archive& ar, T& e)
typename std::enable_if<!use_pair_varint<T>(), bool>::type
serialize_pair_element(Archive& ar, T& e)
{
return ::do_serialize(ar, e);
}
template <typename Archive>
bool serialize_pair_element(Archive& ar, uint64_t& e)
template<typename Archive, typename T>
typename std::enable_if<use_pair_varint<T>(), bool>::type
serialize_pair_element(Archive& ar, T& e)
{
static constexpr const bool previously_varint = std::is_same<uint64_t, T>();
if (!previously_varint && ar.varint_bug_backward_compatibility_enabled() && !typename Archive::is_saving())
return ::do_serialize(ar, e);
ar.serialize_varint(e);
return true;
}