Skip to content

Commit 5809c5c

Browse files
codablockUdjinM6
authored andcommitted
Implement "quorum memberof" (#3004)
* Implement BuildQuorumInfo and call it from quorum_info * Add type to result of BuildQuorumInfo * Implement "quorum memberof"
1 parent 63424fb commit 5809c5c

File tree

1 file changed

+92
-29
lines changed

1 file changed

+92
-29
lines changed

src/rpc/rpcquorums.cpp

Lines changed: 92 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,41 @@ void quorum_info_help()
7676
);
7777
}
7878

79+
UniValue BuildQuorumInfo(const llmq::CQuorumCPtr& quorum, bool includeMembers, bool includeSkShare)
80+
{
81+
UniValue ret(UniValue::VOBJ);
82+
83+
ret.push_back(Pair("height", quorum->height));
84+
ret.push_back(Pair("type", quorum->params.name));
85+
ret.push_back(Pair("quorumHash", quorum->qc.quorumHash.ToString()));
86+
ret.push_back(Pair("minedBlock", quorum->minedBlockHash.ToString()));
87+
88+
if (includeMembers) {
89+
UniValue membersArr(UniValue::VARR);
90+
for (size_t i = 0; i < quorum->members.size(); i++) {
91+
auto& dmn = quorum->members[i];
92+
UniValue mo(UniValue::VOBJ);
93+
mo.push_back(Pair("proTxHash", dmn->proTxHash.ToString()));
94+
mo.push_back(Pair("valid", quorum->qc.validMembers[i]));
95+
if (quorum->qc.validMembers[i]) {
96+
CBLSPublicKey pubKey = quorum->GetPubKeyShare(i);
97+
if (pubKey.IsValid()) {
98+
mo.push_back(Pair("pubKeyShare", pubKey.ToString()));
99+
}
100+
}
101+
membersArr.push_back(mo);
102+
}
103+
104+
ret.push_back(Pair("members", membersArr));
105+
}
106+
ret.push_back(Pair("quorumPublicKey", quorum->qc.quorumPublicKey.ToString()));
107+
CBLSSecretKey skShare = quorum->GetSkShare();
108+
if (includeSkShare && skShare.IsValid()) {
109+
ret.push_back(Pair("secretKeyShare", skShare.ToString()));
110+
}
111+
return ret;
112+
}
113+
79114
UniValue quorum_info(const JSONRPCRequest& request)
80115
{
81116
if (request.fHelp || (request.params.size() != 3 && request.params.size() != 4))
@@ -101,35 +136,7 @@ UniValue quorum_info(const JSONRPCRequest& request)
101136
throw JSONRPCError(RPC_INVALID_PARAMETER, "quorum not found");
102137
}
103138

104-
UniValue ret(UniValue::VOBJ);
105-
106-
ret.push_back(Pair("height", quorum->height));
107-
ret.push_back(Pair("quorumHash", quorum->qc.quorumHash.ToString()));
108-
ret.push_back(Pair("minedBlock", quorum->minedBlockHash.ToString()));
109-
110-
UniValue membersArr(UniValue::VARR);
111-
for (size_t i = 0; i < quorum->members.size(); i++) {
112-
auto& dmn = quorum->members[i];
113-
UniValue mo(UniValue::VOBJ);
114-
mo.push_back(Pair("proTxHash", dmn->proTxHash.ToString()));
115-
mo.push_back(Pair("valid", quorum->qc.validMembers[i]));
116-
if (quorum->qc.validMembers[i]) {
117-
CBLSPublicKey pubKey = quorum->GetPubKeyShare(i);
118-
if (pubKey.IsValid()) {
119-
mo.push_back(Pair("pubKeyShare", pubKey.ToString()));
120-
}
121-
}
122-
membersArr.push_back(mo);
123-
}
124-
125-
ret.push_back(Pair("members", membersArr));
126-
ret.push_back(Pair("quorumPublicKey", quorum->qc.quorumPublicKey.ToString()));
127-
CBLSSecretKey skShare = quorum->GetSkShare();
128-
if (includeSkShare && skShare.IsValid()) {
129-
ret.push_back(Pair("secretKeyShare", skShare.ToString()));
130-
}
131-
132-
return ret;
139+
return BuildQuorumInfo(quorum, true, includeSkShare);
133140
}
134141

135142
void quorum_dkgstatus_help()
@@ -182,6 +189,59 @@ UniValue quorum_dkgstatus(const JSONRPCRequest& request)
182189
return ret;
183190
}
184191

192+
void quorum_memberof_help()
193+
{
194+
throw std::runtime_error(
195+
"quorum memberof \"proTxHash\"\n"
196+
"Checks which quorums the given masternode is a member of.\n"
197+
"\nArguments:\n"
198+
"1. \"proTxHash\" (string, required) ProTxHash of the masternode.\n"
199+
);
200+
}
201+
202+
UniValue quorum_memberof(const JSONRPCRequest& request)
203+
{
204+
if (request.fHelp || (request.params.size() != 2)) {
205+
quorum_memberof_help();
206+
}
207+
208+
uint256 protxHash = ParseHashV(request.params[1], "proTxHash");
209+
210+
const CBlockIndex* pindexTip;
211+
{
212+
LOCK(cs_main);
213+
pindexTip = chainActive.Tip();
214+
}
215+
216+
auto mnList = deterministicMNManager->GetListForBlock(pindexTip->GetBlockHash());
217+
auto dmn = mnList.GetMN(protxHash);
218+
if (!dmn) {
219+
throw JSONRPCError(RPC_INVALID_PARAMETER, "masternode not found");
220+
}
221+
222+
std::set<std::pair<Consensus::LLMQType, uint256>> quorumHashes;
223+
for (const auto& p : Params().GetConsensus().llmqs) {
224+
auto& params = p.second;
225+
auto quorums = llmq::quorumManager->ScanQuorums(params.type, params.signingActiveQuorumCount);
226+
for (auto& quorum : quorums) {
227+
for (auto& m : quorum->members) {
228+
if (m->proTxHash == dmn->proTxHash) {
229+
quorumHashes.emplace(params.type, quorum->qc.quorumHash);
230+
}
231+
}
232+
}
233+
}
234+
235+
UniValue result(UniValue::VARR);
236+
for (auto& p : quorumHashes) {
237+
auto quorum = llmq::quorumManager->GetQuorum(p.first, p.second);
238+
assert(quorum);
239+
result.push_back(BuildQuorumInfo(quorum, false, false));
240+
}
241+
242+
return result;
243+
}
244+
185245
void quorum_sign_help()
186246
{
187247
throw std::runtime_error(
@@ -318,6 +378,7 @@ UniValue quorum_dkgsimerror(const JSONRPCRequest& request)
318378
" info - Return information about a quorum\n"
319379
" dkgsimerror - Simulates DKG errors and malicious behavior.\n"
320380
" dkgstatus - Return the status of the current DKG process\n"
381+
" memberof - Checks which quorums the given masternode is a member of\n"
321382
" sign - Threshold-sign a message\n"
322383
" hasrecsig - Test if a valid recovered signature is present\n"
323384
" getrecsig - Get a recovered signature\n"
@@ -342,6 +403,8 @@ UniValue quorum(const JSONRPCRequest& request)
342403
return quorum_info(request);
343404
} else if (command == "dkgstatus") {
344405
return quorum_dkgstatus(request);
406+
} else if (command == "memberof") {
407+
return quorum_memberof(request);
345408
} else if (command == "sign" || command == "hasrecsig" || command == "getrecsig" || command == "isconflicting") {
346409
return quorum_sigs_cmd(request);
347410
} else if (command == "dkgsimerror") {

0 commit comments

Comments
 (0)