Skip to content

Commit 4d486e6

Browse files
committed
add generatepegoutproof RPC call
1 parent e9f6e82 commit 4d486e6

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

src/wallet/rpcwallet.cpp

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6026,6 +6026,104 @@ UniValue destroyamount(const JSONRPCRequest& request)
60266026
return tx->GetHash().GetHex();
60276027
}
60286028

6029+
// Only used for functionary integration tests
6030+
UniValue generatepegoutproof(const JSONRPCRequest& request)
6031+
{
6032+
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
6033+
CWallet* const pwallet = wallet.get();
6034+
6035+
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
6036+
return NullUniValue;
6037+
}
6038+
6039+
if (request.fHelp || request.params.size() != 3)
6040+
throw std::runtime_error(
6041+
"generatepegoutproof sumkey btcpubkey onlinepubkey\n"
6042+
"\nONLY FOR TESTING: Generates pegout authorization proof for pegout based on the summed privkey and returns in hex. Result should be passed as an argument in `sendtomainchain`. Caution: Whitelist proof-validating mempools will filter incorrect pegoutproofs but aren't consensus enforced!\n"
6043+
"\nArguments:\n"
6044+
"1. \"sumkey\" (string, required) Base58 summed key of Bitcoin and offline key\n"
6045+
"2. \"btcpubkey\" (string, required) Hex pegout destination Bitcoin pubkey\n"
6046+
"3. \"onlinepubkey\" (string, required) hex `online pubkey`\n"
6047+
"\nResult:\n"
6048+
"\"pegoutproof\" (string, hex) pegout authorization proof to be passed into sendtomainchain\n"
6049+
+ HelpExampleCli("generatepegoutproof", "\"cQtNrRngdc4RJ9CkuTVKVLyxPFsijiTJySob24xCdKXGohdFhXML\" \"02c611095119e3dc96db428a0e190a3e142237bcd2efa4fb358257497885af3ab6\" \"0390695fff5535780df1e04c1f6c10e7c0a399fa56cfce34bf8108d0a9bc7a437b\"")
6050+
+ HelpExampleRpc("generatepegoutproof", "\"cQtNrRngdc4RJ9CkuTVKVLyxPFsijiTJySob24xCdKXGohdFhXML\" \"02c611095119e3dc96db428a0e190a3e142237bcd2efa4fb358257497885af3ab6\" \"0390695fff5535780df1e04c1f6c10e7c0a399fa56cfce34bf8108d0a9bc7a437b\"")
6051+
);
6052+
6053+
LOCK2(cs_main, pwallet->cs_wallet);
6054+
6055+
if (!IsHex(request.params[1].get_str()))
6056+
throw JSONRPCError(RPC_TYPE_ERROR, "btcpubkey must be hex string");
6057+
if (!IsHex(request.params[2].get_str()))
6058+
throw JSONRPCError(RPC_TYPE_ERROR, "onlinepubkey must be hex string");
6059+
6060+
//Parse private keys
6061+
6062+
CKey summedSecret = DecodeSecret(request.params[0].get_str());
6063+
if (!summedSecret.IsValid()) {
6064+
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid summed private key encoding");
6065+
}
6066+
6067+
std::vector<unsigned char> sumprivkeybytes(summedSecret.begin(), summedSecret.end());
6068+
std::vector<unsigned char> btcpubkeybytes = ParseHex(request.params[1].get_str());
6069+
std::vector<unsigned char> onlinepubkeybytes = ParseHex(request.params[2].get_str());
6070+
6071+
//Parse onlinepubkey
6072+
CPubKey onlinepubkey;
6073+
onlinepubkey.Set(onlinepubkeybytes.begin(), onlinepubkeybytes.end());
6074+
if (!onlinepubkey.IsFullyValid())
6075+
throw JSONRPCError(RPC_WALLET_ERROR, "Invalid online pubkey");
6076+
secp256k1_pubkey onlinepubkey_secp;
6077+
if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &onlinepubkey_secp, &onlinepubkeybytes[0], onlinepubkeybytes.size()))
6078+
throw JSONRPCError(RPC_WALLET_ERROR, "Invalid online pubkey");
6079+
6080+
CPAKList paklist = g_paklist_blockchain;
6081+
if (g_paklist_config) {
6082+
paklist = *g_paklist_config;
6083+
}
6084+
if (paklist.IsReject()) {
6085+
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pegout freeze is under effect to aid a pak transition to a new list. Please consult the network operator.");
6086+
}
6087+
6088+
//Find PAK online pubkey on PAK list
6089+
int whitelistindex=-1;
6090+
std::vector<secp256k1_pubkey> pak_online = paklist.OnlineKeys();
6091+
for (unsigned int i=0; i<pak_online.size(); i++) {
6092+
if (!memcmp((void *)&pak_online[i], (void *)&onlinepubkey_secp, sizeof(secp256k1_pubkey)))
6093+
whitelistindex = i;
6094+
}
6095+
if (whitelistindex == -1)
6096+
throw JSONRPCError(RPC_WALLET_ERROR, "Given online key is not in Pegout Authorization Key List");
6097+
6098+
CKey masterOnlineKey;
6099+
if (!pwallet->GetKey(onlinepubkey.GetID(), masterOnlineKey))
6100+
throw JSONRPCError(RPC_WALLET_ERROR, "Given online key is in master set but not in wallet");
6101+
6102+
//Parse own offline pubkey
6103+
secp256k1_pubkey btcpubkey;
6104+
if (secp256k1_ec_pubkey_parse(secp256k1_ctx, &btcpubkey, &btcpubkeybytes[0], btcpubkeybytes.size()) != 1)
6105+
throw JSONRPCError(RPC_WALLET_ERROR, "btcpubkey is invalid pubkey");
6106+
6107+
//Create, verify whitelist proof
6108+
secp256k1_whitelist_signature sig;
6109+
if(secp256k1_whitelist_sign(secp256k1_ctx, &sig, &paklist.OnlineKeys()[0], &paklist.OfflineKeys()[0], paklist.size(), &btcpubkey, masterOnlineKey.begin(), &sumprivkeybytes[0], whitelistindex, NULL, NULL) != 1)
6110+
throw JSONRPCError(RPC_WALLET_ERROR, "Pegout authorization proof signing failed");
6111+
6112+
if (secp256k1_whitelist_verify(secp256k1_ctx, &sig, &paklist.OnlineKeys()[0], &paklist.OfflineKeys()[0], paklist.size(), &btcpubkey) != 1)
6113+
throw JSONRPCError(RPC_WALLET_ERROR, "Pegout authorization proof was created and signed but is invalid");
6114+
6115+
//Serialize and return as hex
6116+
size_t expectedOutputSize = 1 + 32 * (1 + paklist.size());
6117+
const size_t preSize = expectedOutputSize;
6118+
assert(1 + 32 * (1 + 256) >= expectedOutputSize);
6119+
unsigned char output[1 + 32 * (1 + 256)];
6120+
secp256k1_whitelist_signature_serialize(secp256k1_ctx, output, &expectedOutputSize, &sig);
6121+
assert(expectedOutputSize == preSize);
6122+
std::vector<unsigned char> voutput(output, output + expectedOutputSize / sizeof(output[0]));
6123+
6124+
return HexStr(voutput.begin(), voutput.end());
6125+
}
6126+
60296127

60306128
// END ELEMENTS commands
60316129
//
@@ -6124,6 +6222,7 @@ static const CRPCCommand commands[] =
61246222
{ "wallet", "issueasset", &issueasset, {"assetamount", "tokenamount", "blind"}},
61256223
{ "wallet", "reissueasset", &reissueasset, {"asset", "assetamount"}},
61266224
{ "wallet", "destroyamount", &destroyamount, {"asset", "amount", "comment"} },
6225+
{ "hidden", "generatepegoutproof", &generatepegoutproof, {"sumkey", "btcpubkey", "onlinepubkey"} },
61276226
};
61286227
// clang-format on
61296228

0 commit comments

Comments
 (0)