Skip to content

Commit 6c63a77

Browse files
codablockpanleone
authored andcommitted
Use CBLSLazySignature in CBatchedSigShares
This removes the burden on the message handler thread when many sig batches arrive. The expensive part of deserialization is now performed in the sig shares worker thread. This also removes the need for the specialized deserialization of the sig shares which tried to avoid the malleability check, as CBLSLazySignature does not perform malleability checks at all.
1 parent bff6e6e commit 6c63a77

File tree

2 files changed

+20
-50
lines changed

2 files changed

+20
-50
lines changed

src/llmq/quorums_signing_shares.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -374,11 +374,6 @@ bool CSigSharesManager::PreVerifyBatchedSigShares(NodeId nodeId, const CBatchedS
374374

375375
for (size_t i = 0; i < batchedSigShares.sigShares.size(); i++) {
376376
auto quorumMember = batchedSigShares.sigShares[i].first;
377-
auto& sigShare = batchedSigShares.sigShares[i].second;
378-
if (!sigShare.IsValid()) {
379-
retBan = true;
380-
return false;
381-
}
382377
if (!dupMembers.emplace(quorumMember).second) {
383378
retBan = true;
384379
return false;
@@ -482,6 +477,14 @@ void CSigSharesManager::ProcessPendingSigShares(CConnman& connman)
482477
continue;
483478
}
484479

480+
// we didn't check this earlier because we use a lazy BLS signature and tried to avoid doing the expensive
481+
// deserialization in the message thread
482+
if (!sigShare.sigShare.Get().IsValid()) {
483+
BanNode(nodeId);
484+
// don't process any additional shares from this node
485+
break;
486+
}
487+
485488
auto quorum = quorums.at(std::make_pair((Consensus::LLMQType)sigShare.llmqType, sigShare.quorumHash));
486489
auto pubKeyShare = quorum->GetPubKeyShare(sigShare.quorumMember);
487490

@@ -492,7 +495,7 @@ void CSigSharesManager::ProcessPendingSigShares(CConnman& connman)
492495
assert(false);
493496
}
494497

495-
batchVerifier.PushMessage(nodeId, sigShare.GetKey(), sigShare.GetSignHash(), sigShare.sigShare, pubKeyShare);
498+
batchVerifier.PushMessage(nodeId, sigShare.GetKey(), sigShare.GetSignHash(), sigShare.sigShare.Get(), pubKeyShare);
496499
verifyCount++;
497500
}
498501
}
@@ -616,7 +619,7 @@ void CSigSharesManager::TryRecoverSig(const CQuorumCPtr& quorum, const uint256&
616619
idsForRecovery.reserve((size_t)quorum->params.threshold);
617620
for (auto it = itPair.first; it != itPair.second && sigSharesForRecovery.size() < quorum->params.threshold; ++it) {
618621
auto& sigShare = it->second;
619-
sigSharesForRecovery.emplace_back(sigShare.sigShare);
622+
sigSharesForRecovery.emplace_back(sigShare.sigShare.Get());
620623
idsForRecovery.emplace_back(CBLSId(quorum->members[sigShare.quorumMember]->proTxHash));
621624
}
622625

@@ -1160,8 +1163,8 @@ void CSigSharesManager::Sign(const CQuorumCPtr& quorum, const uint256& id, const
11601163
sigShare.quorumMember = (uint16_t)memberIdx;
11611164
uint256 signHash = llmq::utils::BuildSignHash(sigShare);
11621165

1163-
sigShare.sigShare = skShare.Sign(signHash);
1164-
if (!sigShare.sigShare.IsValid()) {
1166+
sigShare.sigShare.Set(skShare.Sign(signHash));
1167+
if (!sigShare.sigShare.Get().IsValid()) {
11651168
LogPrintf("CSigSharesManager::%s -- failed to sign sigShare. id=%s, msgHash=%s, time=%s\n", __func__,
11661169
sigShare.id.ToString(), sigShare.msgHash.ToString(), t.count());
11671170
return;

src/llmq/quorums_signing_shares.h

Lines changed: 8 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class CSigShare
3838
uint16_t quorumMember;
3939
uint256 id;
4040
uint256 msgHash;
41-
CBLSSignature sigShare;
41+
CBLSLazySignature sigShare;
4242

4343
SigShareKey key;
4444

@@ -94,50 +94,17 @@ class CBatchedSigShares
9494
uint256 quorumHash;
9595
uint256 id;
9696
uint256 msgHash;
97-
std::vector<std::pair<uint16_t, CBLSSignature>> sigShares;
97+
std::vector<std::pair<uint16_t, CBLSLazySignature>> sigShares;
9898

9999
public:
100-
template <typename Stream, typename Operation>
101-
inline void SerializationOpBase(Stream& s, Operation ser_action)
100+
SERIALIZE_METHODS(CBatchedSigShares, obj)
102101
{
103-
READWRITE(llmqType);
104-
READWRITE(quorumHash);
105-
READWRITE(id);
106-
READWRITE(msgHash);
107-
::Serialize(s, llmqType);
108-
}
109-
110-
template <typename Stream>
111-
inline void Serialize(Stream& s) const
112-
{
113-
s << llmqType;
114-
s << quorumHash;
115-
s << id;
116-
s << msgHash;
117-
// this->SerializationOpBase(s, CSerActionSerialize());
118-
s << sigShares;
102+
READWRITE(obj.llmqType);
103+
READWRITE(obj.quorumHash);
104+
READWRITE(obj.id);
105+
READWRITE(obj.msgHash);
106+
READWRITE(obj.sigShares);
119107
}
120-
template <typename Stream>
121-
inline void Unserialize(Stream& s)
122-
{
123-
// this->SerializationOpBase(s, CSerActionUnserialize());
124-
s >> llmqType;
125-
s >> quorumHash;
126-
s >> id;
127-
s >> msgHash;
128-
// we do custom deserialization here with the malleability check skipped for signatures
129-
// we can do this here because we never use the hash of a sig share for identification and are only interested
130-
// in validity
131-
uint64_t nSize = ReadCompactSize(s);
132-
if (nSize > 400) { // we don't support larger quorums, so this is the limit
133-
throw std::ios_base::failure(strprintf("too many elements (%d) in CBatchedSigShares", nSize));
134-
}
135-
sigShares.resize(nSize);
136-
for (size_t i = 0; i < nSize; i++) {
137-
s >> sigShares[i].first;
138-
sigShares[i].second.Unserialize(s, false);
139-
}
140-
};
141108

142109
CSigShare RebuildSigShare(size_t idx) const
143110
{

0 commit comments

Comments
 (0)