Skip to content

Commit

Permalink
feat: create new composite command "quorum platformsign"
Browse files Browse the repository at this point in the history
This composite command let to limit quorum type for signing for case of whitelist
After that old way to limit platform commands can be deprecated
  • Loading branch information
knst committed Jul 7, 2024
1 parent 12c5b4b commit b2665f8
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 25 deletions.
77 changes: 55 additions & 22 deletions src/rpc/quorums.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,42 +427,27 @@ static RPCHelpMan quorum_memberof()
};
}

static RPCHelpMan quorum_sign()
{
return RPCHelpMan{"quorum sign",
"Threshold-sign a message\n",
{
{"llmqType", RPCArg::Type::NUM, RPCArg::Optional::NO, "LLMQ type."},
{"id", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Request id."},
{"msgHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Message hash."},
{"quorumHash", RPCArg::Type::STR_HEX, /* default */ "", "The quorum identifier."},
{"submit", RPCArg::Type::BOOL, /* default */ "true", "Submits the signature share to the network if this is true. "
"Returns an object containing the signature share if this is false."},
},
RPCResults{},
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
static UniValue quorum_sign_helper(const JSONRPCRequest& request, Consensus::LLMQType llmqType)
{
const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);

const Consensus::LLMQType llmqType{static_cast<Consensus::LLMQType>(ParseInt32V(request.params[0], "llmqType"))};
const auto llmq_params_opt = Params().GetLLMQ(llmqType);
if (!llmq_params_opt.has_value()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type");
}

const uint256 id(ParseHashV(request.params[1], "id"));
const uint256 msgHash(ParseHashV(request.params[2], "msgHash"));
const uint256 id(ParseHashV(request.params[0], "id"));
const uint256 msgHash(ParseHashV(request.params[1], "msgHash"));

uint256 quorumHash;
if (!request.params[3].isNull() && !request.params[3].get_str().empty()) {
quorumHash = ParseHashV(request.params[3], "quorumHash");
if (!request.params[2].isNull() && !request.params[2].get_str().empty()) {
quorumHash = ParseHashV(request.params[2], "quorumHash");
}
bool fSubmit{true};
if (!request.params[4].isNull()) {
fSubmit = ParseBoolV(request.params[4], "submit");
if (!request.params[3].isNull()) {
fSubmit = ParseBoolV(request.params[3], "submit");
}
if (fSubmit) {
return llmq_ctx.sigman->AsyncSignIfMember(llmqType, *llmq_ctx.shareman, id, msgHash, quorumHash);
Expand Down Expand Up @@ -496,6 +481,53 @@ static RPCHelpMan quorum_sign()

return obj;
}
}

static RPCHelpMan quorum_sign()
{
return RPCHelpMan{"quorum sign",
"Threshold-sign a message\n",
{
{"llmqType", RPCArg::Type::NUM, RPCArg::Optional::NO, "LLMQ type."},
{"id", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Request id."},
{"msgHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Message hash."},
{"quorumHash", RPCArg::Type::STR_HEX, /* default */ "", "The quorum identifier."},
{"submit", RPCArg::Type::BOOL, /* default */ "true", "Submits the signature share to the network if this is true. "
"Returns an object containing the signature share if this is false."},
},
RPCResults{},
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
const Consensus::LLMQType llmqType{static_cast<Consensus::LLMQType>(ParseInt32V(request.params[0], "llmqType"))};

JSONRPCRequest new_request{request};
new_request.params.setArray();
for (unsigned int i = 1; i < request.params.size(); ++i) {
new_request.params.push_back(request.params[i]);
}
return quorum_sign_helper(new_request, llmqType);
},
};
}

static RPCHelpMan quorum_platformsign()
{
return RPCHelpMan{"quorum platformsign",
"Threshold-sign a message. It signs messages only for platform quorums\n",
{
{"id", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Request id."},
{"msgHash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Message hash."},
{"quorumHash", RPCArg::Type::STR_HEX, /* default */ "", "The quorum identifier."},
{"submit", RPCArg::Type::BOOL, /* default */ "true", "Submits the signature share to the network if this is true. "
"Returns an object containing the signature share if this is false."},
},
RPCResults{},
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
const Consensus::LLMQType llmqType{Params().GetConsensus().llmqTypePlatform};
return quorum_sign_helper(request, llmqType);
},
};
}
Expand Down Expand Up @@ -1096,6 +1128,7 @@ static const CRPCCommand commands[] =
{ "evo", "quorum", "dkgstatus", &quorum_dkgstatus, {"detail_level"} },
{ "evo", "quorum", "memberof", &quorum_memberof, {"proTxHash", "scanQuorumsCount"} },
{ "evo", "quorum", "sign", &quorum_sign, {"llmqType", "id", "msgHash", "quorumHash", "submit"} },
{ "evo", "quorum", "platformsign", &quorum_platformsign, {"id", "msgHash", "quorumHash", "submit"} },
{ "evo", "quorum", "verify", &quorum_verify, {"llmqType", "id", "msgHash", "signature", "quorumHash", "signHeight"} },
{ "evo", "quorum", "hasrecsig", &quorum_hasrecsig, {"llmqType", "id", "msgHash"} },
{ "evo", "quorum", "getrecsig", &quorum_getrecsig, {"llmqType", "id", "msgHash"} },
Expand Down
2 changes: 1 addition & 1 deletion test/functional/feature_asset_locks.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def create_assetunlock(self, index, withdrawal, pubkey=None, fee=tiny_amount):
unlock_tx.calc_sha256()
msgHash = format(unlock_tx.sha256, '064x')

recsig = self.get_recovered_sig(request_id, msgHash, llmq_type=llmq_type_test)
recsig = self.get_recovered_sig(request_id, msgHash, llmq_type=llmq_type_test, use_platformsign=True)

unlockTx_payload.quorumSig = bytearray.fromhex(recsig["sig"])
unlock_tx.vExtraPayload = unlockTx_payload.serialize()
Expand Down
7 changes: 5 additions & 2 deletions test/functional/test_framework/test_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -2033,13 +2033,16 @@ def check_recovered_sig():
return True
wait_until_helper(check_recovered_sig, timeout=timeout, sleep=1)

def get_recovered_sig(self, rec_sig_id, rec_sig_msg_hash, llmq_type=100):
def get_recovered_sig(self, rec_sig_id, rec_sig_msg_hash, llmq_type=100, use_platformsign=False):
# Note: recsigs aren't relayed to regular nodes by default,
# make sure to pick a mn as a node to query for recsigs.
try:
quorumHash = self.mninfo[0].node.quorum("selectquorum", llmq_type, rec_sig_id)["quorumHash"]
for mn in self.mninfo:
mn.node.quorum("sign", llmq_type, rec_sig_id, rec_sig_msg_hash, quorumHash)
if use_platformsign:
mn.node.quorum("platformsign", rec_sig_id, rec_sig_msg_hash, quorumHash)
else:
mn.node.quorum("sign", llmq_type, rec_sig_id, rec_sig_msg_hash, quorumHash)
self.wait_for_recovered_sig(rec_sig_id, rec_sig_msg_hash, llmq_type, 10)
return self.mninfo[0].node.quorum("getrecsig", llmq_type, rec_sig_id, rec_sig_msg_hash)
except JSONRPCException as e:
Expand Down

0 comments on commit b2665f8

Please sign in to comment.