diff --git a/src/llmq/quorums_signing_shares.cpp b/src/llmq/quorums_signing_shares.cpp index 41b21bb3d3cd3..f962547720141 100644 --- a/src/llmq/quorums_signing_shares.cpp +++ b/src/llmq/quorums_signing_shares.cpp @@ -373,11 +373,6 @@ bool CSigSharesManager::PreVerifyBatchedSigShares(NodeId nodeId, const CBatchedS for (size_t i = 0; i < batchedSigShares.sigShares.size(); i++) { auto quorumMember = batchedSigShares.sigShares[i].first; - auto& sigShare = batchedSigShares.sigShares[i].second; - if (!sigShare.IsValid()) { - retBan = true; - return false; - } if (!dupMembers.emplace(quorumMember).second) { retBan = true; return false; @@ -483,6 +478,14 @@ void CSigSharesManager::ProcessPendingSigShares(CConnman& connman) continue; } + // we didn't check this earlier because we use a lazy BLS signature and tried to avoid doing the expensive + // deserialization in the message thread + if (!sigShare.sigShare.GetSig().IsValid()) { + BanNode(nodeId); + // don't process any additional shares from this node + break; + } + auto quorum = quorums.at(std::make_pair((Consensus::LLMQType)sigShare.llmqType, sigShare.quorumHash)); auto pubKeyShare = quorum->GetPubKeyShare(sigShare.quorumMember); @@ -493,7 +496,7 @@ void CSigSharesManager::ProcessPendingSigShares(CConnman& connman) assert(false); } - batchVerifier.PushMessage(nodeId, sigShare.GetKey(), sigShare.GetSignHash(), sigShare.sigShare, pubKeyShare); + batchVerifier.PushMessage(nodeId, sigShare.GetKey(), sigShare.GetSignHash(), sigShare.sigShare.GetSig(), pubKeyShare); verifyCount++; } } @@ -617,7 +620,7 @@ void CSigSharesManager::TryRecoverSig(const CQuorumCPtr& quorum, const uint256& idsForRecovery.reserve((size_t) quorum->params.threshold); for (auto it = itPair.first; it != itPair.second && sigSharesForRecovery.size() < quorum->params.threshold; ++it) { auto& sigShare = it->second; - sigSharesForRecovery.emplace_back(sigShare.sigShare); + sigSharesForRecovery.emplace_back(sigShare.sigShare.GetSig()); idsForRecovery.emplace_back(CBLSId::FromHash(quorum->members[sigShare.quorumMember]->proTxHash)); } @@ -1168,8 +1171,8 @@ void CSigSharesManager::Sign(const CQuorumCPtr& quorum, const uint256& id, const sigShare.quorumMember = (uint16_t)memberIdx; uint256 signHash = CLLMQUtils::BuildSignHash(sigShare); - sigShare.sigShare = skShare.Sign(signHash); - if (!sigShare.sigShare.IsValid()) { + sigShare.sigShare.SetSig(skShare.Sign(signHash)); + if (!sigShare.sigShare.GetSig().IsValid()) { LogPrintf("CSigSharesManager::%s -- failed to sign sigShare. id=%s, msgHash=%s, time=%s\n", __func__, sigShare.id.ToString(), sigShare.msgHash.ToString(), t.count()); return; diff --git a/src/llmq/quorums_signing_shares.h b/src/llmq/quorums_signing_shares.h index d59756de9d28e..6ae42f6785ed6 100644 --- a/src/llmq/quorums_signing_shares.h +++ b/src/llmq/quorums_signing_shares.h @@ -37,7 +37,7 @@ class CSigShare uint16_t quorumMember; uint256 id; uint256 msgHash; - CBLSSignature sigShare; + CBLSLazySignature sigShare; SigShareKey key; @@ -97,43 +97,21 @@ class CBatchedSigShares uint256 quorumHash; uint256 id; uint256 msgHash; - std::vector> sigShares; + std::vector> sigShares; public: + ADD_SERIALIZE_METHODS; + template - inline void SerializationOpBase(Stream& s, Operation ser_action) + inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(llmqType); READWRITE(quorumHash); READWRITE(id); READWRITE(msgHash); + READWRITE(sigShares); } - template - inline void Serialize(Stream& s) const - { - NCONST_PTR(this)->SerializationOpBase(s, CSerActionSerialize()); - s << sigShares; - } - template - inline void Unserialize(Stream& s) - { - NCONST_PTR(this)->SerializationOpBase(s, CSerActionUnserialize()); - - // we do custom deserialization here with the malleability check skipped for signatures - // we can do this here because we never use the hash of a sig share for identification and are only interested - // in validity - uint64_t nSize = ReadCompactSize(s); - if (nSize > 400) { // we don't support larger quorums, so this is the limit - throw std::ios_base::failure(strprintf("too many elements (%d) in CBatchedSigShares", nSize)); - } - sigShares.resize(nSize); - for (size_t i = 0; i < nSize; i++) { - s >> sigShares[i].first; - sigShares[i].second.Unserialize(s, false); - } - }; - CSigShare RebuildSigShare(size_t idx) const { assert(idx < sigShares.size());