mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 20:12:57 +01:00
Merge #6106: feat: create new composite quorum-command platformsign
2db69d7b81
chore: add release notes for "quorum platformsign" (Konstantin Akimov)283c5f89a2
feat: create new composite command "quorum platformsign" (Konstantin Akimov) Pull request description: ## Issue being fixed or feature implemented It splits from #6100 With just whitelist it is impossible to limit the RPC `quorum sign` to use only one specific quorum type, this PR aim to provide ability for quorum signing for platform quorum only. ## What was done? Implemented a new composite command "quorum platformsign" 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 - #6105 ## How Has This Been Tested? Updated a functional tests to use platform signing for Asset Unlocks feature. ## Breaking Changes N/A ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone ACKs for top commit: UdjinM6: utACK2db69d7b81
PastaPastaPasta: utACK2db69d7b81
Tree-SHA512: b0dff9934137c4faa85664058e1e77f85067cc8d931e6d76ee5b9e610164ac8b0609736d5f09475256cb78d65bf92466624d784f0b13d20136df7e75613662cb
This commit is contained in:
parent
a45e6df58b
commit
db828177bf
6
doc/release-notes-6106.md
Normal file
6
doc/release-notes-6106.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
## Remote Procedure Call (RPC) Changes
|
||||||
|
|
||||||
|
### The new RPCs are:
|
||||||
|
|
||||||
|
- `quorum signplatform` This RPC is added for Platform needs. This composite command let to limit quorum type for signing by platform. It is equivalent of `quorum sign <platform type>`.
|
||||||
|
|
@ -427,42 +427,27 @@ static RPCHelpMan quorum_memberof()
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static RPCHelpMan quorum_sign()
|
static UniValue quorum_sign_helper(const JSONRPCRequest& request, Consensus::LLMQType llmqType)
|
||||||
{
|
|
||||||
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 NodeContext& node = EnsureAnyNodeContext(request.context);
|
const NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
const ChainstateManager& chainman = EnsureChainman(node);
|
const ChainstateManager& chainman = EnsureChainman(node);
|
||||||
const LLMQContext& llmq_ctx = EnsureLLMQContext(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);
|
const auto llmq_params_opt = Params().GetLLMQ(llmqType);
|
||||||
if (!llmq_params_opt.has_value()) {
|
if (!llmq_params_opt.has_value()) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid LLMQ type");
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint256 id(ParseHashV(request.params[1], "id"));
|
const uint256 id(ParseHashV(request.params[0], "id"));
|
||||||
const uint256 msgHash(ParseHashV(request.params[2], "msgHash"));
|
const uint256 msgHash(ParseHashV(request.params[1], "msgHash"));
|
||||||
|
|
||||||
uint256 quorumHash;
|
uint256 quorumHash;
|
||||||
if (!request.params[3].isNull() && !request.params[3].get_str().empty()) {
|
if (!request.params[2].isNull() && !request.params[2].get_str().empty()) {
|
||||||
quorumHash = ParseHashV(request.params[3], "quorumHash");
|
quorumHash = ParseHashV(request.params[2], "quorumHash");
|
||||||
}
|
}
|
||||||
bool fSubmit{true};
|
bool fSubmit{true};
|
||||||
if (!request.params[4].isNull()) {
|
if (!request.params[3].isNull()) {
|
||||||
fSubmit = ParseBoolV(request.params[4], "submit");
|
fSubmit = ParseBoolV(request.params[3], "submit");
|
||||||
}
|
}
|
||||||
if (fSubmit) {
|
if (fSubmit) {
|
||||||
return llmq_ctx.sigman->AsyncSignIfMember(llmqType, *llmq_ctx.shareman, id, msgHash, quorumHash);
|
return llmq_ctx.sigman->AsyncSignIfMember(llmqType, *llmq_ctx.shareman, id, msgHash, quorumHash);
|
||||||
@ -496,6 +481,53 @@ static RPCHelpMan quorum_sign()
|
|||||||
|
|
||||||
return obj;
|
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);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1110,6 +1142,7 @@ static const CRPCCommand commands[] =
|
|||||||
{ "evo", "quorum", "dkgstatus", &quorum_dkgstatus, {"detail_level"} },
|
{ "evo", "quorum", "dkgstatus", &quorum_dkgstatus, {"detail_level"} },
|
||||||
{ "evo", "quorum", "memberof", &quorum_memberof, {"proTxHash", "scanQuorumsCount"} },
|
{ "evo", "quorum", "memberof", &quorum_memberof, {"proTxHash", "scanQuorumsCount"} },
|
||||||
{ "evo", "quorum", "sign", &quorum_sign, {"llmqType", "id", "msgHash", "quorumHash", "submit"} },
|
{ "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", "verify", &quorum_verify, {"llmqType", "id", "msgHash", "signature", "quorumHash", "signHeight"} },
|
||||||
{ "evo", "quorum", "hasrecsig", &quorum_hasrecsig, {"llmqType", "id", "msgHash"} },
|
{ "evo", "quorum", "hasrecsig", &quorum_hasrecsig, {"llmqType", "id", "msgHash"} },
|
||||||
{ "evo", "quorum", "getrecsig", &quorum_getrecsig, {"llmqType", "id", "msgHash"} },
|
{ "evo", "quorum", "getrecsig", &quorum_getrecsig, {"llmqType", "id", "msgHash"} },
|
||||||
|
@ -119,7 +119,7 @@ class AssetLocksTest(DashTestFramework):
|
|||||||
unlock_tx.calc_sha256()
|
unlock_tx.calc_sha256()
|
||||||
msgHash = format(unlock_tx.sha256, '064x')
|
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"])
|
unlockTx_payload.quorumSig = bytearray.fromhex(recsig["sig"])
|
||||||
unlock_tx.vExtraPayload = unlockTx_payload.serialize()
|
unlock_tx.vExtraPayload = unlockTx_payload.serialize()
|
||||||
|
@ -2033,12 +2033,15 @@ class DashTestFramework(BitcoinTestFramework):
|
|||||||
return True
|
return True
|
||||||
wait_until_helper(check_recovered_sig, timeout=timeout, sleep=1)
|
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,
|
# Note: recsigs aren't relayed to regular nodes by default,
|
||||||
# make sure to pick a mn as a node to query for recsigs.
|
# make sure to pick a mn as a node to query for recsigs.
|
||||||
try:
|
try:
|
||||||
quorumHash = self.mninfo[0].node.quorum("selectquorum", llmq_type, rec_sig_id)["quorumHash"]
|
quorumHash = self.mninfo[0].node.quorum("selectquorum", llmq_type, rec_sig_id)["quorumHash"]
|
||||||
for mn in self.mninfo:
|
for mn in self.mninfo:
|
||||||
|
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)
|
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)
|
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)
|
return self.mninfo[0].node.quorum("getrecsig", llmq_type, rec_sig_id, rec_sig_msg_hash)
|
||||||
|
Loading…
Reference in New Issue
Block a user