refactor: quorum sign methods

They are separated to own commit because the code move is not trivial to review
This commit is contained in:
Konstantin Akimov 2024-06-11 20:26:08 +07:00
parent 2af9d86654
commit e3c4d66ef3
No known key found for this signature in database
GPG Key ID: 2176C4A5D01EA524

View File

@ -436,91 +436,10 @@ static RPCHelpMan quorum_sign()
}, },
RPCResults{}, RPCResults{},
RPCExamples{""}, RPCExamples{""},
}.Check(request); [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
}
static void quorum_verify_help(const JSONRPCRequest& request)
{ {
RPCHelpMan{"quorum verify", const NodeContext& node = EnsureAnyNodeContext(request.context);
"Test if a quorum signature is valid for a request id and a message hash\n", const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
{
{"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."},
{"signature", RPCArg::Type::STR, RPCArg::Optional::NO, "Quorum signature to verify."},
{"quorumHash", RPCArg::Type::STR_HEX, /* default */ "",
"The quorum identifier.\n"
"Set to \"\" if you want to specify signHeight instead."},
{"signHeight", RPCArg::Type::NUM, /* default */ "",
"The height at which the message was signed.\n"
"Only works when quorumHash is \"\"."},
},
RPCResults{},
RPCExamples{""},
}.Check(request);
}
static void quorum_hasrecsig_help(const JSONRPCRequest& request)
{
RPCHelpMan{"quorum hasrecsig",
"Test if a valid recovered signature is present\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."},
},
RPCResults{},
RPCExamples{""},
}.Check(request);
}
static void quorum_getrecsig_help(const JSONRPCRequest& request)
{
RPCHelpMan{"quorum getrecsig",
"Get a recovered signature\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."},
},
RPCResults{},
RPCExamples{""},
}.Check(request);
}
static void quorum_isconflicting_help(const JSONRPCRequest& request)
{
RPCHelpMan{"quorum isconflicting",
"Test if a conflict exists\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."},
},
RPCResults{},
RPCExamples{""},
}.Check(request);
}
static UniValue quorum_sigs_cmd(const JSONRPCRequest& request, const LLMQContext& llmq_ctx)
{
auto cmd = request.strMethod;
if (request.fHelp || (request.params.size() != 3)) {
if (cmd == "quorumsign") {
quorum_sign_help(request);
} else if (cmd == "quorumverify") {
quorum_verify_help(request);
} else if (cmd == "quorumhasrecsig") {
quorum_hasrecsig_help(request);
} else if (cmd == "quorumgetrecsig") {
quorum_getrecsig_help(request);
} else if (cmd == "quorumisconflicting") {
quorum_isconflicting_help(request);
} else {
// shouldn't happen as it's already handled by the caller
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid cmd");
}
}
Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType"); Consensus::LLMQType llmqType = (Consensus::LLMQType)ParseInt32V(request.params[0], "llmqType");
@ -532,7 +451,6 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request, const LLMQContext
uint256 id(ParseHashV(request.params[1], "id")); uint256 id(ParseHashV(request.params[1], "id"));
uint256 msgHash(ParseHashV(request.params[2], "msgHash")); uint256 msgHash(ParseHashV(request.params[2], "msgHash"));
if (cmd == "quorumsign") {
uint256 quorumHash; uint256 quorumHash;
if (!request.params[3].isNull() && !request.params[3].get_str().empty()) { if (!request.params[3].isNull() && !request.params[3].get_str().empty()) {
quorumHash = ParseHashV(request.params[3], "quorumHash"); quorumHash = ParseHashV(request.params[3], "quorumHash");
@ -573,7 +491,43 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request, const LLMQContext
return obj; return obj;
} }
} else if (cmd == "quorumverify") { },
};
}
static RPCHelpMan quorum_verify()
{
return RPCHelpMan{"quorum verify",
"Test if a quorum signature is valid for a request id and a message hash\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."},
{"signature", RPCArg::Type::STR, RPCArg::Optional::NO, "Quorum signature to verify."},
{"quorumHash", RPCArg::Type::STR_HEX, /* default */ "",
"The quorum identifier.\n"
"Set to \"\" if you want to specify signHeight instead."},
{"signHeight", RPCArg::Type::NUM, /* default */ "",
"The height at which the message was signed.\n"
"Only works when quorumHash is \"\"."},
},
RPCResults{},
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
const NodeContext& node = EnsureAnyNodeContext(request.context);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
Consensus::LLMQType llmqType = (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");
}
uint256 id(ParseHashV(request.params[1], "id"));
uint256 msgHash(ParseHashV(request.params[2], "msgHash"));
const bool use_bls_legacy = bls::bls_legacy_scheme.load(); const bool use_bls_legacy = bls::bls_legacy_scheme.load();
CBLSSignature sig; CBLSSignature sig;
if (!sig.SetHexStr(request.params[3].get_str(), use_bls_legacy)) { if (!sig.SetHexStr(request.params[3].get_str(), use_bls_legacy)) {
@ -589,7 +543,8 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request, const LLMQContext
int signOffset{llmq_params_opt->dkgInterval}; int signOffset{llmq_params_opt->dkgInterval};
return llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, msgHash, sig, 0) || return llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, msgHash, sig, 0) ||
llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, msgHash, sig, signOffset); llmq::VerifyRecoveredSig(llmqType, *llmq_ctx.qman, signHeight, id, msgHash, sig, signOffset);
} else { }
uint256 quorumHash(ParseHashV(request.params[4], "quorumHash")); uint256 quorumHash(ParseHashV(request.params[4], "quorumHash"));
llmq::CQuorumCPtr quorum = llmq_ctx.qman->GetQuorum(llmqType, quorumHash); llmq::CQuorumCPtr quorum = llmq_ctx.qman->GetQuorum(llmqType, quorumHash);
@ -599,10 +554,67 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request, const LLMQContext
uint256 signHash = llmq::BuildSignHash(llmqType, quorum->qc->quorumHash, id, msgHash); uint256 signHash = llmq::BuildSignHash(llmqType, quorum->qc->quorumHash, id, msgHash);
return sig.VerifyInsecure(quorum->qc->quorumPublicKey, signHash); return sig.VerifyInsecure(quorum->qc->quorumPublicKey, signHash);
},
};
} }
} else if (cmd == "quorumhasrecsig") {
static RPCHelpMan quorum_hasrecsig()
{
return RPCHelpMan{"quorum hasrecsig",
"Test if a valid recovered signature is present\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."},
},
RPCResults{},
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
const NodeContext& node = EnsureAnyNodeContext(request.context);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
Consensus::LLMQType llmqType = (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");
}
uint256 id(ParseHashV(request.params[1], "id"));
uint256 msgHash(ParseHashV(request.params[2], "msgHash"));
return llmq_ctx.sigman->HasRecoveredSig(llmqType, id, msgHash); return llmq_ctx.sigman->HasRecoveredSig(llmqType, id, msgHash);
} else if (cmd == "quorumgetrecsig") { },
};
}
static RPCHelpMan quorum_getrecsig()
{
return RPCHelpMan{"quorum getrecsig",
"Get a recovered signature\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."},
},
RPCResults{},
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
const NodeContext& node = EnsureAnyNodeContext(request.context);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
Consensus::LLMQType llmqType = (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");
}
uint256 id(ParseHashV(request.params[1], "id"));
uint256 msgHash(ParseHashV(request.params[2], "msgHash"));
llmq::CRecoveredSig recSig; llmq::CRecoveredSig recSig;
if (!llmq_ctx.sigman->GetRecoveredSigForId(llmqType, id, recSig)) { if (!llmq_ctx.sigman->GetRecoveredSigForId(llmqType, id, recSig)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "recovered signature not found"); throw JSONRPCError(RPC_INVALID_PARAMETER, "recovered signature not found");
@ -611,12 +623,39 @@ static UniValue quorum_sigs_cmd(const JSONRPCRequest& request, const LLMQContext
throw JSONRPCError(RPC_INVALID_PARAMETER, "recovered signature not found"); throw JSONRPCError(RPC_INVALID_PARAMETER, "recovered signature not found");
} }
return recSig.ToJson(); return recSig.ToJson();
} else if (cmd == "quorumisconflicting") { },
return llmq_ctx.sigman->IsConflicting(llmqType, id, msgHash); };
} else {
// shouldn't happen as it's already handled by the caller
throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid cmd");
} }
static RPCHelpMan quorum_isconflicting()
{
return RPCHelpMan{"quorum isconflicting",
"Test if a conflict exists\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."},
},
RPCResults{},
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
const NodeContext& node = EnsureAnyNodeContext(request.context);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
Consensus::LLMQType llmqType = (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");
}
uint256 id(ParseHashV(request.params[1], "id"));
uint256 msgHash(ParseHashV(request.params[2], "msgHash"));
return llmq_ctx.sigman->IsConflicting(llmqType, id, msgHash);
},
};
} }
static RPCHelpMan quorum_selectquorum() static RPCHelpMan quorum_selectquorum()