Skip to content

Commit 78d057d

Browse files
ogabrielideskwvgUdjinM6PastaPastaPasta
authored
1 parent c549cc1 commit 78d057d

35 files changed

+647
-211
lines changed

src/bls/bls.h

Lines changed: 128 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ class CBLSWrapper
9999
*(static_cast<C*>(this)) = C();
100100
}
101101

102-
//TODO: Overwrite function with default value of specificLegacyScheme
103102
void SetByteVector(const std::vector<uint8_t>& vecBytes, const bool specificLegacyScheme)
104103
{
105104
if (vecBytes.size() != SerSize) {
@@ -125,7 +124,6 @@ class CBLSWrapper
125124
SetByteVector(vecBytes, bls::bls_legacy_scheme.load());
126125
}
127126

128-
//TODO: Overwrite function with default value of specificLegacyScheme
129127
std::vector<uint8_t> ToByteVector(const bool specificLegacyScheme) const
130128
{
131129
if (!fValid) {
@@ -147,8 +145,7 @@ class CBLSWrapper
147145
return cachedHash;
148146
}
149147

150-
//TODO: Add version with argument (bool specificLegacyScheme)
151-
bool SetHexStr(const std::string& str)
148+
bool SetHexStr(const std::string& str, const bool specificLegacyScheme)
152149
{
153150
if (!IsHex(str)) {
154151
Reset();
@@ -159,16 +156,20 @@ class CBLSWrapper
159156
Reset();
160157
return false;
161158
}
162-
SetByteVector(b);
159+
SetByteVector(b, specificLegacyScheme);
163160
return IsValid();
164161
}
165162

163+
bool SetHexStr(const std::string& str)
164+
{
165+
return SetHexStr(str, bls::bls_legacy_scheme.load());
166+
}
167+
166168
inline void Serialize(CSizeComputer& s) const
167169
{
168170
s.seek(SerSize);
169171
}
170172

171-
//TODO: Overwrite function with default value of specificLegacyScheme
172173
template <typename Stream>
173174
inline void Serialize(Stream& s, const bool specificLegacyScheme) const
174175
{
@@ -181,15 +182,14 @@ class CBLSWrapper
181182
Serialize(s, bls::bls_legacy_scheme.load());
182183
}
183184

184-
//TODO: Overwrite function with default value of specificLegacyScheme
185185
template <typename Stream>
186186
inline void Unserialize(Stream& s, const bool specificLegacyScheme, bool checkMalleable = true)
187187
{
188188
std::vector<uint8_t> vecBytes(SerSize, 0);
189189
s.read(reinterpret_cast<char*>(vecBytes.data()), SerSize);
190190
SetByteVector(vecBytes, specificLegacyScheme);
191191

192-
if (checkMalleable && !CheckMalleable(vecBytes)) {
192+
if (checkMalleable && !CheckMalleable(vecBytes, specificLegacyScheme)) {
193193
throw std::ios_base::failure("malleable BLS object");
194194
}
195195
}
@@ -200,7 +200,6 @@ class CBLSWrapper
200200
Unserialize(s, bls::bls_legacy_scheme.load(), checkMalleable);
201201
}
202202

203-
//TODO: Overwrite function with default value of specificLegacyScheme
204203
inline bool CheckMalleable(const std::vector<uint8_t>& vecBytes, const bool specificLegacyScheme) const
205204
{
206205
if (memcmp(vecBytes.data(), ToByteVector(specificLegacyScheme).data(), SerSize)) {
@@ -305,6 +304,44 @@ class CBLSPublicKey : public CBLSWrapper<bls::G1Element, BLS_CURVE_PUBKEY_SIZE,
305304

306305
};
307306

307+
class ConstCBLSPublicKeyVersionWrapper {
308+
private:
309+
bool legacy;
310+
bool checkMalleable;
311+
const CBLSPublicKey& obj;
312+
public:
313+
ConstCBLSPublicKeyVersionWrapper(const CBLSPublicKey& obj, bool legacy, bool checkMalleable = true)
314+
: obj(obj)
315+
, legacy(legacy)
316+
, checkMalleable(checkMalleable)
317+
{}
318+
template <typename Stream>
319+
inline void Serialize(Stream& s) const {
320+
obj.Serialize(s, legacy);
321+
}
322+
};
323+
324+
class CBLSPublicKeyVersionWrapper {
325+
private:
326+
bool legacy;
327+
bool checkMalleable;
328+
CBLSPublicKey& obj;
329+
public:
330+
CBLSPublicKeyVersionWrapper(CBLSPublicKey& obj, bool legacy, bool checkMalleable = true)
331+
: obj(obj)
332+
, legacy(legacy)
333+
, checkMalleable(checkMalleable)
334+
{}
335+
template <typename Stream>
336+
inline void Serialize(Stream& s) const {
337+
obj.Serialize(s, legacy);
338+
}
339+
template <typename Stream>
340+
inline void Unserialize(Stream& s) {
341+
obj.Unserialize(s, legacy, checkMalleable);
342+
}
343+
};
344+
308345
class CBLSSignature : public CBLSWrapper<bls::G2Element, BLS_CURVE_SIG_SIZE, CBLSSignature>
309346
{
310347
friend class CBLSSecretKey;
@@ -332,6 +369,27 @@ class CBLSSignature : public CBLSWrapper<bls::G2Element, BLS_CURVE_SIG_SIZE, CBL
332369
bool Recover(const std::vector<CBLSSignature>& sigs, const std::vector<CBLSId>& ids);
333370
};
334371

372+
class CBLSSignatureVersionWrapper {
373+
private:
374+
bool legacy;
375+
bool checkMalleable;
376+
CBLSSignature& obj;
377+
public:
378+
CBLSSignatureVersionWrapper(CBLSSignature& obj, bool legacy, bool checkMalleable = true)
379+
: obj(obj)
380+
, legacy(legacy)
381+
, checkMalleable(checkMalleable)
382+
{}
383+
template <typename Stream>
384+
inline void Serialize(Stream& s) const {
385+
obj.Serialize(s, legacy);
386+
}
387+
template <typename Stream>
388+
inline void Unserialize(Stream& s, bool checkMalleable = true) {
389+
obj.Unserialize(s, legacy, checkMalleable);
390+
}
391+
};
392+
335393
#ifndef BUILD_BITCOIN_INTERNAL
336394
template<typename BLSObject>
337395
class CBLSLazyWrapper
@@ -341,6 +399,7 @@ class CBLSLazyWrapper
341399

342400
mutable std::vector<uint8_t> vecBytes;
343401
mutable bool bufValid{false};
402+
mutable bool bufLegacyScheme{true};
344403

345404
mutable BLSObject obj;
346405
mutable bool objInitialized{false};
@@ -349,7 +408,8 @@ class CBLSLazyWrapper
349408

350409
public:
351410
CBLSLazyWrapper() :
352-
vecBytes(BLSObject::SerSize, 0)
411+
vecBytes(BLSObject::SerSize, 0),
412+
bufLegacyScheme(bls::bls_legacy_scheme.load())
353413
{
354414
// the all-zero buf is considered a valid buf, but the resulting object will return false for IsValid
355415
bufValid = true;
@@ -365,6 +425,7 @@ class CBLSLazyWrapper
365425
{
366426
std::unique_lock<std::mutex> l(r.mutex);
367427
bufValid = r.bufValid;
428+
bufLegacyScheme = r.bufLegacyScheme;
368429
if (r.bufValid) {
369430
vecBytes = r.vecBytes;
370431
} else {
@@ -386,30 +447,47 @@ class CBLSLazyWrapper
386447
}
387448

388449
template<typename Stream>
389-
inline void Serialize(Stream& s) const
450+
inline void Serialize(Stream& s, const bool specificLegacyScheme) const
390451
{
391452
std::unique_lock<std::mutex> l(mutex);
392453
if (!objInitialized && !bufValid) {
393-
throw std::ios_base::failure("obj and buf not initialized");
454+
// the all-zero buf is considered a valid buf
455+
std::fill(vecBytes.begin(), vecBytes.end(), 0);
456+
bufLegacyScheme = specificLegacyScheme;
457+
bufValid = true;
394458
}
395-
if (!bufValid) {
396-
vecBytes = obj.ToByteVector();
459+
if (!bufValid || (bufLegacyScheme != specificLegacyScheme)) {
460+
vecBytes = obj.ToByteVector(specificLegacyScheme);
397461
bufValid = true;
462+
bufLegacyScheme = specificLegacyScheme;
398463
hash.SetNull();
399464
}
400465
s.write(reinterpret_cast<const char*>(vecBytes.data()), vecBytes.size());
401466
}
402467

403468
template<typename Stream>
404-
inline void Unserialize(Stream& s)
469+
inline void Serialize(Stream& s) const
470+
{
471+
Serialize(s, bls::bls_legacy_scheme.load());
472+
}
473+
474+
template<typename Stream>
475+
inline void Unserialize(Stream& s, const bool specificLegacyScheme) const
405476
{
406477
std::unique_lock<std::mutex> l(mutex);
407478
s.read(reinterpret_cast<char*>(vecBytes.data()), BLSObject::SerSize);
408479
bufValid = true;
480+
bufLegacyScheme = specificLegacyScheme;
409481
objInitialized = false;
410482
hash.SetNull();
411483
}
412484

485+
template<typename Stream>
486+
inline void Unserialize(Stream& s) const
487+
{
488+
Unserialize(s, bls::bls_legacy_scheme.load());
489+
}
490+
413491
void Set(const BLSObject& _obj)
414492
{
415493
std::unique_lock<std::mutex> l(mutex);
@@ -426,8 +504,17 @@ class CBLSLazyWrapper
426504
return invalidObj;
427505
}
428506
if (!objInitialized) {
429-
obj.SetByteVector(vecBytes);
430-
if (!obj.CheckMalleable(vecBytes)) {
507+
obj.SetByteVector(vecBytes, bufLegacyScheme);
508+
if (!obj.IsValid()) {
509+
// If setting of BLS object using one scheme failed, then we need to attempt again with the opposite scheme.
510+
// This is due to the fact that LazyBLSWrapper receives a serialised buffer but attempts to create actual BLS object when needed.
511+
// That could happen when the fork has been activated and the enforced scheme has switched.
512+
obj.SetByteVector(vecBytes, !bufLegacyScheme);
513+
if (obj.IsValid()) {
514+
bufLegacyScheme = !bufLegacyScheme;
515+
}
516+
}
517+
if (!obj.CheckMalleable(vecBytes, bufLegacyScheme)) {
431518
bufValid = false;
432519
objInitialized = false;
433520
obj = invalidObj;
@@ -440,7 +527,7 @@ class CBLSLazyWrapper
440527

441528
bool operator==(const CBLSLazyWrapper& r) const
442529
{
443-
if (bufValid && r.bufValid) {
530+
if (bufValid && r.bufValid && bufLegacyScheme == r.bufLegacyScheme) {
444531
return vecBytes == r.vecBytes;
445532
}
446533
if (objInitialized && r.objInitialized) {
@@ -454,12 +541,13 @@ class CBLSLazyWrapper
454541
return !(*this == r);
455542
}
456543

457-
uint256 GetHash() const
544+
uint256 GetHash(const bool specificLegacyScheme = bls::bls_legacy_scheme.load()) const
458545
{
459546
std::unique_lock<std::mutex> l(mutex);
460-
if (!bufValid) {
461-
vecBytes = obj.ToByteVector();
547+
if (!bufValid || bufLegacyScheme != specificLegacyScheme) {
548+
vecBytes = obj.ToByteVector(specificLegacyScheme);
462549
bufValid = true;
550+
bufLegacyScheme = specificLegacyScheme;
463551
hash.SetNull();
464552
}
465553
if (hash.IsNull()) {
@@ -472,6 +560,25 @@ class CBLSLazyWrapper
472560
};
473561
using CBLSLazySignature = CBLSLazyWrapper<CBLSSignature>;
474562
using CBLSLazyPublicKey = CBLSLazyWrapper<CBLSPublicKey>;
563+
564+
class CBLSLazyPublicKeyVersionWrapper {
565+
private:
566+
bool legacy;
567+
CBLSLazyPublicKey& obj;
568+
public:
569+
CBLSLazyPublicKeyVersionWrapper(CBLSLazyPublicKey& obj, bool legacy)
570+
: obj(obj)
571+
, legacy(legacy)
572+
{}
573+
template <typename Stream>
574+
inline void Serialize(Stream& s) const {
575+
obj.Serialize(s, legacy);
576+
}
577+
template <typename Stream>
578+
inline void Unserialize(Stream& s) {
579+
obj.Unserialize(s, legacy);
580+
}
581+
};
475582
#endif
476583

477584
using BLSIdVector = std::vector<CBLSId>;

src/coinjoin/coinjoin.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <consensus/validation.h>
1111
#include <llmq/chainlocks.h>
1212
#include <llmq/instantsend.h>
13+
#include <llmq/utils.h>
1314
#include <masternode/node.h>
1415
#include <masternode/sync.h>
1516
#include <messagesigner.h>
@@ -55,7 +56,8 @@ bool CCoinJoinQueue::Sign()
5556
if (!sig.IsValid()) {
5657
return false;
5758
}
58-
vchSig = sig.ToByteVector();
59+
bool legacy_bls_scheme = !llmq::utils::IsV19Active(::ChainActive().Tip());
60+
vchSig = sig.ToByteVector(legacy_bls_scheme);
5961

6062
return true;
6163
}
@@ -97,12 +99,12 @@ bool CCoinJoinBroadcastTx::Sign()
9799
if (!fMasternodeMode) return false;
98100

99101
uint256 hash = GetSignatureHash();
100-
101102
CBLSSignature sig = WITH_LOCK(activeMasternodeInfoCs, return activeMasternodeInfo.blsKeyOperator->Sign(hash));
102103
if (!sig.IsValid()) {
103104
return false;
104105
}
105-
vchSig = sig.ToByteVector();
106+
bool legacy_bls_scheme = !llmq::utils::IsV19Active(::ChainActive().Tip());
107+
vchSig = sig.ToByteVector(legacy_bls_scheme);
106108

107109
return true;
108110
}

src/evo/deterministicmns.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -354,14 +354,19 @@ CSimplifiedMNListDiff CDeterministicMNList::BuildSimplifiedDiff(const CDetermini
354354
CSimplifiedMNListDiff diffRet;
355355
diffRet.baseBlockHash = blockHash;
356356
diffRet.blockHash = to.blockHash;
357+
diffRet.nVersion = llmq::utils::IsV19Active(::ChainActive().Tip()) ? CSimplifiedMNListDiff::BASIC_BLS_VERSION : CSimplifiedMNListDiff::LEGACY_BLS_VERSION;
357358

358359
to.ForEachMN(false, [&](auto& toPtr) {
359360
auto fromPtr = GetMN(toPtr.proTxHash);
360361
if (fromPtr == nullptr) {
362+
CSimplifiedMNListEntry sme(toPtr);
363+
sme.nVersion = diffRet.nVersion;
361364
diffRet.mnList.emplace_back(toPtr);
362365
} else {
363366
CSimplifiedMNListEntry sme1(toPtr);
364367
CSimplifiedMNListEntry sme2(*fromPtr);
368+
sme1.nVersion = diffRet.nVersion;
369+
sme2.nVersion = diffRet.nVersion;
365370
if (sme1 != sme2) {
366371
diffRet.mnList.emplace_back(toPtr);
367372
} else if (extended && (sme1.scriptPayout != sme2.scriptPayout || sme1.scriptOperatorPayout != sme2.scriptOperatorPayout)) {
@@ -1136,7 +1141,7 @@ bool CheckProRegTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValid
11361141
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-protx-payload");
11371142
}
11381143

1139-
if (auto maybe_err = ptx.IsTriviallyValid(); maybe_err.did_err) {
1144+
if (auto maybe_err = ptx.IsTriviallyValid(llmq::utils::IsV19Active(pindexPrev)); maybe_err.did_err) {
11401145
return state.Invalid(maybe_err.reason, false, REJECT_INVALID, std::string(maybe_err.error_str));
11411146
}
11421147

@@ -1241,7 +1246,7 @@ bool CheckProUpServTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CVa
12411246
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-protx-payload");
12421247
}
12431248

1244-
if (auto maybe_err = ptx.IsTriviallyValid(); maybe_err.did_err) {
1249+
if (auto maybe_err = ptx.IsTriviallyValid(llmq::utils::IsV19Active(pindexPrev)); maybe_err.did_err) {
12451250
return state.Invalid(maybe_err.reason, false, REJECT_INVALID, std::string(maybe_err.error_str));
12461251
}
12471252

@@ -1296,7 +1301,7 @@ bool CheckProUpRegTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CVal
12961301
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-protx-payload");
12971302
}
12981303

1299-
if (auto maybe_err = ptx.IsTriviallyValid(); maybe_err.did_err) {
1304+
if (auto maybe_err = ptx.IsTriviallyValid(llmq::utils::IsV19Active(pindexPrev)); maybe_err.did_err) {
13001305
return state.Invalid(maybe_err.reason, false, REJECT_INVALID, std::string(maybe_err.error_str));
13011306
}
13021307

@@ -1369,7 +1374,7 @@ bool CheckProUpRevTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CVal
13691374
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-protx-payload");
13701375
}
13711376

1372-
if (auto maybe_err = ptx.IsTriviallyValid(); maybe_err.did_err) {
1377+
if (auto maybe_err = ptx.IsTriviallyValid(llmq::utils::IsV19Active(pindexPrev)); maybe_err.did_err) {
13731378
return state.Invalid(maybe_err.reason, false, REJECT_INVALID, std::string(maybe_err.error_str));
13741379
}
13751380

0 commit comments

Comments
 (0)