mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
partial merge #19032: Serialization improvements: final step
71f016c6eb42e1ac2c905e04ba4d20c2009e533f Remove old serialization primitives (Pieter Wuille) 92beff15d3ae2646c00bd78146d7592a7097ce9c Convert LimitedString to formatter (Pieter Wuille) ef17c03e074b6c3f185afa4eff572ba687c2a171 Convert wallet to new serialization (Pieter Wuille) 65c589e45e8b8914698a0fd25cd5aafdda30869c Convert Qt to new serialization (Pieter Wuille) Pull request description: This is the final step 🥳 of the serialization improvements extracted from #10785. It converts the LimitedString wrapper to a new-style formatter, and updates the wallet and Qt code to use the new serialization framework. Finally all remaining old primitives are removed. ACKs for top commit: jonatack: ACK 71f016c6eb42e1ac2 reviewed diff, builds/tests/re-fuzzed. laanwj: Code review ACK 71f016c6eb42e1ac2c905e04ba4d20c2009e533f Tree-SHA512: d952194bc73259f6510bd4ab1348a1febbbf9862af30f905991812fb0e1f23f15948cdb3fc662be54d648e8f6d95b11060055d2e7a8c2cb5bf008224870b1ea1
This commit is contained in:
parent
6e5210adeb
commit
9029448233
@ -22,19 +22,11 @@ public:
|
||||
QDateTime date;
|
||||
SendCoinsRecipient recipient;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
unsigned int nDate = date.toTime_t();
|
||||
|
||||
READWRITE(this->nVersion);
|
||||
READWRITE(id);
|
||||
READWRITE(nDate);
|
||||
READWRITE(recipient);
|
||||
|
||||
if (ser_action.ForRead())
|
||||
date = QDateTime::fromTime_t(nDate);
|
||||
SERIALIZE_METHODS(RecentRequestEntry, obj) {
|
||||
unsigned int date_timet;
|
||||
SER_WRITE(obj, date_timet = obj.date.toTime_t());
|
||||
READWRITE(obj.nVersion, obj.id, date_timet, obj.recipient);
|
||||
SER_READ(obj, obj.date = QDateTime::fromTime_t(date_timet));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -70,34 +70,28 @@ public:
|
||||
static const int CURRENT_VERSION = 1;
|
||||
int nVersion;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
SERIALIZE_METHODS(SendCoinsRecipient, obj)
|
||||
{
|
||||
std::string address_str, label_str, message_str, auth_merchant_str, sPaymentRequest;
|
||||
PaymentRequestPlus paymentRequest;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
std::string sAddress = address.toStdString();
|
||||
std::string sLabel = label.toStdString();
|
||||
std::string sMessage = message.toStdString();
|
||||
std::string sPaymentRequest;
|
||||
if (!ser_action.ForRead() && paymentRequest.IsInitialized())
|
||||
SER_WRITE(obj, address_str = obj.address.toStdString());
|
||||
SER_WRITE(obj, label_str = obj.label.toStdString());
|
||||
SER_WRITE(obj, message_str = obj.message.toStdString());
|
||||
SER_WRITE(obj, auth_merchant_str = obj.authenticatedMerchant.toStdString());
|
||||
SER_WRITE(obj, paymentRequest = obj.paymentRequest);
|
||||
if (paymentRequest.IsInitialized()) {
|
||||
paymentRequest.SerializeToString(&sPaymentRequest);
|
||||
std::string sAuthenticatedMerchant = authenticatedMerchant.toStdString();
|
||||
}
|
||||
|
||||
READWRITE(this->nVersion);
|
||||
READWRITE(sAddress);
|
||||
READWRITE(sLabel);
|
||||
READWRITE(amount);
|
||||
READWRITE(sMessage);
|
||||
READWRITE(sPaymentRequest);
|
||||
READWRITE(sAuthenticatedMerchant);
|
||||
READWRITE(obj.nVersion, address_str, label_str, obj.amount, message_str, sPaymentRequest, auth_merchant_str);
|
||||
|
||||
if (ser_action.ForRead())
|
||||
{
|
||||
address = QString::fromStdString(sAddress);
|
||||
label = QString::fromStdString(sLabel);
|
||||
message = QString::fromStdString(sMessage);
|
||||
if (!sPaymentRequest.empty())
|
||||
paymentRequest.parse(QByteArray::fromRawData(sPaymentRequest.data(), sPaymentRequest.size()));
|
||||
authenticatedMerchant = QString::fromStdString(sAuthenticatedMerchant);
|
||||
SER_READ(obj, obj.address = QString::fromStdString(address_str));
|
||||
SER_READ(obj, obj.label = QString::fromStdString(label_str));
|
||||
SER_READ(obj, obj.message = QString::fromStdString(message_str));
|
||||
SER_READ(obj, obj.authenticatedMerchant = QString::fromStdString(auth_merchant_str));
|
||||
if (!sPaymentRequest.empty()) {
|
||||
SER_READ(obj, obj.paymentRequest.parse(QByteArray::fromRawData(sPaymentRequest.data(), sPaymentRequest.size())));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -46,26 +46,6 @@ static const unsigned int MAX_VECTOR_ALLOCATE = 5000000;
|
||||
struct deserialize_type {};
|
||||
constexpr deserialize_type deserialize {};
|
||||
|
||||
/**
|
||||
* Used to bypass the rule against non-const reference to temporary
|
||||
* where it makes sense with wrappers.
|
||||
*/
|
||||
template<typename T>
|
||||
inline T& REF(const T& val)
|
||||
{
|
||||
return const_cast<T&>(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to acquire a non-const pointer "this" to generate bodies
|
||||
* of const serialization operations from a template
|
||||
*/
|
||||
template<typename T>
|
||||
inline T* NCONST_PTR(const T* val)
|
||||
{
|
||||
return const_cast<T*>(val);
|
||||
}
|
||||
|
||||
//! Safely convert odd char pointer types to standard ones.
|
||||
inline char* CharCast(char* c) { return c; }
|
||||
inline char* CharCast(unsigned char* c) { return (char*)c; }
|
||||
@ -192,22 +172,6 @@ template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; }
|
||||
#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; })
|
||||
|
||||
/**
|
||||
* Implement three methods for serializable objects. These are actually wrappers over
|
||||
* "SerializationOp" template, which implements the body of each class' serialization
|
||||
* code. Adding "ADD_SERIALIZE_METHODS" in the body of the class causes these wrappers to be
|
||||
* added as members.
|
||||
*/
|
||||
#define ADD_SERIALIZE_METHODS \
|
||||
template<typename Stream> \
|
||||
void Serialize(Stream& s) const { \
|
||||
NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize()); \
|
||||
} \
|
||||
template<typename Stream> \
|
||||
void Unserialize(Stream& s) { \
|
||||
SerializationOp(s, CSerActionUnserialize()); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Ser and Unser methods needed for implementing a formatter (see Using below).
|
||||
*
|
||||
@ -507,7 +471,7 @@ static inline Wrapper<Formatter, T&> Using(T&& t) { return Wrapper<Formatter, T&
|
||||
#define AUTOBITSET(obj, size) CAutoBitSet(REF(obj), (size))
|
||||
#define VARINT(obj, ...) Using<VarIntFormatter<__VA_ARGS__>>(obj)
|
||||
#define COMPACTSIZE(obj) Using<CompactSizeFormatter>(obj)
|
||||
#define LIMITED_STRING(obj,n) LimitedString< n >(REF(obj))
|
||||
#define LIMITED_STRING(obj,n) Using<LimitedStringFormatter<n>>(obj)
|
||||
|
||||
class CFixedBitSet
|
||||
{
|
||||
@ -748,31 +712,23 @@ struct CompactSizeFormatter
|
||||
};
|
||||
|
||||
template<size_t Limit>
|
||||
class LimitedString
|
||||
struct LimitedStringFormatter
|
||||
{
|
||||
protected:
|
||||
std::string& string;
|
||||
public:
|
||||
explicit LimitedString(std::string& _string) : string(_string) {}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s)
|
||||
void Unser(Stream& s, std::string& v)
|
||||
{
|
||||
size_t size = ReadCompactSize(s);
|
||||
if (size > Limit) {
|
||||
throw std::ios_base::failure("String length limit exceeded");
|
||||
}
|
||||
string.resize(size);
|
||||
if (size != 0)
|
||||
s.read((char*)string.data(), size);
|
||||
v.resize(size);
|
||||
if (size != 0) s.read((char*)v.data(), size);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s) const
|
||||
void Ser(Stream& s, const std::string& v)
|
||||
{
|
||||
WriteCompactSize(s, string.size());
|
||||
if (!string.empty())
|
||||
s.write((char*)string.data(), string.size());
|
||||
s << v;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1330,7 +1286,7 @@ void Unserialize(Stream& is, std::shared_ptr<T>& p)
|
||||
|
||||
|
||||
/**
|
||||
* Support for ADD_SERIALIZE_METHODS and READWRITE macro
|
||||
* Support for SERIALIZE_METHODS and READWRITE macro.
|
||||
*/
|
||||
struct CSerActionSerialize
|
||||
{
|
||||
|
@ -44,15 +44,9 @@ public:
|
||||
//! such as the various parameters to scrypt
|
||||
std::vector<unsigned char> vchOtherDerivationParameters;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(vchCryptedKey);
|
||||
READWRITE(vchSalt);
|
||||
READWRITE(nDerivationMethod);
|
||||
READWRITE(nDeriveIterations);
|
||||
READWRITE(vchOtherDerivationParameters);
|
||||
SERIALIZE_METHODS(CMasterKey, obj)
|
||||
{
|
||||
READWRITE(obj.vchCryptedKey, obj.vchSalt, obj.nDerivationMethod, obj.nDeriveIterations, obj.vchOtherDerivationParameters);
|
||||
}
|
||||
|
||||
CMasterKey()
|
||||
|
@ -116,27 +116,30 @@ public:
|
||||
CKeyPool();
|
||||
CKeyPool(const CPubKey& vchPubKeyIn, bool fInternalIn);
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s) const
|
||||
{
|
||||
int nVersion = s.GetVersion();
|
||||
if (!(s.GetType() & SER_GETHASH))
|
||||
READWRITE(nVersion);
|
||||
READWRITE(nTime);
|
||||
READWRITE(vchPubKey);
|
||||
if (ser_action.ForRead()) {
|
||||
try {
|
||||
READWRITE(fInternal);
|
||||
}
|
||||
catch (std::ios_base::failure&) {
|
||||
/* flag as external address if we can't read the internal boolean
|
||||
(this will be the case for any wallet before the HD chain split version) */
|
||||
fInternal = false;
|
||||
}
|
||||
if (!(s.GetType() & SER_GETHASH)) {
|
||||
s << nVersion;
|
||||
}
|
||||
else {
|
||||
READWRITE(fInternal);
|
||||
s << nTime << vchPubKey << fInternal;
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s)
|
||||
{
|
||||
int nVersion = s.GetVersion();
|
||||
if (!(s.GetType() & SER_GETHASH)) {
|
||||
s >> nVersion;
|
||||
}
|
||||
s >> nTime >> vchPubKey;
|
||||
try {
|
||||
s >> fInternal;
|
||||
} catch (std::ios_base::failure&) {
|
||||
/* flag as external address if we can't read the internal boolean
|
||||
(this will be the case for any wallet before the HD chain split version) */
|
||||
fInternal = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -74,12 +74,9 @@ public:
|
||||
nCreateTime = nCreateTime_;
|
||||
}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(this->nVersion);
|
||||
READWRITE(nCreateTime);
|
||||
SERIALIZE_METHODS(CKeyMetadata, obj)
|
||||
{
|
||||
READWRITE(obj.nVersion, obj.nCreateTime);
|
||||
}
|
||||
|
||||
void SetNull()
|
||||
|
Loading…
Reference in New Issue
Block a user