Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/avalanche.cpp
Show First 20 Lines • Show All 455 Lines • ▼ Show 20 Lines | avalanche::ProofValidationState state; | ||||
if (!proof.verify(state, | if (!proof.verify(state, | ||||
node.chainman->ActiveChainstate().CoinsTip())) { | node.chainman->ActiveChainstate().CoinsTip())) { | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, | throw JSONRPCError(RPC_INVALID_PARAMETER, | ||||
"The proof is invalid: " + state.ToString()); | "The proof is invalid: " + state.ToString()); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
static UniValue sendavalancheproof(const Config &config, | |||||
const JSONRPCRequest &request) { | |||||
RPCHelpMan{ | |||||
"sendavalancheproof", | |||||
"Broadcast an avalanche proof.\n", | |||||
{ | |||||
{"proof", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | |||||
"The avalanche proof to broadcast."}, | |||||
}, | |||||
RPCResult{RPCResult::Type::BOOL, "success", | |||||
"Whether the proof was sent successfully or not."}, | |||||
RPCExamples{HelpExampleRpc("sendavalancheproof", "<proof>")}, | |||||
} | |||||
.Check(request); | |||||
if (!g_avalanche) { | |||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Avalanche is not initialized"); | |||||
} | |||||
auto proof = std::make_shared<avalanche::Proof>(); | |||||
NodeContext &node = EnsureNodeContext(request.context); | |||||
// Verify the proof. Note that this is redundant with the verification done | |||||
// when adding the proof to the pool, but we get a chance to give a better | |||||
// error message. | |||||
verifyProofOrThrow(node, *proof, request.params[0].get_str()); | |||||
// Add the proof to the pool if we don't have it already. Since the proof | |||||
// verification has already been done, a failure likely indicates that there | |||||
// already is a proof with conflicting utxos. | |||||
const avalanche::ProofId &proofid = proof->getId(); | |||||
if (!g_avalanche->getProof(proofid) && !g_avalanche->addProof(proof)) { | |||||
throw JSONRPCError( | |||||
RPC_INVALID_PARAMETER, | |||||
"The proof has conflicting utxo with an existing proof"); | |||||
} | |||||
// TODO actually announce the proof via an inv message | |||||
// RelayProof(proofid, *node.connman); | |||||
return true; | |||||
} | |||||
static UniValue verifyavalancheproof(const Config &config, | static UniValue verifyavalancheproof(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
RPCHelpMan{ | RPCHelpMan{ | ||||
"verifyavalancheproof", | "verifyavalancheproof", | ||||
"Verify an avalanche proof is valid and return the error otherwise.\n", | "Verify an avalanche proof is valid and return the error otherwise.\n", | ||||
{ | { | ||||
{"proof", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | {"proof", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | ||||
"Proof to verify."}, | "Proof to verify."}, | ||||
Show All 19 Lines | static const CRPCCommand commands[] = { | ||||
// category name actor (function) argNames | // category name actor (function) argNames | ||||
// ------------------- ------------------------ ---------------------- ---------- | // ------------------- ------------------------ ---------------------- ---------- | ||||
{ "avalanche", "getavalanchekey", getavalanchekey, {}}, | { "avalanche", "getavalanchekey", getavalanchekey, {}}, | ||||
{ "avalanche", "addavalanchenode", addavalanchenode, {"nodeid"}}, | { "avalanche", "addavalanchenode", addavalanchenode, {"nodeid"}}, | ||||
{ "avalanche", "buildavalancheproof", buildavalancheproof, {"sequence", "expiration", "master", "stakes"}}, | { "avalanche", "buildavalancheproof", buildavalancheproof, {"sequence", "expiration", "master", "stakes"}}, | ||||
{ "avalanche", "decodeavalancheproof", decodeavalancheproof, {"proof"}}, | { "avalanche", "decodeavalancheproof", decodeavalancheproof, {"proof"}}, | ||||
{ "avalanche", "delegateavalancheproof", delegateavalancheproof, {"proof", "privatekey", "publickey", "delegation"}}, | { "avalanche", "delegateavalancheproof", delegateavalancheproof, {"proof", "privatekey", "publickey", "delegation"}}, | ||||
{ "avalanche", "getavalanchepeerinfo", getavalanchepeerinfo, {}}, | { "avalanche", "getavalanchepeerinfo", getavalanchepeerinfo, {}}, | ||||
{ "avalanche", "sendavalancheproof", sendavalancheproof, {"proof"}}, | |||||
{ "avalanche", "verifyavalancheproof", verifyavalancheproof, {"proof"}}, | { "avalanche", "verifyavalancheproof", verifyavalancheproof, {"proof"}}, | ||||
}; | }; | ||||
// clang-format on | // clang-format on | ||||
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) { | for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) { | ||||
t.appendCommand(commands[vcidx].name, &commands[vcidx]); | t.appendCommand(commands[vcidx].name, &commands[vcidx]); | ||||
} | } | ||||
} | } |