| 933 | } |
| 934 | |
| 935 | RPCHelpMan claimpegin() |
| 936 | { |
| 937 | return RPCHelpMan{"claimpegin", |
| 938 | "\nClaim coins from the main chain by creating a pegin transaction with the necessary metadata after the corresponding Bitcoin transaction.\n" |
| 939 | "Note that the transaction will not be relayed unless it is buried at least 102 blocks deep.\n" |
| 940 | "If a transaction is not relayed it may require manual addition to a functionary mempool in order for it to be mined.\n", |
| 941 | { |
| 942 | {"bitcoin_tx", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The raw bitcoin transaction (in hex) depositing bitcoin to the mainchain_address generated by getpeginaddress"}, |
| 943 | {"txoutproof", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "A rawtxoutproof (in hex) generated by the mainchain daemon's `gettxoutproof` containing a proof of only bitcoin_tx"}, |
| 944 | {"claim_script", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED_NAMED_ARG, "The witness program generated by getpeginaddress. Only needed if not in wallet."}, |
| 945 | }, |
| 946 | RPCResult{ |
| 947 | RPCResult::Type::STR_HEX, "txid", "txid of the resulting sidechain transaction", |
| 948 | }, |
| 949 | RPCExamples{ |
| 950 | HelpExampleCli("claimpegin", "\"0200000002b80a99d63ca943d72141750d983a3eeda3a5c5a92aa962884ffb141eb49ffb4f000000006a473044022031ffe1d76decdfbbdb7e2ee6010e865a5134137c261e1921da0348b95a207f9e02203596b065c197e31bcc2f80575154774ac4e80acd7d812c91d93c4ca6a3636f27012102d2130dfbbae9bd27eee126182a39878ac4e117d0850f04db0326981f43447f9efeffffffb80a99d63ca943d72141750d983a3eeda3a5c5a92aa962884ffb141eb49ffb4f010000006b483045022100cf041ce0eb249ae5a6bc33c71c156549c7e5ad877ae39e2e3b9c8f1d81ed35060220472d4e4bcc3b7c8d1b34e467f46d80480959183d743dad73b1ed0e93ec9fd14f012103e73e8b55478ab9c5de22e2a9e73c3e6aca2c2e93cd2bad5dc4436a9a455a5c44feffffff0200e1f5050000000017a914da1745e9b549bd0bfa1a569971c77eba30cd5a4b87e86cbe00000000001976a914a25fe72e7139fd3f61936b228d657b2548b3936a88acc0020000\" \"00000020976e918ed537b0f99028648f2a25c0bd4513644fb84d9cbe1108b4df6b8edf6ba715c424110f0934265bf8c5763d9cc9f1675a0f728b35b9bc5875f6806be3d19cd5b159ffff7f2000000000020000000224eab3da09d99407cb79f0089e3257414c4121cb85a320e1fd0f88678b6b798e0713a8d66544b6f631f9b6d281c71633fb91a67619b189a06bab09794d5554a60105\" \"0014058c769ffc7d12c35cddec87384506f536383f9c\"") |
| 951 | + HelpExampleRpc("claimpegin", "\"0200000002b80a99d63ca943d72141750d983a3eeda3a5c5a92aa962884ffb141eb49ffb4f000000006a473044022031ffe1d76decdfbbdb7e2ee6010e865a5134137c261e1921da0348b95a207f9e02203596b065c197e31bcc2f80575154774ac4e80acd7d812c91d93c4ca6a3636f27012102d2130dfbbae9bd27eee126182a39878ac4e117d0850f04db0326981f43447f9efeffffffb80a99d63ca943d72141750d983a3eeda3a5c5a92aa962884ffb141eb49ffb4f010000006b483045022100cf041ce0eb249ae5a6bc33c71c156549c7e5ad877ae39e2e3b9c8f1d81ed35060220472d4e4bcc3b7c8d1b34e467f46d80480959183d743dad73b1ed0e93ec9fd14f012103e73e8b55478ab9c5de22e2a9e73c3e6aca2c2e93cd2bad5dc4436a9a455a5c44feffffff0200e1f5050000000017a914da1745e9b549bd0bfa1a569971c77eba30cd5a4b87e86cbe00000000001976a914a25fe72e7139fd3f61936b228d657b2548b3936a88acc0020000\", \"00000020976e918ed537b0f99028648f2a25c0bd4513644fb84d9cbe1108b4df6b8edf6ba715c424110f0934265bf8c5763d9cc9f1675a0f728b35b9bc5875f6806be3d19cd5b159ffff7f2000000000020000000224eab3da09d99407cb79f0089e3257414c4121cb85a320e1fd0f88678b6b798e0713a8d66544b6f631f9b6d281c71633fb91a67619b189a06bab09794d5554a60105\", \"0014058c769ffc7d12c35cddec87384506f536383f9c\"") |
| 952 | }, |
| 953 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 954 | { |
| 955 | CTransactionRef tx_ref; |
| 956 | CMutableTransaction mtx; |
| 957 | |
| 958 | std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); |
| 959 | if (!wallet) return NullUniValue; |
| 960 | CWallet* const pwallet = wallet.get(); |
| 961 | |
| 962 | LOCK(pwallet->cs_wallet); |
| 963 | |
| 964 | if (pwallet->chain().isInitialBlockDownload()) { |
| 965 | throw JSONRPCError(RPC_WALLET_ERROR, "Peg-ins cannot be completed during initial sync or reindexing."); |
| 966 | } |
| 967 | |
| 968 | // NOTE: Making an RPC from within another RPC is not generally a good idea. In particular, it |
| 969 | // is necessary to copy the URI, which contains the wallet if one was given; otherwise |
| 970 | // multi-wallet support will silently break. The resulting request object is still missing a |
| 971 | // bunch of other fields, although they are usually not used by RPC handlers. This is a |
| 972 | // brittle hack, and further examples of this pattern should not be introduced. |
| 973 | |
| 974 | // Get raw peg-in transaction |
| 975 | JSONRPCRequest req; |
| 976 | req.context = request.context; |
| 977 | req.URI = request.URI; |
| 978 | req.params = request.params; |
| 979 | UniValue ret(createrawpegin().HandleRequest(req)); // See the note above, on why this is a bad idea. |
| 980 | |
| 981 | // Make sure it can be propagated and confirmed |
| 982 | if (!ret["mature"].isNull() && ret["mature"].get_bool() == false) { |
| 983 | throw JSONRPCError(RPC_INVALID_PARAMETER, "Peg-in Bitcoin transaction needs more confirmations to be sent."); |
| 984 | } |
| 985 | |
| 986 | // Sign it |
| 987 | JSONRPCRequest req2; |
| 988 | req2.context = request.context; |
| 989 | req2.URI = request.URI; |
| 990 | UniValue varr(UniValue::VARR); |
| 991 | varr.push_back(ret["hex"]); |
| 992 | req2.params = varr; |
nothing calls this directly
no test coverage detected