Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Resolve mainnet v19 fork issues #5403

Merged
merged 10 commits into from
Jun 4, 2023
33 changes: 17 additions & 16 deletions src/bls/bls.h
Original file line number Diff line number Diff line change
Expand Up @@ -418,10 +418,7 @@ class CBLSLazyWrapper
CBLSLazyWrapper() :
vecBytes(BLSObject::SerSize, 0),
bufLegacyScheme(bls::bls_legacy_scheme.load())
{
// the all-zero buf is considered a valid buf, but the resulting object will return false for IsValid
bufValid = true;
}
{}

explicit CBLSLazyWrapper(const CBLSLazyWrapper& r)
{
Expand Down Expand Up @@ -459,12 +456,8 @@ class CBLSLazyWrapper
{
std::unique_lock<std::mutex> l(mutex);
if (!objInitialized && !bufValid) {
// the all-zero buf is considered a valid buf
std::fill(vecBytes.begin(), vecBytes.end(), 0);
bufLegacyScheme = specificLegacyScheme;
bufValid = true;
}
if (!bufValid || (bufLegacyScheme != specificLegacyScheme)) {
} else if (!bufValid || (bufLegacyScheme != specificLegacyScheme)) {
vecBytes = obj.ToByteVector(specificLegacyScheme);
bufValid = true;
bufLegacyScheme = specificLegacyScheme;
Expand All @@ -476,7 +469,7 @@ class CBLSLazyWrapper
template<typename Stream>
inline void Serialize(Stream& s) const
{
Serialize(s, bls::bls_legacy_scheme.load());
Serialize(s, bufLegacyScheme);
}

template<typename Stream>
Expand All @@ -493,13 +486,14 @@ class CBLSLazyWrapper
template<typename Stream>
inline void Unserialize(Stream& s) const
{
Unserialize(s, bls::bls_legacy_scheme.load());
Unserialize(s, bufLegacyScheme);
}

void Set(const BLSObject& _obj)
void Set(const BLSObject& _obj, const bool specificLegacyScheme)
{
std::unique_lock<std::mutex> l(mutex);
bufValid = false;
bufLegacyScheme = specificLegacyScheme;
objInitialized = true;
obj = _obj;
hash.SetNull();
Expand Down Expand Up @@ -549,13 +543,15 @@ class CBLSLazyWrapper
return !(*this == r);
}

uint256 GetHash(const bool specificLegacyScheme = bls::bls_legacy_scheme.load()) const
uint256 GetHash() const
{
std::unique_lock<std::mutex> l(mutex);
if (!bufValid || bufLegacyScheme != specificLegacyScheme) {
vecBytes = obj.ToByteVector(specificLegacyScheme);
if (!objInitialized && !bufValid) {
std::fill(vecBytes.begin(), vecBytes.end(), 0);
hash.SetNull();
} else if (!bufValid) {
vecBytes = obj.ToByteVector(bufLegacyScheme);
bufValid = true;
bufLegacyScheme = specificLegacyScheme;
hash.SetNull();
}
if (hash.IsNull()) {
Expand All @@ -565,6 +561,11 @@ class CBLSLazyWrapper
}
return hash;
}

std::string ToString() const
{
return Get().ToString(bufLegacyScheme);
}
};
using CBLSLazySignature = CBLSLazyWrapper<CBLSSignature>;
using CBLSLazyPublicKey = CBLSLazyWrapper<CBLSPublicKey>;
Expand Down
191 changes: 129 additions & 62 deletions src/evo/deterministicmns.cpp

Large diffs are not rendered by default.

53 changes: 37 additions & 16 deletions src/evo/deterministicmns.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ class CDeterministicMN
uint64_t internalId{std::numeric_limits<uint64_t>::max()};

public:
static constexpr uint16_t CURRENT_MN_FORMAT = 0;
static constexpr uint16_t MN_OLD_FORMAT = 0;
static constexpr uint16_t MN_TYPE_FORMAT = 1;
static constexpr uint16_t MN_VERSION_FORMAT = 2;
static constexpr uint16_t MN_CURRENT_FORMAT = MN_VERSION_FORMAT;

uint256 proTxHash;
COutPoint collateralOutpoint;
Expand Down Expand Up @@ -73,12 +75,16 @@ class CDeterministicMN
READWRITE(VARINT(internalId));
READWRITE(collateralOutpoint);
READWRITE(nOperatorReward);
// We need to read CDeterministicMNState using the old format only when called with CURRENT_MN_FORMAT on Unserialize()
// We need to read CDeterministicMNState using the old format only when called with MN_OLD_FORMAT or MN_TYPE_FORMAT on Unserialize()
// Serialisation (writing) will be done always using new format
if (ser_action.ForRead() && format_version == CURRENT_MN_FORMAT) {
if (ser_action.ForRead() && format_version == MN_OLD_FORMAT) {
CDeterministicMNState_Oldformat old_state;
READWRITE(old_state);
pdmnState = std::make_shared<const CDeterministicMNState>(old_state);
} else if (ser_action.ForRead() && format_version == MN_TYPE_FORMAT) {
CDeterministicMNState_mntype_format old_state;
READWRITE(old_state);
pdmnState = std::make_shared<const CDeterministicMNState>(old_state);
} else {
READWRITE(pdmnState);
}
Expand All @@ -97,11 +103,11 @@ class CDeterministicMN
template<typename Stream>
void Serialize(Stream& s) const
{
const_cast<CDeterministicMN*>(this)->SerializationOp(s, CSerActionSerialize(), MN_TYPE_FORMAT);
const_cast<CDeterministicMN*>(this)->SerializationOp(s, CSerActionSerialize(), MN_CURRENT_FORMAT);
}

template <typename Stream>
void Unserialize(Stream& s, const uint8_t format_version = MN_TYPE_FORMAT)
void Unserialize(Stream& s, const uint8_t format_version = MN_CURRENT_FORMAT)
{
SerializationOp(s, CSerActionUnserialize(), format_version);
}
Expand Down Expand Up @@ -203,14 +209,14 @@ class CDeterministicMNList
}

template<typename Stream>
void Unserialize(Stream& s, const uint8_t format_version = CDeterministicMN::MN_TYPE_FORMAT) {
void Unserialize(Stream& s, const uint8_t format_version = CDeterministicMN::MN_CURRENT_FORMAT) {
mnMap = MnMap();
mnUniquePropertyMap = MnUniquePropertyMap();
mnInternalIdMap = MnInternalIdMap();

SerializationOpBase(s, CSerActionUnserialize());

bool evodb_migration = (format_version == CDeterministicMN::CURRENT_MN_FORMAT);
bool evodb_migration = (format_version == CDeterministicMN::MN_OLD_FORMAT || format_version == CDeterministicMN::MN_TYPE_FORMAT);
size_t cnt = ReadCompactSize(s);
for (size_t i = 0; i < cnt; i++) {
if (evodb_migration) {
Expand Down Expand Up @@ -383,8 +389,6 @@ class CDeterministicMNList
[[nodiscard]] CDeterministicMNListDiff BuildDiff(const CDeterministicMNList& to) const;
[[nodiscard]] CDeterministicMNList ApplyDiff(const CBlockIndex* pindex, const CDeterministicMNListDiff& diff) const;

void RepopulateUniquePropertyMap();

void AddMN(const CDeterministicMNCPtr& dmn, bool fBumpTotalCount = true);
void UpdateMN(const CDeterministicMN& oldDmn, const std::shared_ptr<const CDeterministicMNState>& pdmnState);
void UpdateMN(const uint256& proTxHash, const std::shared_ptr<const CDeterministicMNState>& pdmnState);
Expand All @@ -394,19 +398,27 @@ class CDeterministicMNList
template <typename T>
[[nodiscard]] bool HasUniqueProperty(const T& v) const
{
return mnUniquePropertyMap.count(::SerializeHash(v)) != 0;
return mnUniquePropertyMap.count(GetUniquePropertyHash(v)) != 0;
}
template <typename T>
[[nodiscard]] CDeterministicMNCPtr GetUniquePropertyMN(const T& v) const
{
auto p = mnUniquePropertyMap.find(::SerializeHash(v));
auto p = mnUniquePropertyMap.find(GetUniquePropertyHash(v));
if (!p) {
return nullptr;
}
return GetMN(p->first);
}

private:
template <typename T>
[[nodiscard]] uint256 GetUniquePropertyHash(const T& v) const
{
if constexpr (std::is_same<T, CBLSPublicKey>()) {
assert(false);
}
return ::SerializeHash(v);
}
template <typename T>
[[nodiscard]] bool AddUniqueProperty(const CDeterministicMN& dmn, const T& v)
{
Expand All @@ -415,7 +427,7 @@ class CDeterministicMNList
return false;
}

auto hash = ::SerializeHash(v);
auto hash = GetUniquePropertyHash(v);
auto oldEntry = mnUniquePropertyMap.find(hash);
if (oldEntry != nullptr && oldEntry->first != dmn.proTxHash) {
return false;
Expand All @@ -435,7 +447,7 @@ class CDeterministicMNList
return false;
}

auto oldHash = ::SerializeHash(oldValue);
auto oldHash = GetUniquePropertyHash(oldValue);
auto p = mnUniquePropertyMap.find(oldHash);
if (p == nullptr || p->first != dmn.proTxHash) {
return false;
Expand Down Expand Up @@ -464,6 +476,16 @@ class CDeterministicMNList
}
return true;
}

friend bool operator==(const CDeterministicMNList& a, const CDeterministicMNList& b)
{
return a.blockHash == b.blockHash &&
a.nHeight == b.nHeight &&
a.nTotalRegisteredCount == b.nTotalRegisteredCount &&
a.mnMap == b.mnMap &&
a.mnInternalIdMap == b.mnInternalIdMap &&
a.mnUniquePropertyMap == b.mnUniquePropertyMap;
}
};

class CDeterministicMNListDiff
Expand Down Expand Up @@ -492,7 +514,7 @@ class CDeterministicMNListDiff
}

template <typename Stream>
void Unserialize(Stream& s, const uint8_t format_version = CDeterministicMN::MN_TYPE_FORMAT)
void Unserialize(Stream& s, const uint8_t format_version = CDeterministicMN::MN_CURRENT_FORMAT)
{
updatedMNs.clear();
removedMns.clear();
Expand All @@ -502,8 +524,6 @@ class CDeterministicMNListDiff
tmp = ReadCompactSize(s);
for (size_t i = 0; i < tmp; i++) {
CDeterministicMN mn(0);
// Unserialise CDeterministicMN using CURRENT_MN_FORMAT and set it's type to the default value TYPE_REGULAR_MASTERNODE
// It will be later written with format MN_TYPE_FORMAT which includes the type field.
mn.Unserialize(s, format_version);
auto dmn = std::make_shared<CDeterministicMN>(mn);
addedMNs.push_back(dmn);
Expand Down Expand Up @@ -595,6 +615,7 @@ class CDeterministicMNManager
bool IsDIP3Enforced(int nHeight = -1) LOCKS_EXCLUDED(cs);

bool MigrateDBIfNeeded();
bool MigrateDBIfNeeded2();

void DoMaintenance() LOCKS_EXCLUDED(cs);

Expand Down
6 changes: 3 additions & 3 deletions src/evo/dmnstate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ std::string CDeterministicMNState::ToString() const
return strprintf("CDeterministicMNState(nRegisteredHeight=%d, nLastPaidHeight=%d, nPoSePenalty=%d, nPoSeRevivedHeight=%d, nPoSeBanHeight=%d, nRevocationReason=%d, "
"ownerAddress=%s, pubKeyOperator=%s, votingAddress=%s, addr=%s, payoutAddress=%s, operatorPayoutAddress=%s)",
nRegisteredHeight, nLastPaidHeight, nPoSePenalty, nPoSeRevivedHeight, nPoSeBanHeight, nRevocationReason,
EncodeDestination(PKHash(keyIDOwner)), pubKeyOperator.Get().ToString(), EncodeDestination(PKHash(keyIDVoting)), addr.ToStringIPPort(false), payoutAddress, operatorPayoutAddress);
EncodeDestination(PKHash(keyIDOwner)), pubKeyOperator.ToString(), EncodeDestination(PKHash(keyIDVoting)), addr.ToStringIPPort(false), payoutAddress, operatorPayoutAddress);
}

void CDeterministicMNState::ToJson(UniValue& obj, MnType nType) const
Expand All @@ -55,7 +55,7 @@ void CDeterministicMNState::ToJson(UniValue& obj, MnType nType) const
if (ExtractDestination(scriptPayout, dest)) {
obj.pushKV("payoutAddress", EncodeDestination(dest));
}
obj.pushKV("pubKeyOperator", pubKeyOperator.Get().ToString());
obj.pushKV("pubKeyOperator", pubKeyOperator.ToString());
if (ExtractDestination(scriptOperatorPayout, dest)) {
obj.pushKV("operatorPayoutAddress", EncodeDestination(dest));
}
Expand Down Expand Up @@ -108,7 +108,7 @@ void CDeterministicMNStateDiff::ToJson(UniValue& obj, MnType nType) const
}
}
if (fields & Field_pubKeyOperator) {
obj.pushKV("pubKeyOperator", state.pubKeyOperator.Get().ToString());
obj.pushKV("pubKeyOperator", state.pubKeyOperator.ToString());
}
if (nType == MnType::HighPerformance) {
if (fields & Field_platformNodeID) {
Expand Down
Loading