Skip to content

Commit 733cdbc

Browse files
committed
feat: introduce CDeterministicMNStateDiffLegacy class with original field positions and conversion to new format
1 parent d7319b6 commit 733cdbc

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed

src/evo/dmnstate.h

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class CDeterministicMNState
3535
int nPoSeBanHeight{-1};
3636

3737
friend class CDeterministicMNStateDiff;
38+
friend class CDeterministicMNStateDiffLegacy;
3839

3940
public:
4041
int nVersion{ProTxVersion::LegacyBLS};
@@ -284,4 +285,139 @@ class CDeterministicMNStateDiff
284285
}
285286
};
286287

288+
// Legacy deserializer class
289+
class CDeterministicMNStateDiffLegacy
290+
{
291+
private:
292+
// Legacy field enum with original bit positions
293+
enum LegacyField : uint32_t {
294+
LegacyField_nRegisteredHeight = 0x0001,
295+
LegacyField_nLastPaidHeight = 0x0002,
296+
LegacyField_nPoSePenalty = 0x0004,
297+
LegacyField_nPoSeRevivedHeight = 0x0008,
298+
LegacyField_nPoSeBanHeight = 0x0010,
299+
LegacyField_nRevocationReason = 0x0020,
300+
LegacyField_confirmedHash = 0x0040,
301+
LegacyField_confirmedHashWithProRegTxHash = 0x0080,
302+
LegacyField_keyIDOwner = 0x0100,
303+
LegacyField_pubKeyOperator = 0x0200,
304+
LegacyField_keyIDVoting = 0x0400,
305+
LegacyField_netInfo = 0x0800,
306+
LegacyField_scriptPayout = 0x1000,
307+
LegacyField_scriptOperatorPayout = 0x2000,
308+
LegacyField_nConsecutivePayments = 0x4000,
309+
LegacyField_platformNodeID = 0x8000,
310+
LegacyField_platformP2PPort = 0x10000,
311+
LegacyField_platformHTTPPort = 0x20000,
312+
LegacyField_nVersion = 0x40000,
313+
};
314+
315+
// Legacy member template with old bit positions
316+
template <auto CDeterministicMNState::*Field, uint32_t Mask>
317+
struct LegacyMember {
318+
static constexpr uint32_t mask = Mask;
319+
static auto& get(CDeterministicMNState& state) { return state.*Field; }
320+
static const auto& get(const CDeterministicMNState& state) { return state.*Field; }
321+
};
322+
323+
#define LEGACY_DMN_STATE_MEMBER(name) \
324+
LegacyMember<&CDeterministicMNState::name, LegacyField_##name> {}
325+
static constexpr auto legacy_members = boost::hana::make_tuple(
326+
LEGACY_DMN_STATE_MEMBER(nRegisteredHeight),
327+
LEGACY_DMN_STATE_MEMBER(nLastPaidHeight),
328+
LEGACY_DMN_STATE_MEMBER(nPoSePenalty),
329+
LEGACY_DMN_STATE_MEMBER(nPoSeRevivedHeight),
330+
LEGACY_DMN_STATE_MEMBER(nPoSeBanHeight),
331+
LEGACY_DMN_STATE_MEMBER(nRevocationReason),
332+
LEGACY_DMN_STATE_MEMBER(confirmedHash),
333+
LEGACY_DMN_STATE_MEMBER(confirmedHashWithProRegTxHash),
334+
LEGACY_DMN_STATE_MEMBER(keyIDOwner),
335+
LEGACY_DMN_STATE_MEMBER(pubKeyOperator),
336+
LEGACY_DMN_STATE_MEMBER(keyIDVoting),
337+
LEGACY_DMN_STATE_MEMBER(netInfo),
338+
LEGACY_DMN_STATE_MEMBER(scriptPayout),
339+
LEGACY_DMN_STATE_MEMBER(scriptOperatorPayout),
340+
LEGACY_DMN_STATE_MEMBER(nConsecutivePayments),
341+
LEGACY_DMN_STATE_MEMBER(platformNodeID),
342+
LEGACY_DMN_STATE_MEMBER(platformP2PPort),
343+
LEGACY_DMN_STATE_MEMBER(platformHTTPPort),
344+
LEGACY_DMN_STATE_MEMBER(nVersion)
345+
);
346+
#undef LEGACY_DMN_STATE_MEMBER
347+
348+
public:
349+
uint32_t fields{0};
350+
CDeterministicMNState state;
351+
352+
CDeterministicMNStateDiffLegacy() = default;
353+
354+
template <typename Stream>
355+
CDeterministicMNStateDiffLegacy(deserialize_type, Stream& s) { s >> *this; }
356+
357+
// Deserialize using legacy format
358+
SERIALIZE_METHODS(CDeterministicMNStateDiffLegacy, obj)
359+
{
360+
READWRITE(VARINT(obj.fields));
361+
362+
bool read_pubkey{false};
363+
boost::hana::for_each(legacy_members, [&](auto&& member) {
364+
using BaseType = std::decay_t<decltype(member)>;
365+
if constexpr (BaseType::mask == LegacyField_pubKeyOperator) {
366+
if (obj.fields & member.mask) {
367+
SER_READ(obj, read_pubkey = true);
368+
READWRITE(CBLSLazyPublicKeyVersionWrapper(const_cast<CBLSLazyPublicKey&>(obj.state.pubKeyOperator),
369+
obj.state.nVersion == ProTxVersion::LegacyBLS));
370+
}
371+
} else if constexpr (BaseType::mask == LegacyField_netInfo) {
372+
if (obj.fields & member.mask) {
373+
// Legacy format supports non-extended addresses only
374+
READWRITE(NetInfoSerWrapper(const_cast<std::shared_ptr<NetInfoInterface>&>(obj.state.netInfo), false));
375+
}
376+
} else {
377+
if (obj.fields & member.mask) {
378+
READWRITE(member.get(obj.state));
379+
}
380+
}
381+
});
382+
383+
if (read_pubkey) {
384+
SER_READ(obj, obj.fields |= LegacyField_nVersion);
385+
SER_READ(obj, obj.state.pubKeyOperator.SetLegacy(obj.state.nVersion == ProTxVersion::LegacyBLS));
386+
}
387+
}
388+
389+
// Convert to new format
390+
CDeterministicMNStateDiff ToNewFormat() const
391+
{
392+
CDeterministicMNStateDiff newDiff;
393+
newDiff.state = state;
394+
395+
// Convert field bits to new positions
396+
#define LEGACY_DMN_STATE_BITS(name) \
397+
if (fields & LegacyField_##name) newDiff.fields |= CDeterministicMNStateDiff::Field_##name;
398+
LEGACY_DMN_STATE_BITS(nVersion)
399+
LEGACY_DMN_STATE_BITS(nRegisteredHeight)
400+
LEGACY_DMN_STATE_BITS(nLastPaidHeight)
401+
LEGACY_DMN_STATE_BITS(nPoSePenalty)
402+
LEGACY_DMN_STATE_BITS(nPoSeRevivedHeight)
403+
LEGACY_DMN_STATE_BITS(nPoSeBanHeight)
404+
LEGACY_DMN_STATE_BITS(nRevocationReason)
405+
LEGACY_DMN_STATE_BITS(confirmedHash)
406+
LEGACY_DMN_STATE_BITS(confirmedHashWithProRegTxHash)
407+
LEGACY_DMN_STATE_BITS(keyIDOwner)
408+
LEGACY_DMN_STATE_BITS(pubKeyOperator)
409+
LEGACY_DMN_STATE_BITS(keyIDVoting)
410+
LEGACY_DMN_STATE_BITS(netInfo)
411+
LEGACY_DMN_STATE_BITS(scriptPayout)
412+
LEGACY_DMN_STATE_BITS(scriptOperatorPayout)
413+
LEGACY_DMN_STATE_BITS(nConsecutivePayments)
414+
LEGACY_DMN_STATE_BITS(platformNodeID)
415+
LEGACY_DMN_STATE_BITS(platformP2PPort)
416+
LEGACY_DMN_STATE_BITS(platformHTTPPort)
417+
#undef LEGACY_DMN_STATE_BITS
418+
419+
return newDiff;
420+
}
421+
};
422+
287423
#endif // BITCOIN_EVO_DMNSTATE_H

0 commit comments

Comments
 (0)