-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Put height into mined commitments and use it instead of the special handling of quorumVvecHash #2501
Put height into mined commitments and use it instead of the special handling of quorumVvecHash #2501
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -6,6 +6,9 @@ | |||||
#include "quorums_utils.h" | ||||||
|
||||||
#include "chainparams.h" | ||||||
#include "validation.h" | ||||||
|
||||||
#include "evo/specialtx.h" | ||||||
|
||||||
#include <univalue.h> | ||||||
|
||||||
|
@@ -24,7 +27,7 @@ CFinalCommitment::CFinalCommitment(const Consensus::LLMQParams& params, const ui | |||||
LogPrintStr(strprintf("CFinalCommitment::%s -- %s", __func__, tinyformat::format(__VA_ARGS__))); \ | ||||||
} while(0) | ||||||
|
||||||
bool CFinalCommitment::Verify(const std::vector<CDeterministicMNCPtr>& members) const | ||||||
bool CFinalCommitment::Verify(const std::vector<CDeterministicMNCPtr>& members, bool checkSigs) const | ||||||
{ | ||||||
if (nVersion == 0 || nVersion > CURRENT_VERSION) { | ||||||
return false; | ||||||
|
@@ -76,30 +79,33 @@ bool CFinalCommitment::Verify(const std::vector<CDeterministicMNCPtr>& members) | |||||
} | ||||||
} | ||||||
|
||||||
uint256 commitmentHash = CLLMQUtils::BuildCommitmentHash((uint8_t)params.type, quorumHash, validMembers, quorumPublicKey, quorumVvecHash); | ||||||
// sigs are only checked when the block is processed | ||||||
UdjinM6 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
if (checkSigs) { | ||||||
uint256 commitmentHash = CLLMQUtils::BuildCommitmentHash((uint8_t)params.type, quorumHash, validMembers, quorumPublicKey, quorumVvecHash); | ||||||
|
||||||
std::vector<CBLSPublicKey> memberPubKeys; | ||||||
for (size_t i = 0; i < members.size(); i++) { | ||||||
if (!signers[i]) { | ||||||
continue; | ||||||
std::vector<CBLSPublicKey> memberPubKeys; | ||||||
for (size_t i = 0; i < members.size(); i++) { | ||||||
if (!signers[i]) { | ||||||
continue; | ||||||
} | ||||||
memberPubKeys.emplace_back(members[i]->pdmnState->pubKeyOperator); | ||||||
} | ||||||
memberPubKeys.emplace_back(members[i]->pdmnState->pubKeyOperator); | ||||||
} | ||||||
|
||||||
if (!membersSig.VerifySecureAggregated(memberPubKeys, commitmentHash)) { | ||||||
LogPrintfFinalCommitment("invalid aggregated members signature\n"); | ||||||
return false; | ||||||
} | ||||||
if (!membersSig.VerifySecureAggregated(memberPubKeys, commitmentHash)) { | ||||||
LogPrintfFinalCommitment("invalid aggregated members signature\n"); | ||||||
return false; | ||||||
} | ||||||
|
||||||
if (!quorumSig.VerifyInsecure(quorumPublicKey, commitmentHash)) { | ||||||
LogPrintfFinalCommitment("invalid quorum signature\n"); | ||||||
return false; | ||||||
if (!quorumSig.VerifyInsecure(quorumPublicKey, commitmentHash)) { | ||||||
LogPrintfFinalCommitment("invalid quorum signature\n"); | ||||||
return false; | ||||||
} | ||||||
} | ||||||
|
||||||
return true; | ||||||
} | ||||||
|
||||||
bool CFinalCommitment::VerifyNull(int nHeight) const | ||||||
bool CFinalCommitment::VerifyNull() const | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not relevant for this PR but I'd like a comment on this method normally, overall comments are fairly limited in this new code There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll create a PR in the next days to include more documentation in general, hope that helps understanding all the new code. |
||||||
{ | ||||||
if (!Params().GetConsensus().llmqs.count((Consensus::LLMQType)llmqType)) { | ||||||
LogPrintfFinalCommitment("invalid llmqType=%d\n", llmqType); | ||||||
|
@@ -111,11 +117,6 @@ bool CFinalCommitment::VerifyNull(int nHeight) const | |||||
return false; | ||||||
} | ||||||
|
||||||
uint256 expectedQuorumVvecHash = ::SerializeHash(std::make_pair(quorumHash, nHeight)); | ||||||
if (quorumVvecHash != expectedQuorumVvecHash) { | ||||||
return false; | ||||||
} | ||||||
|
||||||
return true; | ||||||
} | ||||||
|
||||||
|
@@ -143,4 +144,51 @@ void CFinalCommitment::ToJson(UniValue& obj) const | |||||
obj.push_back(Pair("quorumPublicKey", quorumPublicKey.ToString())); | ||||||
} | ||||||
|
||||||
bool CheckLLMQCommitment(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state) | ||||||
{ | ||||||
CFinalCommitmentTxPayload qcTx; | ||||||
if (!GetTxPayload(tx, qcTx)) { | ||||||
return state.DoS(100, false, REJECT_INVALID, "bad-qc-payload"); | ||||||
} | ||||||
|
||||||
if (qcTx.nVersion == 0 || qcTx.nVersion > CFinalCommitmentTxPayload::CURRENT_VERSION) { | ||||||
return state.DoS(100, false, REJECT_INVALID, "bad-qc-version"); | ||||||
} | ||||||
|
||||||
if (qcTx.nHeight != pindexPrev->nHeight + 1) { | ||||||
return state.DoS(100, false, REJECT_INVALID, "bad-qc-height"); | ||||||
} | ||||||
|
||||||
if (!mapBlockIndex.count(qcTx.commitment.quorumHash)) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I prefer it to be explicit, I think it is easier to read and it conveys the intent better
Suggested change
|
||||||
return state.DoS(100, false, REJECT_INVALID, "bad-qc-quorum-hash"); | ||||||
} | ||||||
|
||||||
const CBlockIndex* pindexQuorum = mapBlockIndex[qcTx.commitment.quorumHash]; | ||||||
|
||||||
if (pindexQuorum != pindexPrev->GetAncestor(pindexQuorum->nHeight)) { | ||||||
// not part of active chain | ||||||
return state.DoS(100, false, REJECT_INVALID, "bad-qc-quorum-hash"); | ||||||
} | ||||||
|
||||||
if (!Params().GetConsensus().llmqs.count((Consensus::LLMQType)qcTx.commitment.llmqType)) { | ||||||
LogPrintfFinalCommitment("invalid llmqType=%d\n", qcTx.commitment.llmqType); | ||||||
return false; | ||||||
UdjinM6 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
} | ||||||
const auto& params = Params().GetConsensus().llmqs.at((Consensus::LLMQType)qcTx.commitment.llmqType); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. might make sense to have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, the first one is checking for existence (which is an important validity check). The second one actually fetches it (by using |
||||||
|
||||||
if (qcTx.commitment.IsNull()) { | ||||||
if (!qcTx.commitment.VerifyNull()) { | ||||||
return state.DoS(100, false, REJECT_INVALID, "bad-qc-invalid-null"); | ||||||
} | ||||||
return true; | ||||||
} | ||||||
|
||||||
auto members = CLLMQUtils::GetAllQuorumMembers(params.type, qcTx.commitment.quorumHash); | ||||||
if (!qcTx.commitment.Verify(members, false)) { | ||||||
return false; | ||||||
UdjinM6 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
} | ||||||
|
||||||
return true; | ||||||
} | ||||||
|
||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,8 +48,8 @@ class CFinalCommitment | |
return (int)std::count(validMembers.begin(), validMembers.end(), true); | ||
} | ||
|
||
bool Verify(const std::vector<CDeterministicMNCPtr>& members) const; | ||
bool VerifyNull(int nHeight) const; | ||
bool Verify(const std::vector<CDeterministicMNCPtr>& members, bool checkSigs) const; | ||
bool VerifyNull() const; | ||
bool VerifySizes(const Consensus::LLMQParams& params) const; | ||
|
||
void ToJson(UniValue& obj) const; | ||
|
@@ -79,6 +79,7 @@ class CFinalCommitment | |
return false; | ||
} | ||
if (quorumPublicKey.IsValid() || | ||
!quorumVvecHash.IsNull() || | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this seems bad... I don't really know enough about it though, so I'll just point it out and wait for you to say it's correct :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's correct, but you made me question it for a second ;) |
||
membersSig.IsValid() || | ||
quorumSig.IsValid()) { | ||
return false; | ||
|
@@ -87,6 +88,30 @@ class CFinalCommitment | |
} | ||
}; | ||
|
||
class CFinalCommitmentTxPayload | ||
{ | ||
public: | ||
static const uint16_t CURRENT_VERSION = 1; | ||
|
||
public: | ||
uint16_t nVersion{CURRENT_VERSION}; | ||
uint32_t nHeight{(uint32_t)-1}; | ||
CFinalCommitment commitment; | ||
|
||
public: | ||
ADD_SERIALIZE_METHODS | ||
|
||
template<typename Stream, typename Operation> | ||
inline void SerializationOp(Stream& s, Operation ser_action) | ||
{ | ||
READWRITE(nVersion); | ||
READWRITE(nHeight); | ||
READWRITE(commitment); | ||
} | ||
}; | ||
|
||
bool CheckLLMQCommitment(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state); | ||
|
||
} | ||
|
||
#endif //DASH_QUORUMS_COMMITMENT_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this lock only need to happen for the
Misbehaving
? If that is the case, there isn't really a reason to have it above the print. (not really relevant tho ¯\(ツ)/¯)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, you're right. It's only for
Misbehaving
. I'd like to avoid fixing that for now as I don't want to loose the ACK for this PR if it's not really required...need to finish RC5.