CoolFace
Datasetpublic

GSaha567/seq_level_training_data

sourceHugging Faceupdated 8mo agoView on Hugging Face
0likes52downloads
shard_000069.csv85851 linesDownload Raw Back to root
1text,length,is_long_context,metric_val,label_metric2"// Copyright (c) 2009-2020 The Bitcoin Core developers3// Copyright (c) 2020 The Bitcoin Global developers4// Distributed under the MIT software license, see the accompanying5// file COPYING or http://www.opensource.org/licenses/mit-license.php.6 7#include <chain.h>8#include <core_io.h>9#include <interfaces/chain.h>10#include <key_io.h>11#include <merkleblock.h>12#include <rpc/server.h>13#include <rpc/util.h>14#include <script/descriptor.h>15#include <script/script.h>16#include <script/standard.h>17#include <sync.h>18#include <util/bip32.h>19#include <util/system.h>20#include <util/time.h>21#include <util/translation.h>22#include <wallet/rpcwallet.h>23#include <wallet/wallet.h>24 25#include <stdint.h>26#include <tuple>27 28#include <boost/algorithm/string.hpp>29#include <boost/date_time/posix_time/posix_time.hpp>30 31#include <univalue.h>32 33 34int64_t static DecodeDumpTime(const std::string &str) {35    static const boost::posix_time::ptime epoch = boost::posix_time::from_time_t(0);36    static const std::locale loc(std::locale::classic(),37        new boost::posix_time::time_input_facet(""%Y-%m-%dT%H:%M:%SZ""));38    std::istringstream iss(str);39    iss.imbue(loc);40    boost::posix_time::ptime ptime(boost::date_time::not_a_date_time);41    iss >> ptime;42    if (ptime.is_not_a_date_time())43        return 0;44    return (ptime - epoch).total_seconds();45}46 47std::string static EncodeDumpString(const std::string &str) {48    std::stringstream ret;49    for (const unsigned char c : str) {50        if (c <= 32 || c >= 128 || c == '%') {51            ret << '%' << HexStr(&c, &c + 1);52        } else {53            ret << c;54        }55    }56    return ret.str();57}58 59static std::string DecodeDumpString(const std::string &str) {60    std::stringstream ret;61    for (unsigned int pos = 0; pos < str.length(); pos++) {62        unsigned char c = str[pos];63        if (c == '%' && pos+2 < str.length()) {64            c = (((str[pos+1]>>6)*9+((str[pos+1]-'0')&15)) << 4) |65                ((str[pos+2]>>6)*9+((str[pos+2]-'0')&15));66            pos += 2;67        }68        ret << c;69    }70    return ret.str();71}72 73static bool GetWalletAddressesForKey(CWallet* const pwallet, const CKeyID& keyid, std::string& strAddr, std::string& strLabel) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)74{75    bool fLabelFound = false;76    CKey key;77    pwallet->GetKey(keyid, key);78    for (const auto& dest : GetAllDestinationsForKey(key.GetPubKey())) {79        if (pwallet->mapAddressBook.count(dest)) {80            if (!strAddr.empty()) {81                strAddr += "","";82            }83            strAddr += EncodeDestination(dest);84            strLabel = EncodeDumpString(pwallet->mapAddressBook[dest].name);85            fLabelFound = true;86        }87    }88    if (!fLabelFound) {89        strAddr = EncodeDestination(GetDestinationForKey(key.GetPubKey(), pwallet->m_default_address_type));90    }91    return fLabelFound;92}93 94static const int64_t TIMESTAMP_MIN = 0;95 96static void RescanWallet(CWallet& wallet, const WalletRescanReserver& reserver, int64_t time_begin = TIMESTAMP_MIN, bool update = true)97{98    int64_t scanned_time = wallet.RescanFromTime(time_begin, reserver, update);99    if (wallet.IsAbortingRescan()) {100        throw JSONRPCError(RPC_MISC_ERROR, ""Rescan aborted by user."");101    } else if (scanned_time > time_begin) {102        throw JSONRPCError(RPC_WALLET_ERROR, ""Rescan was unable to fully rescan the blockchain. Some transactions may be missing."");103    }104}105 106UniValue importprivkey(const JSONRPCRequest& request)107{108    std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);109    CWallet* const pwallet = wallet.get();110    if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {111        return NullUniValue;112    }113 114            RPCHelpMan{""importprivkey"",115                ""\\nAdds a private key (as returned by dumpprivkey) to your wallet. Requires a new wallet backup.\\n""116                ""Hint: use importmulti to import more than one private key.\\n""117            ""\\nNote: This call can take over an hour to complete if rescan is true, during that time, other rpc calls\\n""118            ""may report that the imported key exists but related transactions are still missing, leading to temporarily incorrect/bogus balances and unspent outputs until rescan completes.\\n""119            ""Note: Use \\""getwalletinfo\\"" to query the scanning progress.\\n"",120                {121                    {""privkey"", RPCArg::Type::STR, RPCArg::Optional::NO, ""The private key (see dumpprivkey)""},122                    {""label"", RPCArg::Type::STR, /* default */ ""current label if address exists, otherwise \\""\\"""", ""An optional label""},123                    {""rescan"", RPCArg::Type::BOOL, /* default */ ""true"", ""Rescan the wallet for transactions""},124                },125                RPCResults{},126                RPCExamples{127            ""\\nDump a private key\\n""128            + HelpExampleCli(""dumpprivkey"", ""\\""myaddress\\"""") +129            ""\\nImport the private key with rescan\\n""130            + HelpExampleCli(""importprivkey"", ""\\""mykey\\"""") +131            ""\\nImport using a label and without rescan\\n""132            + HelpExampleCli(""importprivkey"", ""\\""mykey\\"" \\""testing\\"" false"") +133            ""\\nImport using default blank label and without rescan\\n""134            + HelpExampleCli(""importprivkey"", ""\\""mykey\\"" \\""\\"" false"") +135            ""\\nAs a JSON-RPC call\\n""136            + HelpExampleRpc(""importprivkey"", ""\\""mykey\\"", \\""testing\\"", false"")137                },138            }.Check(request);139 140    if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {141        throw JSONRPCError(RPC_WALLET_ERROR, ""Cannot import private keys to a wallet with private keys disabled"");142    }143 144    WalletRescanReserver reserver(pwallet);145    bool fRescan = true;146    {147        auto locked_chain = pwallet->chain().lock();148        LOCK(pwallet->cs_wallet);149 150        EnsureWalletIsUnlocked(pwallet);151 152        std::string strSecret = request.params[0].get_str();153        std::string strLabel = """";154        if (!request.params[1].isNull())155            strLabel = request.params[1].get_str();156 157        // Whether to perform rescan after import158        if (!request.params[2].isNull())159            fRescan = request.params[2].get_bool();160 161        if (fRescan && pwallet->chain().havePruned()) {162            // Exit early and print an error.163            // If a block is pruned after this check, we will import the key(s),164            // but fail the rescan with a generic error.165            throw JSONRPCError(RPC_WALLET_ERROR, ""Rescan is disabled when blocks are pruned"");166        }167 168        if (fRescan && !reserver.reserve()) {169            throw JSONRPCError(RPC_WALLET_ERROR, ""Wallet is currently rescanning. Abort existing rescan or wait."");170        }171 172        CKey key = DecodeSecret(strSecret);173        if (!key.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Invalid private key encoding"");174 175        CPubKey pubkey = key.GetPubKey();176        assert(key.VerifyPubKey(pubkey));177        CKeyID vchAddress = pubkey.GetID();178        {179            pwallet->MarkDirty();180 181            // We don't know which corresponding address will be used;182            // label all new addresses, and label existing addresses if a183            // label was passed.184            for (const auto& dest : GetAllDestinationsForKey(pubkey)) {185                if (!request.params[1].isNull() || pwallet->mapAddressBook.count(dest) == 0) {186                    pwallet->SetAddressBook(dest, strLabel, ""receive"");187                }188            }189 190            // Use timestamp of 1 to scan the whole chain191            if (!pwallet->ImportPrivKeys({{vchAddress, key}}, 1)) {192                throw JSONRPCError(RPC_WALLET_ERROR, ""Error adding key to wallet"");193            }194 195            // Add the wpkh script for this key if possible196            if (pubkey.IsCompressed()) {197                pwallet->ImportScripts({GetScriptForDestination(WitnessV0KeyHash(vchAddress))}, 0 /* timestamp */);198            }199        }200    }201    if (fRescan) {202        RescanWallet(*pwallet, reserver);203    }204 205    return NullUniValue;206}207 208UniValue abortrescan(const JSONRPCRequest& request)209{210    std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);211    CWallet* const pwallet = wallet.get();212    if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {213        return NullUniValue;214    }215 216            RPCHelpMan{""abortrescan"",217                ""\\nStops current wallet rescan triggered by an RPC call, e.g. by an importprivkey call.\\n""218                ""Note: Use \\""getwalletinfo\\"" to query the scanning progress.\\n"",219                {},220                RPCResults{},221                RPCExamples{222            ""\\nImport a private key\\n""223            + HelpExampleCli(""importprivkey"", ""\\""mykey\\"""") +224            ""\\nAbort the running wallet rescan\\n""225            + HelpExampleCli(""abortrescan"", """") +226            ""\\nAs a JSON-RPC call\\n""227            + HelpExampleRpc(""abortrescan"", """")228                },229            }.Check(request);230 231    if (!pwallet->IsScanning() || pwallet->IsAbortingRescan()) return false;232    pwallet->AbortRescan();233    return true;234}235 236UniValue importaddress(const JSONRPCRequest& request)237{238    std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);239    CWallet* const pwallet = wallet.get();240    if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {241        return NullUniValue;242    }243 244            RPCHelpMan{""importaddress"",245                ""\\nAdds an address or script (in hex) that can be watched as if it were in your wallet but cannot be used to spend. Requires a new wallet backup.\\n""246            ""\\nNote: This call can take over an hour to complete if rescan is true, during that time, other rpc calls\\n""247            ""may report that the imported address exists but related transactions are still missing, leading to temporarily incorrect/bogus balances and unspent outputs until rescan completes.\\n""248            ""If you have the full public key, you should call importpubkey instead of this.\\n""249            ""Hint: use importmulti to import more than one address.\\n""250            ""\\nNote: If you import a non-standard raw script in hex form, outputs sending to it will be treated\\n""251            ""as change, and not show up in many RPCs.\\n""252            ""Note: Use \\""getwalletinfo\\"" to query the scanning progress.\\n"",253                {254                    {""address"", RPCArg::Type::STR, RPCArg::Optional::NO, ""The Bitcoin Global address (or hex-encoded script)""},255                    {""label"", RPCArg::Type::STR, /* default */ ""\\""\\"""", ""An optional label""},256                    {""rescan"", RPCArg::Type::BOOL, /* default */ ""true"", ""Rescan the wallet for transactions""},257                    {""p2sh"", RPCArg::Type::BOOL, /* default */ ""false"", ""Add the P2SH version of the script as well""},258                },259                RPCResults{},260                RPCExamples{261            ""\\nImport an address with rescan\\n""262            + HelpExampleCli(""importaddress"", ""\\""myaddress\\"""") +263            ""\\nImport using a label without rescan\\n""264            + HelpExampleCli(""importaddress"", ""\\""myaddress\\"" \\""testing\\"" false"") +265            ""\\nAs a JSON-RPC call\\n""266            + HelpExampleRpc(""importaddress"", ""\\""myaddress\\"", \\""testing\\"", false"")267                },268            }.Check(request);269 270 271    std::string strLabel;272    if (!request.params[1].isNull())273        strLabel = request.params[1].get_str();274 275    // Whether to perform rescan after import276    bool fRescan = true;277    if (!request.params[2].isNull())278        fRescan = request.params[2].get_bool();279 280    if (fRescan && pwallet->chain().havePruned()) {281        // Exit early and print an error.282        // If a block is pruned after this check, we will import the key(s),283        // but fail the rescan with a generic error.284        throw JSONRPCError(RPC_WALLET_ERROR, ""Rescan is disabled when blocks are pruned"");285    }286 287    WalletRescanReserver reserver(pwallet);288    if (fRescan && !reserver.reserve()) {289        throw JSONRPCError(RPC_WALLET_ERROR, ""Wallet is currently rescanning. Abort existing rescan or wait."");290    }291 292    // Whether to import a p2sh version, too293    bool fP2SH = false;294    if (!request.params[3].isNull())295        fP2SH = request.params[3].get_bool();296 297    {298        auto locked_chain = pwallet->chain().lock();299        LOCK(pwallet->cs_wallet);300 301        CTxDestination dest = DecodeDestination(request.params[0].get_str());302        if (IsValidDestination(dest)) {303            if (fP2SH) {304                throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Cannot use the p2sh flag with an address - use a script instead"");305            }306 307            pwallet->MarkDirty();308 309            pwallet->ImportScriptPubKeys(strLabel, {GetScriptForDestination(dest)}, false /* have_solving_data */, true /* apply_label */, 1 /* timestamp */);310        } else if (IsHex(request.params[0].get_str())) {311            std::vector<unsigned char> data(ParseHex(request.params[0].get_str()));312            CScript redeem_script(data.begin(), data.end());313 314            std::set<CScript> scripts = {redeem_script};315            pwallet->ImportScripts(scripts, 0 /* timestamp */);316 317            if (fP2SH) {318                scripts.insert(GetScriptForDestination(ScriptHash(CScriptID(redeem_script))));319            }320 321            pwallet->ImportScriptPubKeys(strLabel, scripts, false /* have_solving_data */, true /* apply_label */, 1 /* timestamp */);322        } else {323            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Invalid Bitcoin Global address or script"");324        }325    }326    if (fRescan)327    {328        RescanWallet(*pwallet, reserver);329        {330            auto locked_chain = pwallet->chain().lock();331            LOCK(pwallet->cs_wallet);332            pwallet->ReacceptWalletTransactions(*locked_chain);333        }334    }335 336    return NullUniValue;337}338 339UniValue importprunedfunds(const JSONRPCRequest& request)340{341    std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);342    CWallet* const pwallet = wallet.get();343    if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {344        return NullUniValue;345    }346 347            RPCHelpMan{""importprunedfunds"",348                ""\\nImports funds without rescan. Corresponding address or script must previously be included in wallet. Aimed towards pruned wallets. The end-user is responsible to import additional transactions that subsequently spend the imported outputs or rescan after the point in the blockchain the transaction is included.\\n"",349                {350                    {""rawtransaction"", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, ""A raw transaction in hex funding an already-existing address in wallet""},351                    {""txoutproof"", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, ""The hex output from gettxoutproof that contains the transaction""},352                },353                RPCResults{},354                RPCExamples{""""},355            }.Check(request);356 357    CMutableTransaction tx;358    if (!DecodeHexTx(tx, request.params[0].get_str()))359        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, ""TX decode failed"");360    uint256 hashTx = tx.GetHash();361    CWalletTx wtx(pwallet, MakeTransactionRef(std::move(tx)));362 363    CDataStream ssMB(ParseHexV(request.params[1], ""proof""), SER_NETWORK, PROTOCOL_VERSION);364    CMerkleBlock merkleBlock;365    ssMB >> merkleBlock;366 367    //Search partial merkle tree in proof for our transaction and index in valid block368    std::vector<uint256> vMatch;369    std::vector<unsigned int> vIndex;370    unsigned int txnIndex = 0;371    if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) == merkleBlock.header.hashMerkleRoot) {372 373        auto locked_chain = pwallet->chain().lock();374        if (locked_chain->getBlockHeight(merkleBlock.header.GetHash()) == nullopt) {375            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Block not found in chain"");376        }377 378        std::vector<uint256>::const_iterator it;379        if ((it = std::find(vMatch.begin(), vMatch.end(), hashTx))==vMatch.end()) {380            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Transaction given doesn't exist in proof"");381        }382 383        txnIndex = vIndex[it - vMatch.begin()];384    }385    else {386        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Something wrong with merkleblock"");387    }388 389    wtx.SetConf(CWalletTx::Status::CONFIRMED, merkleBlock.header.GetHash(), txnIndex);390 391    auto locked_chain = pwallet->chain().lock();392    LOCK(pwallet->cs_wallet);393 394    if (pwallet->IsMine(*wtx.tx)) {395        pwallet->AddToWallet(wtx, false);396        return NullUniValue;397    }398 399    throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""No addresses in wallet correspond to included transaction"");400}401 402UniValue removeprunedfunds(const JSONRPCRequest& request)403{404    std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);405    CWallet* const pwallet = wallet.get();406    if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {407        return NullUniValue;408    }409 410            RPCHelpMan{""removeprunedfunds"",411                ""\\nDeletes the specified transaction from the wallet. Meant for use with pruned wallets and as a companion to importprunedfunds. This will affect wallet balances.\\n"",412                {413                    {""txid"", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, ""The hex-encoded id of the transaction you are deleting""},414                },415                RPCResults{},416                RPCExamples{417                    HelpExampleCli(""removeprunedfunds"", ""\\""a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\\"""") +418            ""\\nAs a JSON-RPC call\\n""419            + HelpExampleRpc(""removeprunedfunds"", ""\\""a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\\"""")420                },421            }.Check(request);422 423    auto locked_chain = pwallet->chain().lock();424    LOCK(pwallet->cs_wallet);425 426    uint256 hash(ParseHashV(request.params[0], ""txid""));427    std::vector<uint256> vHash;428    vHash.push_back(hash);429    std::vector<uint256> vHashOut;430 431    if (pwallet->ZapSelectTx(vHash, vHashOut) != DBErrors::LOAD_OK) {432        throw JSONRPCError(RPC_WALLET_ERROR, ""Could not properly delete the transaction."");433    }434 435    if(vHashOut.empty()) {436        throw JSONRPCError(RPC_INVALID_PARAMETER, ""Transaction does not exist in wallet."");437    }438 439    return NullUniValue;440}441 442UniValue importpubkey(const JSONRPCRequest& request)443{444    std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);445    CWallet* const pwallet = wallet.get();446    if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {447        return NullUniValue;448    }449 450            RPCHelpMan{""importpubkey"",451                ""\\nAdds a public key (in hex) that can be watched as if it were in your wallet but cannot be used to spend. Requires a new wallet backup.\\n""452                ""Hint: use importmulti to import more than one public key.\\n""453            ""\\nNote: This call can take over an hour to complete if rescan is true, during that time, other rpc calls\\n""454            ""may report that the imported pubkey exists but related transactions are still missing, leading to temporarily incorrect/bogus balances and unspent outputs until rescan completes.\\n""455            ""Note: Use \\""getwalletinfo\\"" to query the scanning progress.\\n"",456                {457                    {""pubkey"", RPCArg::Type::STR, RPCArg::Optional::NO, ""The hex-encoded public key""},458                    {""label"", RPCArg::Type::STR, /* default */ ""\\""\\"""", ""An optional label""},459                    {""rescan"", RPCArg::Type::BOOL, /* default */ ""true"", ""Rescan the wallet for transactions""},460                },461                RPCResults{},462                RPCExamples{463            ""\\nImport a public key with rescan\\n""464            + HelpExampleCli(""importpubkey"", ""\\""mypubkey\\"""") +465            ""\\nImport using a label without rescan\\n""466            + HelpExampleCli(""importpubkey"", ""\\""mypubkey\\"" \\""testing\\"" false"") +467            ""\\nAs a JSON-RPC call\\n""468            + HelpExampleRpc(""importpubkey"", ""\\""mypubkey\\"", \\""testing\\"", false"")469                },470            }.Check(request);471 472 473    std::string strLabel;474    if (!request.params[1].isNull())475        strLabel = request.params[1].get_str();476 477    // Whether to perform rescan after import478    bool fRescan = true;479    if (!request.params[2].isNull())480        fRescan = request.params[2].get_bool();481 482    if (fRescan && pwallet->chain().havePruned()) {483        // Exit early and print an error.484        // If a block is pruned after this check, we will import the key(s),485        // but fail the rescan with a generic error.486        throw JSONRPCError(RPC_WALLET_ERROR, ""Rescan is disabled when blocks are pruned"");487    }488 489    WalletRescanReserver reserver(pwallet);490    if (fRescan && !reserver.reserve()) {491        throw JSONRPCError(RPC_WALLET_ERROR, ""Wallet is currently rescanning. Abort existing rescan or wait."");492    }493 494    if (!IsHex(request.params[0].get_str()))495        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Pubkey must be a hex string"");496    std::vector<unsigned char> data(ParseHex(request.params[0].get_str()));497    CPubKey pubKey(data.begin(), data.end());498    if (!pubKey.IsFullyValid())499        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Pubkey is not a valid public key"");500 501    {502        auto locked_chain = pwallet->chain().lock();503        LOCK(pwallet->cs_wallet);504 505        std::set<CScript> script_pub_keys;506        for (const auto& dest : GetAllDestinationsForKey(pubKey)) {507            script_pub_keys.insert(GetScriptForDestination(dest));508        }509 510        pwallet->MarkDirty();511 512        pwallet->ImportScriptPubKeys(strLabel, script_pub_keys, true /* have_solving_data */, true /* apply_label */, 1 /* timestamp */);513 514        pwallet->ImportPubKeys({pubKey.GetID()}, {{pubKey.GetID(), pubKey}} , {} /* key_origins */, false /* add_keypool */, false /* internal */, 1 /* timestamp */);515    }516    if (fRescan)517    {518        RescanWallet(*pwallet, reserver);519        {520            auto locked_chain = pwallet->chain().lock();521            LOCK(pwallet->cs_wallet);522            pwallet->ReacceptWalletTransactions(*locked_chain);523        }524    }525 526    return NullUniValue;527}528 529 530UniValue importwallet(const JSONRPCRequest& request)531{532    std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);533    CWallet* const pwallet = wallet.get();534    if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {535        return NullUniValue;536    }537 538            RPCHelpMan{""importwallet"",539                ""\\nImports keys from a wallet dump file (see dumpwallet). Requires a new wallet backup to include imported keys.\\n""540                ""Note: Use \\""getwalletinfo\\"" to query the scanning progress.\\n"",541                {542                    {""filename"", RPCArg::Type::STR, RPCArg::Optional::NO, ""The wallet file""},543                },544                RPCResults{},545                RPCExamples{546            ""\\nDump the wallet\\n""547            + HelpExampleCli(""dumpwallet"", ""\\""test\\"""") +548            ""\\nImport the wallet\\n""549            + HelpExampleCli(""importwallet"", ""\\""test\\"""") +550            ""\\nImport using the json rpc call\\n""551            + HelpExampleRpc(""importwallet"", ""\\""test\\"""")552                },553            }.Check(request);554 555    if (pwallet->chain().havePruned()) {556        // Exit early and print an error.557        // If a block is pruned after this check, we will import the key(s),558        // but fail the rescan with a generic error.559        throw JSONRPCError(RPC_WALLET_ERROR, ""Importing wallets is disabled when blocks are pruned"");560    }561 562    WalletRescanReserver reserver(pwallet);563    if (!reserver.reserve()) {564        throw JSONRPCError(RPC_WALLET_ERROR, ""Wallet is currently rescanning. Abort existing rescan or wait."");565    }566 567    int64_t nTimeBegin = 0;568    bool fGood = true;569    {570        auto locked_chain = pwallet->chain().lock();571        LOCK(pwallet->cs_wallet);572 573        EnsureWalletIsUnlocked(pwallet);574 575        fsbridge::ifstream file;576        file.open(request.params[0].get_str(), std::ios::in | std::ios::ate);577        if (!file.is_open()) {578            throw JSONRPCError(RPC_INVALID_PARAMETER, ""Cannot open wallet dump file"");579        }580        Optional<int> tip_height = locked_chain->getHeight();581        nTimeBegin = tip_height ? locked_chain->getBlockTime(*tip_height) : 0;582 583        int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg());584        file.seekg(0, file.beg);585 586        // Use uiInterface.ShowProgress instead of pwallet.ShowProgress because pwallet.ShowProgress has a cancel button tied to AbortRescan which587        // we don't want for this progress bar showing the import progress. uiInterface.ShowProgress does not have a cancel button.588        pwallet->chain().showProgress(strprintf(""%s "" + _(""Importing..."").translated, pwallet->GetDisplayName()), 0, false); // show progress dialog in GUI589        std::vector<std::tuple<CKey, int64_t, bool, std::string>> keys;590        std::vector<std::pair<CScript, int64_t>> scripts;591        while (file.good()) {592            pwallet->chain().showProgress("""", std::max(1, std::min(50, (int)(((double)file.tellg() / (double)nFilesize) * 100))), false);593            std::string line;594            std::getline(file, line);595            if (line.empty() || line[0] == '#')596                continue;597 598            std::vector<std::string> vstr;599            boost::split(vstr, line, boost::is_any_of("" ""));600            if (vstr.size() < 2)601                continue;602            CKey key = DecodeSecret(vstr[0]);603            if (key.IsValid()) {604                int64_t nTime = DecodeDumpTime(vstr[1]);605                std::string strLabel;606                bool fLabel = true;607                for (unsigned int nStr = 2; nStr < vstr.size(); nStr++) {608                    if (vstr[nStr].front() == '#')609                        break;610                    if (vstr[nStr] == ""change=1"")611                        fLabel = false;612                    if (vstr[nStr] == ""reserve=1"")613                        fLabel = false;614                    if (vstr[nStr].substr(0,6) == ""label="") {615                        strLabel = DecodeDumpString(vstr[nStr].substr(6));616                        fLabel = true;617                    }618                }619                keys.push_back(std::make_tuple(key, nTime, fLabel, strLabel));620            } else if(IsHex(vstr[0])) {621                std::vector<unsigned char> vData(ParseHex(vstr[0]));622                CScript script = CScript(vData.begin(), vData.end());623                int64_t birth_time = DecodeDumpTime(vstr[1]);624                scripts.push_back(std::pair<CScript, int64_t>(script, birth_time));625            }626        }627        file.close();628        // We now know whether we are importing private keys, so we can error if private keys are disabled629        if (keys.size() > 0 && pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {630            pwallet->chain().showProgress("""", 100, false); // hide progress dialog in GUI631            throw JSONRPCError(RPC_WALLET_ERROR, ""Importing wallets is disabled when private keys are disabled"");632        }633        double total = (double)(keys.size() + scripts.size());634        double progress = 0;635        for (const auto& key_tuple : keys) {636            pwallet->chain().showProgress("""", std::max(50, std::min(75, (int)((progress / total) * 100) + 50)), false);637            const CKey& key = std::get<0>(key_tuple);638            int64_t time = std::get<1>(key_tuple);639            bool has_label = std::get<2>(key_tuple);640            std::string label = std::get<3>(key_tuple);641 642            CPubKey pubkey = key.GetPubKey();643            assert(key.VerifyPubKey(pubkey));644            CKeyID keyid = pubkey.GetID();645 646            pwallet->WalletLogPrintf(""Importing %s...\\n"", EncodeDestination(PKHash(keyid)));647 648            if (!pwallet->ImportPrivKeys({{keyid, key}}, time)) {649                pwallet->WalletLogPrintf(""Error importing key for %s\\n"", EncodeDestination(PKHash(keyid)));650                fGood = false;651                continue;652            }653 654            if (has_label)655                pwallet->SetAddressBook(PKHash(keyid), label, ""receive"");656 657            nTimeBegin = std::min(nTimeBegin, time);658            progress++;659        }660        for (const auto& script_pair : scripts) {661            pwallet->chain().showProgress("""", std::max(50, std::min(75, (int)((progress / total) * 100) + 50)), false);662            const CScript& script = script_pair.first;663            int64_t time = script_pair.second;664 665            if (!pwallet->ImportScripts({script}, time)) {666                pwallet->WalletLogPrintf(""Error importing script %s\\n"", HexStr(script));667                fGood = false;668                continue;669            }670            if (time > 0) {671                nTimeBegin = std::min(nTimeBegin, time);672            }673 674            progress++;675        }676        pwallet->chain().showProgress("""", 100, false); // hide progress dialog in GUI677    }678    pwallet->chain().showProgress("""", 100, false); // hide progress dialog in GUI679    RescanWallet(*pwallet, reserver, nTimeBegin, false /* update */);680    pwallet->MarkDirty();681 682    if (!fGood)683        throw JSONRPCError(RPC_WALLET_ERROR, ""Error adding some keys/scripts to wallet"");684 685    return NullUniValue;686}687 688UniValue dumpprivkey(const JSONRPCRequest& request)689{690    std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);691    CWallet* const pwallet = wallet.get();692    if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {693        return NullUniValue;694    }695 696            RPCHelpMan{""dumpprivkey"",697                ""\\nReveals the private key corresponding to 'address'.\\n""698                ""Then the importprivkey can be used with this output\\n"",699                {700                    {""address"", RPCArg::Type::STR, RPCArg::Optional::NO, ""The bitcoin address for the private key""},701                },702                RPCResult{703            ""\\""key\\""                (string) The private key\\n""704                },705                RPCExamples{706                    HelpExampleCli(""dumpprivkey"", ""\\""myaddress\\"""")707            + HelpExampleCli(""importprivkey"", ""\\""mykey\\"""")708            + HelpExampleRpc(""dumpprivkey"", ""\\""myaddress\\"""")709                },710            }.Check(request);711 712    auto locked_chain = pwallet->chain().lock();713    LOCK(pwallet->cs_wallet);714 715    EnsureWalletIsUnlocked(pwallet);716 717    std::string strAddress = request.params[0].get_str();718    CTxDestination dest = DecodeDestination(strAddress);719    if (!IsValidDestination(dest)) {720        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Invalid Bitcoin Global address"");721    }722    auto keyid = GetKeyForDestination(*pwallet, dest);723    if (keyid.IsNull()) {724        throw JSONRPCError(RPC_TYPE_ERROR, ""Address does not refer to a key"");725    }726    CKey vchSecret;727    if (!pwallet->GetKey(keyid, vchSecret)) {728        throw JSONRPCError(RPC_WALLET_ERROR, ""Private key for address "" + strAddress + "" is not known"");729    }730    return EncodeSecret(vchSecret);731}732 733 734UniValue dumpwallet(const JSONRPCRequest& request)735{736    std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);737    CWallet* const pwallet = wallet.get();738    if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {739        return NullUniValue;740    }741 742            RPCHelpMan{""dumpwallet"",743                ""\\nDumps all wallet keys in a human-readable format to a server-side file. This does not allow overwriting existing files.\\n""744                ""Imported scripts are included in the dumpfile, but corresponding BIP173 addresses, etc. may not be added automatically by importwallet.\\n""745                ""Note that if your wallet contains keys which are not derived from your HD seed (e.g. imported keys), these are not covered by\\n""746                ""only backing up the seed itself, and must be backed up too (e.g. ensure you back up the whole dumpfile).\\n"",747                {748                    {""filename"", RPCArg::Type::STR, RPCArg::Optional::NO, ""The filename with path (either absolute or relative to bitglobd)""},749                },750                RPCResult{751            ""{                           (json object)\\n""752            ""  \\""filename\\"" : {        (string) The filename with full absolute path\\n""753            ""}\\n""754                },755                RPCExamples{756                    HelpExampleCli(""dumpwallet"", ""\\""test\\"""")757            + HelpExampleRpc(""dumpwallet"", ""\\""test\\"""")758                },759            }.Check(request);760 761    auto locked_chain = pwallet->chain().lock();762    LOCK(pwallet->cs_wallet);763 764    EnsureWalletIsUnlocked(pwallet);765 766    fs::path filepath = request.params[0].get_str();767    filepath = fs::absolute(filepath);768 769    /* Prevent arbitrary files from being overwritten. There have been reports770     * that users have overwritten wallet files this way:771     * https://github.com/bitcoin/bitcoin/issues/9934772     * It may also avoid other security issues.773     */774    if (fs::exists(filepath)) {775        throw JSONRPCError(RPC_INVALID_PARAMETER, filepath.string() + "" already exists. If you are sure this is what you want, move it out of the way first"");776    }777 778    fsbridge::ofstream file;779    file.open(filepath);780    if (!file.is_open())781        throw JSONRPCError(RPC_INVALID_PARAMETER, ""Cannot open wallet dump file"");782 783    std::map<CKeyID, int64_t> mapKeyBirth;784    const std::map<CKeyID, int64_t>& mapKeyPool = pwallet->GetAllReserveKeys();785    pwallet->GetKeyBirthTimes(*locked_chain, mapKeyBirth);786 787    std::set<CScriptID> scripts = pwallet->GetCScripts();788 789    // sort time/key pairs790    std::vector<std::pair<int64_t, CKeyID> > vKeyBirth;791    for (const auto& entry : mapKeyBirth) {792        vKeyBirth.push_back(std::make_pair(entry.second, entry.first));793    }794    mapKeyBirth.clear();795    std::sort(vKeyBirth.begin(), vKeyBirth.end());796 797    // produce output798    file << strprintf(""# Wallet dump created by Bitcoin %s\\n"", CLIENT_BUILD);799    file << strprintf(""# * Created on %s\\n"", FormatISO8601DateTime(GetTime()));800    const Optional<int> tip_height = locked_chain->getHeight();801    file << strprintf(""# * Best block at time of backup was %i (%s),\\n"", tip_height.get_value_or(-1), tip_height ? locked_chain->getBlockHash(*tip_height).ToString() : ""(missing block hash)"");802    file << strprintf(""#   mined on %s\\n"", tip_height ? FormatISO8601DateTime(locked_chain->getBlockTime(*tip_height)) : ""(missing block time)"");803    file << ""\\n"";804 805    // add the base58check encoded extended master if the wallet uses HD806    CKeyID seed_id = pwallet->GetHDChain().seed_id;807    if (!seed_id.IsNull())808    {809        CKey seed;810        if (pwallet->GetKey(seed_id, seed)) {811            CExtKey masterKey;812            masterKey.SetSeed(seed.begin(), seed.size());813 814            file << ""# extended private masterkey: "" << EncodeExtKey(masterKey) << ""\\n\\n"";815        }816    }817    for (std::vector<std::pair<int64_t, CKeyID> >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) {818        const CKeyID &keyid = it->second;819        std::string strTime = FormatISO8601DateTime(it->first);820        std::string strAddr;821        std::string strLabel;822        CKey key;823        if (pwallet->GetKey(keyid, key)) {824            file << strprintf(""%s %s "", EncodeSecret(key), strTime);825            if (GetWalletAddressesForKey(pwallet, keyid, strAddr, strLabel)) {826               file << strprintf(""label=%s"", strLabel);827            } else if (keyid == seed_id) {828                file << ""hdseed=1"";829            } else if (mapKeyPool.count(keyid)) {830                file << ""reserve=1"";831            } else if (pwallet->mapKeyMetadata[keyid].hdKeypath == ""s"") {832                file << ""inactivehdseed=1"";833            } else {834                file << ""change=1"";835            }836            file << strprintf("" # addr=%s%s\\n"", strAddr, (pwallet->mapKeyMetadata[keyid].has_key_origin ? "" hdkeypath=""+WriteHDKeypath(pwallet->mapKeyMetadata[keyid].key_origin.path) : """"));837        }838    }839    file << ""\\n"";840    for (const CScriptID &scriptid : scripts) {841        CScript script;842        std::string create_time = ""0"";843        std::string address = EncodeDestination(ScriptHash(scriptid));844        // get birth times for scripts with metadata845        auto it = pwallet->m_script_metadata.find(scriptid);846        if (it != pwallet->m_script_metadata.end()) {847            create_time = FormatISO8601DateTime(it->second.nCreateTime);848        }849        if(pwallet->GetCScript(scriptid, script)) {850            file << strprintf(""%s %s script=1"", HexStr(script.begin(), script.end()), create_time);851            file << strprintf("" # addr=%s\\n"", address);852        }853    }854    file << ""\\n"";855    file << ""# End of dump\\n"";856    file.close();857 858    UniValue reply(UniValue::VOBJ);859    reply.pushKV(""filename"", filepath.string());860 861    return reply;862}863 864struct ImportData865{866    // Input data867    std::unique_ptr<CScript> redeemscript; //!< Provided redeemScript; will be moved to `import_scripts` if relevant.868    std::unique_ptr<CScript> witnessscript; //!< Provided witnessScript; will be moved to `import_scripts` if relevant.869 870    // Output data871    std::set<CScript> import_scripts;872    std::map<CKeyID, bool> used_keys; //!< Import these private keys if available (the value indicates whether if the key is required for solvability)873    std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>> key_origins;874};875 876enum class ScriptContext877{878    TOP, //!< Top-level scriptPubKey879    P2SH, //!< P2SH redeemScript880    WITNESS_V0, //!< P2WSH witnessScript881};882 883// Analyse the provided scriptPubKey, determining which keys and which redeem scripts from the ImportData struct are needed to spend it, and mark them as used.884// Returns an error string, or the empty string for success.885static std::string RecurseImportData(const CScript& script, ImportData& import_data, const ScriptContext script_ctx)886{887    // Use Solver to obtain script type and parsed pubkeys or hashes:888    std::vector<std::vector<unsigned char>> solverdata;889    txnouttype script_type = Solver(script, solverdata);890 891    switch (script_type) {892    case TX_PUBKEY: {893        CPubKey pubkey(solverdata[0].begin(), solverdata[0].end());894        import_data.used_keys.emplace(pubkey.GetID(), false);895        return """";896    }897    case TX_PUBKEYHASH: {898        CKeyID id = CKeyID(uint160(solverdata[0]));899        import_data.used_keys[id] = true;900        return """";901    }902    case TX_SCRIPTHASH: {903        if (script_ctx == ScriptContext::P2SH) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Trying to nest P2SH inside another P2SH"");904        if (script_ctx == ScriptContext::WITNESS_V0) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Trying to nest P2SH inside a P2WSH"");905        assert(script_ctx == ScriptContext::TOP);906        CScriptID id = CScriptID(uint160(solverdata[0]));907        auto subscript = std::move(import_data.redeemscript); // Remove redeemscript from import_data to check for superfluous script later.908        if (!subscript) return ""missing redeemscript"";909        if (CScriptID(*subscript) != id) return ""redeemScript does not match the scriptPubKey"";910        import_data.import_scripts.emplace(*subscript);911        return RecurseImportData(*subscript, import_data, ScriptContext::P2SH);912    }913    case TX_MULTISIG: {914        for (size_t i = 1; i + 1< solverdata.size(); ++i) {915            CPubKey pubkey(solverdata[i].begin(), solverdata[i].end());916            import_data.used_keys.emplace(pubkey.GetID(), false);917        }918        return """";919    }920    case TX_WITNESS_V0_SCRIPTHASH: {921        if (script_ctx == ScriptContext::WITNESS_V0) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Trying to nest P2WSH inside another P2WSH"");922        uint256 fullid(solverdata[0]);923        CScriptID id;924        CRIPEMD160().Write(fullid.begin(), fullid.size()).Finalize(id.begin());925        auto subscript = std::move(import_data.witnessscript); // Remove redeemscript from import_data to check for superfluous script later.926        if (!subscript) return ""missing witnessscript"";927        if (CScriptID(*subscript) != id) return ""witnessScript does not match the scriptPubKey or redeemScript"";928        if (script_ctx == ScriptContext::TOP) {929            import_data.import_scripts.emplace(script); // Special rule for IsMine: native P2WSH requires the TOP script imported (see script/ismine.cpp)930        }931        import_data.import_scripts.emplace(*subscript);932        return RecurseImportData(*subscript, import_data, ScriptContext::WITNESS_V0);933    }934    case TX_WITNESS_V0_KEYHASH: {935        if (script_ctx == ScriptContext::WITNESS_V0) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Trying to nest P2WPKH inside P2WSH"");936        CKeyID id = CKeyID(uint160(solverdata[0]));937        import_data.used_keys[id] = true;938        if (script_ctx == ScriptContext::TOP) {939            import_data.import_scripts.emplace(script); // Special rule for IsMine: native P2WPKH requires the TOP script imported (see script/ismine.cpp)940        }941        return """";942    }943    case TX_NULL_DATA:944        return ""unspendable script"";945    case TX_NONSTANDARD:946    case TX_WITNESS_UNKNOWN:947    default:948        return ""unrecognized script"";949    }950}951 952static UniValue ProcessImportLegacy(ImportData& import_data, std::map<CKeyID, CPubKey>& pubkey_map, std::map<CKeyID, CKey>& privkey_map, std::set<CScript>& script_pub_keys, bool& have_solving_data, const UniValue& data, std::vector<CKeyID>& ordered_pubkeys)953{954    UniValue warnings(UniValue::VARR);955 956    // First ensure scriptPubKey has either a script or JSON with ""address"" string957    const UniValue& scriptPubKey = data[""scriptPubKey""];958    bool isScript = scriptPubKey.getType() == UniValue::VSTR;959    if (!isScript && !(scriptPubKey.getType() == UniValue::VOBJ && scriptPubKey.exists(""address""))) {960        throw JSONRPCError(RPC_INVALID_PARAMETER, ""scriptPubKey must be string with script or JSON with address string"");961    }962    const std::string& output = isScript ? scriptPubKey.get_str() : scriptPubKey[""address""].get_str();963 964    // Optional fields.965    const std::string& strRedeemScript = data.exists(""redeemscript"") ? data[""redeemscript""].get_str() : """";966    const std::string& witness_script_hex = data.exists(""witnessscript"") ? data[""witnessscript""].get_str() : """";967    const UniValue& pubKeys = data.exists(""pubkeys"") ? data[""pubkeys""].get_array() : UniValue();968    const UniValue& keys = data.exists(""keys"") ? data[""keys""].get_array() : UniValue();969    const bool internal = data.exists(""internal"") ? data[""internal""].get_bool() : false;970    const bool watchOnly = data.exists(""watchonly"") ? data[""watchonly""].get_bool() : false;971 972    if (data.exists(""range"")) {973        throw JSONRPCError(RPC_INVALID_PARAMETER, ""Range should not be specified for a non-descriptor import"");974    }975 976    // Generate the script and destination for the scriptPubKey provided977    CScript script;978    if (!isScript) {979        CTxDestination dest = DecodeDestination(output);980        if (!IsValidDestination(dest)) {981            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Invalid address \\"""" + output + ""\\"""");982        }983        script = GetScriptForDestination(dest);984    } else {985        if (!IsHex(output)) {986            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Invalid scriptPubKey \\"""" + output + ""\\"""");987        }988        std::vector<unsigned char> vData(ParseHex(output));989        script = CScript(vData.begin(), vData.end());990        CTxDestination dest;991        if (!ExtractDestination(script, dest) && !internal) {992            throw JSONRPCError(RPC_INVALID_PARAMETER, ""Internal must be set to true for nonstandard scriptPubKey imports."");993        }994    }995    script_pub_keys.emplace(script);996 997    // Parse all arguments998    if (strRedeemScript.size()) {999        if (!IsHex(strRedeemScript)) {1000            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Invalid redeem script \\"""" + strRedeemScript + ""\\"": must be hex string"");1001        }1002        auto parsed_redeemscript = ParseHex(strRedeemScript);1003        import_data.redeemscript = MakeUnique<CScript>(parsed_redeemscript.begin(), parsed_redeemscript.end());1004    }1005    if (witness_script_hex.size()) {1006        if (!IsHex(witness_script_hex)) {1007            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Invalid witness script \\"""" + witness_script_hex + ""\\"": must be hex string"");1008        }1009        auto parsed_witnessscript = ParseHex(witness_script_hex);1010        import_data.witnessscript = MakeUnique<CScript>(parsed_witnessscript.begin(), parsed_witnessscript.end());1011    }1012    for (size_t i = 0; i < pubKeys.size(); ++i) {1013        const auto& str = pubKeys[i].get_str();1014        if (!IsHex(str)) {1015            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Pubkey \\"""" + str + ""\\"" must be a hex string"");1016        }1017        auto parsed_pubkey = ParseHex(str);1018        CPubKey pubkey(parsed_pubkey.begin(), parsed_pubkey.end());1019        if (!pubkey.IsFullyValid()) {1020            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Pubkey \\"""" + str + ""\\"" is not a valid public key"");1021        }1022        pubkey_map.emplace(pubkey.GetID(), pubkey);1023        ordered_pubkeys.push_back(pubkey.GetID());1024    }1025    for (size_t i = 0; i < keys.size(); ++i) {1026        const auto& str = keys[i].get_str();1027        CKey key = DecodeSecret(str);1028        if (!key.IsValid()) {1029            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Invalid private key encoding"");1030        }1031        CPubKey pubkey = key.GetPubKey();1032        CKeyID id = pubkey.GetID();1033        if (pubkey_map.count(id)) {1034            pubkey_map.erase(id);1035        }1036        privkey_map.emplace(id, key);1037    }1038 1039 1040    // Verify and process input data1041    have_solving_data = import_data.redeemscript || import_data.witnessscript || pubkey_map.size() || privkey_map.size();1042    if (have_solving_data) {1043        // Match up data in import_data with the scriptPubKey in script.1044        auto error = RecurseImportData(script, import_data, ScriptContext::TOP);1045 1046        // Verify whether the watchonly option corresponds to the availability of private keys.1047        bool spendable = std::all_of(import_data.used_keys.begin(), import_data.used_keys.end(), [&](const std::pair<CKeyID, bool>& used_key){ return privkey_map.count(used_key.first) > 0; });1048        if (!watchOnly && !spendable) {1049            warnings.push_back(""Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag."");1050        }1051        if (watchOnly && spendable) {1052            warnings.push_back(""All private keys are provided, outputs will be considered spendable. If this is intentional, do not specify the watchonly flag."");1053        }1054 1055        // Check that all required keys for solvability are provided.1056        if (error.empty()) {1057            for (const auto& require_key : import_data.used_keys) {1058                if (!require_key.second) continue; // Not a required key1059                if (pubkey_map.count(require_key.first) == 0 && privkey_map.count(require_key.first) == 0) {1060                    error = ""some required keys are missing"";1061                }1062            }1063        }1064 1065        if (!error.empty()) {1066            warnings.push_back(""Importing as non-solvable: "" + error + "". If this is intentional, don't provide any keys, pubkeys, witnessscript, or redeemscript."");1067            import_data = ImportData();1068            pubkey_map.clear();1069            privkey_map.clear();1070            have_solving_data = false;1071        } else {1072            // RecurseImportData() removes any relevant redeemscript/witnessscript from import_data, so we can use that to discover if a superfluous one was provided.1073            if (import_data.redeemscript) warnings.push_back(""Ignoring redeemscript as this is not a P2SH script."");1074            if (import_data.witnessscript) warnings.push_back(""Ignoring witnessscript as this is not a (P2SH-)P2WSH script."");1075            for (auto it = privkey_map.begin(); it != privkey_map.end(); ) {1076                auto oldit = it++;1077                if (import_data.used_keys.count(oldit->first) == 0) {1078                    warnings.push_back(""Ignoring irrelevant private key."");1079                    privkey_map.erase(oldit);1080                }1081            }1082            for (auto it = pubkey_map.begin(); it != pubkey_map.end(); ) {1083                auto oldit = it++;1084                auto key_data_it = import_data.used_keys.find(oldit->first);1085                if (key_data_it == import_data.used_keys.end() || !key_data_it->second) {1086                    warnings.push_back(""Ignoring public key \\"""" + HexStr(oldit->first) + ""\\"" as it doesn't appear inside P2PKH or P2WPKH."");1087                    pubkey_map.erase(oldit);1088                }1089            }1090        }1091    }1092 1093    return warnings;1094}1095 1096static UniValue ProcessImportDescriptor(ImportData& import_data, std::map<CKeyID, CPubKey>& pubkey_map, std::map<CKeyID, CKey>& privkey_map, std::set<CScript>& script_pub_keys, bool& have_solving_data, const UniValue& data, std::vector<CKeyID>& ordered_pubkeys)1097{1098    UniValue warnings(UniValue::VARR);1099 1100    const std::string& descriptor = data[""desc""].get_str();1101    FlatSigningProvider keys;1102    std::string error;1103    auto parsed_desc = Parse(descriptor, keys, error, /* require_checksum = */ true);1104    if (!parsed_desc) {1105        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error);1106    }1107 1108    have_solving_data = parsed_desc->IsSolvable();1109    const bool watch_only = data.exists(""watchonly"") ? data[""watchonly""].get_bool() : false;1110 1111    int64_t range_start = 0, range_end = 0;1112    if (!parsed_desc->IsRange() && data.exists(""range"")) {1113        throw JSONRPCError(RPC_INVALID_PARAMETER, ""Range should not be specified for an un-ranged descriptor"");1114    } else if (parsed_desc->IsRange()) {1115        if (!data.exists(""range"")) {1116            throw JSONRPCError(RPC_INVALID_PARAMETER, ""Descriptor is ranged, please specify the range"");1117        }1118        std::tie(range_start, range_end) = ParseDescriptorRange(data[""range""]);1119    }1120 1121    const UniValue& priv_keys = data.exists(""keys"") ? data[""keys""].get_array() : UniValue();1122 1123    // Expand all descriptors to get public keys and scripts, and private keys if available.1124    for (int i = range_start; i <= range_end; ++i) {1125        FlatSigningProvider out_keys;1126        std::vector<CScript> scripts_temp;1127        parsed_desc->Expand(i, keys, scripts_temp, out_keys);1128        std::copy(scripts_temp.begin(), scripts_temp.end(), std::inserter(script_pub_keys, script_pub_keys.end()));1129        for (const auto& key_pair : out_keys.pubkeys) {1130            ordered_pubkeys.push_back(key_pair.first);1131        }1132 1133        for (const auto& x : out_keys.scripts) {1134            import_data.import_scripts.emplace(x.second);1135        }1136 1137        parsed_desc->ExpandPrivate(i, keys, out_keys);1138 1139        std::copy(out_keys.pubkeys.begin(), out_keys.pubkeys.end(), std::inserter(pubkey_map, pubkey_map.end()));1140        std::copy(out_keys.keys.begin(), out_keys.keys.end(), std::inserter(privkey_map, privkey_map.end()));1141        import_data.key_origins.insert(out_keys.origins.begin(), out_keys.origins.end());1142    }1143 1144    for (size_t i = 0; i < priv_keys.size(); ++i) {1145        const auto& str = priv_keys[i].get_str();1146        CKey key = DecodeSecret(str);1147        if (!key.IsValid()) {1148            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, ""Invalid private key encoding"");1149        }1150        CPubKey pubkey = key.GetPubKey();1151        CKeyID id = pubkey.GetID();1152 1153        // Check if this private key corresponds to a public key from the descriptor1154        if (!pubkey_map.count(id)) {1155            warnings.push_back(""Ignoring irrelevant private key."");1156        } else {1157            privkey_map.emplace(id, key);1158        }1159    }1160 1161    // Check if all the public keys have corresponding private keys in the import for spendability.1162    // This does not take into account threshold multisigs which could be spendable without all keys.1163    // Thus, threshold multisigs without all keys will be considered not spendable here, even if they are,1164    // perhaps triggering a false warning message. This is consistent with the current wallet IsMine check.1165    bool spendable = std::all_of(pubkey_map.begin(), pubkey_map.end(),1166        [&](const std::pair<CKeyID, CPubKey>& used_key) {1167            return privkey_map.count(used_key.first) > 0;1168        }) && std::all_of(import_data.key_origins.begin(), import_data.key_origins.end(),1169        [&](const std::pair<CKeyID, std::pair<CPubKey, KeyOriginInfo>>& entry) {1170            return privkey_map.count(entry.first) > 0;1171        });1172    if (!watch_only && !spendable) {1173        warnings.push_back(""Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag."");1174    }1175    if (watch_only && spendable) {1176        warnings.push_back(""All private keys are provided, outputs will be considered spendable. If this is intentional, do not specify the watchonly flag."");1177    }1178 1179    return warnings;1180}1181 1182static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)1183{1184    UniValue warnings(UniValue::VARR);1185    UniValue result(UniValue::VOBJ);1186 1187    try {1188        const bool internal = data.exists(""internal"") ? data[""internal""].get_bool() : false;1189        // Internal addresses should not have a label1190        if (internal && data.exists(""label"")) {1191            throw JSONRPCError(RPC_INVALID_PARAMETER, ""Internal addresses should not have a label"");1192        }1193        const std::string& label = data.exists(""label"") ? data[""label""].get_str() : """";1194        const bool add_keypool = data.exists(""keypool"") ? data[""keypool""].get_bool() : false;1195 1196        // Add to keypool only works with privkeys disabled1197        if (add_keypool && !pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {1198            throw JSONRPCError(RPC_INVALID_PARAMETER, ""Keys can only be imported to the keypool when private keys are disabled"");1199        }1200 

Showing the first 1,200 of 85851 lines. Download the file for the rest.