Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/avalanche.cpp
Show First 20 Lines • Show All 142 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
RPCExamples{HelpExampleRpc("buildavalancheproof", | RPCExamples{HelpExampleRpc("buildavalancheproof", | ||||
"0 1234567800 \"<master>\" []")}, | "0 1234567800 \"<master>\" []")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VNUM, | RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VNUM, | ||||
UniValue::VSTR, UniValue::VARR}); | UniValue::VSTR, UniValue::VARR}); | ||||
if (!g_avalanche) { | |||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Avalanche is not initialized"); | |||||
} | |||||
const uint64_t sequence = request.params[0].get_int64(); | const uint64_t sequence = request.params[0].get_int64(); | ||||
const int64_t expiration = request.params[1].get_int64(); | const int64_t expiration = request.params[1].get_int64(); | ||||
avalanche::ProofBuilder pb(sequence, expiration, | avalanche::ProofBuilder pb(sequence, expiration, | ||||
ParsePubKey(request.params[2])); | ParsePubKey(request.params[2])); | ||||
const UniValue &stakes = request.params[3].get_array(); | const UniValue &stakes = request.params[3].get_array(); | ||||
for (size_t i = 0; i < stakes.size(); i++) { | for (size_t i = 0; i < stakes.size(); i++) { | ||||
const UniValue &stake = stakes[i]; | const UniValue &stake = stakes[i]; | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | static UniValue buildavalancheproof(const Config &config, | ||||
const avalanche::Proof proof = pb.build(); | const avalanche::Proof proof = pb.build(); | ||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); | CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); | ||||
ss << proof; | ss << proof; | ||||
return HexStr(ss); | return HexStr(ss); | ||||
} | } | ||||
static UniValue decodeavalancheproof(const Config &config, | |||||
const JSONRPCRequest &request) { | |||||
RPCHelpMan{ | |||||
"decodeavalancheproof", | |||||
"Convert a serialized, hex-encoded proof, into JSON object. " | |||||
"The validity of the proof is not verified.\n", | |||||
{ | |||||
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | |||||
"The proof hex string"}, | |||||
}, | |||||
RPCResult{ | |||||
RPCResult::Type::OBJ, | |||||
"", | |||||
"", | |||||
{ | |||||
{RPCResult::Type::NUM, "sequence", | |||||
"The proof's sequential number"}, | |||||
{RPCResult::Type::NUM, "expiration", | |||||
"A timestamp indicating when the proof expires"}, | |||||
{RPCResult::Type::STR_HEX, "master", "The master public key"}, | |||||
{RPCResult::Type::STR_HEX, "proofid", | |||||
"The proof's unique identifier"}, | |||||
{RPCResult::Type::ARR, | |||||
"stakes", | |||||
"", | |||||
{ | |||||
{RPCResult::Type::OBJ, | |||||
"", | |||||
"", | |||||
{ | |||||
{RPCResult::Type::STR_HEX, "txid", | |||||
"The transaction id"}, | |||||
{RPCResult::Type::NUM, "vout", "The output number"}, | |||||
{RPCResult::Type::STR_AMOUNT, "amount", | |||||
"The amount in this UTXO"}, | |||||
{RPCResult::Type::NUM, "height", | |||||
"The height at which this UTXO was mined"}, | |||||
{RPCResult::Type::BOOL, "iscoinbase", | |||||
"Indicate whether the UTXO is a coinbase"}, | |||||
{RPCResult::Type::STR_HEX, "pubkey", | |||||
"This UTXO's public key"}, | |||||
{RPCResult::Type::STR, "signature", | |||||
"Signature of the proofid with this UTXO's private " | |||||
"key (base64 encoded)"}, | |||||
}}, | |||||
}}, | |||||
}}, | |||||
RPCExamples{HelpExampleCli("decodeavalancheproof", "\"<hex proof>\"") + | |||||
HelpExampleRpc("decodeavalancheproof", "\"<hex proof>\"")}, | |||||
} | |||||
.Check(request); | |||||
RPCTypeCheck(request.params, {UniValue::VSTR}); | |||||
avalanche::Proof proof; | |||||
bilingual_str error; | |||||
if (!avalanche::Proof::FromHex(proof, request.params[0].get_str(), error)) { | |||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, error.original); | |||||
} | |||||
UniValue result(UniValue::VOBJ); | |||||
result.pushKV("sequence", proof.getSequence()); | |||||
result.pushKV("expiration", proof.getExpirationTime()); | |||||
result.pushKV("master", HexStr(proof.getMaster())); | |||||
result.pushKV("proofid", proof.getId().ToString()); | |||||
UniValue stakes(UniValue::VARR); | |||||
for (const avalanche::SignedStake &s : proof.getStakes()) { | |||||
const COutPoint &utxo = s.getStake().getUTXO(); | |||||
UniValue stake(UniValue::VOBJ); | |||||
stake.pushKV("txid", utxo.GetTxId().ToString()); | |||||
stake.pushKV("vout", uint64_t(utxo.GetN())); | |||||
stake.pushKV("amount", ValueFromAmount(s.getStake().getAmount())); | |||||
stake.pushKV("height", uint64_t(s.getStake().getHeight())); | |||||
stake.pushKV("iscoinbase", s.getStake().isCoinbase()); | |||||
stake.pushKV("pubkey", HexStr(s.getStake().getPubkey())); | |||||
stake.pushKV("signature", EncodeBase64(s.getSignature())); | |||||
stakes.push_back(stake); | |||||
} | |||||
result.pushKV("stakes", stakes); | |||||
return result; | |||||
} | |||||
static UniValue delegateavalancheproof(const Config &config, | static UniValue delegateavalancheproof(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
RPCHelpMan{ | RPCHelpMan{ | ||||
"delegateavalancheproof", | "delegateavalancheproof", | ||||
"Delegate the avalanche proof to another public key.\n", | "Delegate the avalanche proof to another public key.\n", | ||||
{ | { | ||||
{"proof", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | {"proof", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | ||||
"The proof to be delegated."}, | "The proof to be delegated."}, | ||||
▲ Show 20 Lines • Show All 223 Lines • ▼ Show 20 Lines | |||||
void RegisterAvalancheRPCCommands(CRPCTable &t) { | void RegisterAvalancheRPCCommands(CRPCTable &t) { | ||||
// clang-format off | // clang-format off | ||||
static const CRPCCommand commands[] = { | 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", "delegateavalancheproof", delegateavalancheproof, {"proof", "privatekey", "publickey", "delegation"}}, | { "avalanche", "delegateavalancheproof", delegateavalancheproof, {"proof", "privatekey", "publickey", "delegation"}}, | ||||
{ "avalanche", "getavalanchepeerinfo", getavalanchepeerinfo, {}}, | { "avalanche", "getavalanchepeerinfo", getavalanchepeerinfo, {}}, | ||||
{ "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]); | ||||
} | } | ||||
} | } |