Skip to content

Commit 965a4a7

Browse files
codablockpanleone
authored andcommitted
Use lazy BLS signatures more often and don't always verify self-recovered sigs (dashpay#2860)
* Make CBLSLazySignature thread safe * Perform malleability check in CBLSLazySignature * Use CBLSLazySignature in CRecoveredSig and CInstantSendLock * Only sporadically verify self-recovered signatures * test
1 parent f4a5a04 commit 965a4a7

File tree

5 files changed

+31
-38
lines changed

5 files changed

+31
-38
lines changed

src/llmq/quorums_chainlocks.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ void CChainLocksHandler::HandleNewRecoveredSig(const llmq::CRecoveredSig& recove
345345

346346
clsig.nHeight = lastSignedHeight;
347347
clsig.blockHash = lastSignedMsgHash;
348-
clsig.sig = recoveredSig.sig;
348+
clsig.sig = recoveredSig.sig.Get();
349349
}
350350
ProcessNewChainLock(-1, clsig, ::SerializeHash(clsig));
351351
}

src/llmq/quorums_signing.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ bool CRecoveredSigsDb::ReadRecoveredSig(Consensus::LLMQType llmqType, const uint
100100
}
101101

102102
try {
103-
ret.Unserialize(ds, false);
103+
ret.Unserialize(ds);
104104
return true;
105105
} catch (std::exception&) {
106106
return false;
@@ -326,11 +326,6 @@ bool CSigningManager::PreVerifyRecoveredSig(NodeId nodeId, const CRecoveredSig&
326326
return false;
327327
}
328328

329-
if (!recoveredSig.sig.IsValid()) {
330-
retBan = true;
331-
return false;
332-
}
333-
334329
return true;
335330
}
336331

@@ -417,8 +412,14 @@ bool CSigningManager::ProcessPendingRecoveredSigs(CConnman& connman)
417412
auto& v = p.second;
418413

419414
for (auto& recSig : v) {
415+
// we didn't verify the lazy signature until now
416+
if (!recSig.sig.Get().IsValid()) {
417+
batchVerifier.badSources.emplace(nodeId);
418+
break;
419+
}
420+
420421
const auto& quorum = quorums.at(std::make_pair((Consensus::LLMQType)recSig.llmqType, recSig.quorumHash));
421-
batchVerifier.PushMessage(nodeId, recSig.GetHash(), llmq::utils::BuildSignHash(recSig), recSig.sig, quorum->quorumPublicKey);
422+
batchVerifier.PushMessage(nodeId, recSig.GetHash(), llmq::utils::BuildSignHash(recSig), recSig.sig.Get(), quorum->quorumPublicKey);
422423
verifyCount++;
423424
}
424425
}

src/llmq/quorums_signing.h

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,34 +26,20 @@ class CRecoveredSig
2626
uint256 quorumHash;
2727
uint256 id;
2828
uint256 msgHash;
29-
CBLSSignature sig;
29+
CBLSLazySignature sig;
3030

3131
// only in-memory
3232
uint256 hash;
3333

3434
public:
35-
template <typename Stream>
36-
inline void Serialize(Stream& s) const
35+
SERIALIZE_METHODS(CRecoveredSig, obj)
3736
{
38-
s << llmqType;
39-
s << quorumHash;
40-
s << id;
41-
s << msgHash;
42-
s << sig;
43-
}
44-
template <typename Stream>
45-
inline void Unserialize(Stream& s, bool checkMalleable = true, bool updateHash = true, bool skipSig = false)
46-
{
47-
s >> llmqType;
48-
s >> quorumHash;
49-
s >> id;
50-
s >> msgHash;
51-
if (!skipSig) {
52-
sig.Unserialize(s, checkMalleable);
53-
if (updateHash) {
54-
UpdateHash();
55-
}
56-
}
37+
READWRITE(obj.llmqType);
38+
READWRITE(obj.quorumHash);
39+
READWRITE(obj.id);
40+
READWRITE(obj.msgHash);
41+
READWRITE(obj.sig);
42+
SER_READ(obj, obj.UpdateHash());
5743
}
5844

5945
void UpdateHash()

src/llmq/quorums_signing_shares.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -753,16 +753,21 @@ void CSigSharesManager::TryRecoverSig(const CQuorumCPtr& quorum, const uint256&
753753
rs.quorumHash = quorum->pindexQuorum->GetBlockHash();
754754
rs.id = id;
755755
rs.msgHash = msgHash;
756-
rs.sig = recoveredSig;
756+
rs.sig.Set(recoveredSig);
757757
rs.UpdateHash();
758758

759-
auto signHash = llmq::utils::BuildSignHash(rs);
760-
bool valid = rs.sig.VerifyInsecure(quorum->quorumPublicKey, signHash);
761-
if (!valid) {
762-
// this should really not happen as we have verified all signature shares before
763-
LogPrintf("CSigSharesManager::%s -- own recovered signature is invalid. id=%s, msgHash=%s\n", __func__,
764-
id.ToString(), msgHash.ToString());
765-
return;
759+
// There should actually be no need to verify the self-recovered signatures as it should always succeed. Let's
760+
// however still verify it from time to time, so that we have a chance to catch bugs. We do only this sporadic
761+
// verification because this is unbatched and thus slow verification that happens here.
762+
if (((recoveredSigsCounter++) % 100) == 0) {
763+
auto signHash = llmq::utils::BuildSignHash(rs);
764+
bool valid = recoveredSig.VerifyInsecure(quorum->quorumPublicKey, signHash);
765+
if (!valid) {
766+
// this should really not happen as we have verified all signature shares before
767+
LogPrintf("CSigSharesManager::%s -- own recovered signature is invalid. id=%s, msgHash=%s\n", __func__,
768+
id.ToString(), msgHash.ToString());
769+
return;
770+
}
766771
}
767772

768773
quorumSigningManager->ProcessRecoveredSig(-1, rs, quorum, connman);

src/llmq/quorums_signing_shares.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ class CSigSharesManager : public CRecoveredSigsListener
353353
FastRandomContext rnd;
354354

355355
int64_t lastCleanupTime{0};
356+
std::atomic<uint32_t> recoveredSigsCounter{0};
356357

357358
public:
358359
CSigSharesManager();

0 commit comments

Comments
 (0)