@@ -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+ " \n ONLY 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+ " \n Arguments:\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+ " \n Result:\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