~ubuntu-branches/debian/stretch/bitcoin/stretch

« back to all changes in this revision

Viewing changes to src/wallet/rpcdump.cpp

  • Committer: Package Import Robot
  • Author(s): Anthony Towns
  • Date: 2016-10-21 17:13:13 UTC
  • mfrom: (1.3.2)
  • Revision ID: package-import@ubuntu.com-20161021171313-7eu2ltpbk0xag3q1
Tags: 0.13.0-0.1
* Non-maintainer upload.
* New upstream release.
* Allow compilation with gcc/g++ 6. (Closes: Bug#835963)
* Additional fixes for openssl 1.1 compatibility. (See Bug#828248)
* Check if -latomic is needed (it is on mips*).
* Remove reproducible build patch, since leveldb build system is
  no longer used in 0.13. (See Bug#791834)
* Update description since the blockchain is much more than "several GB"
  now. (Closes: Bug#835809)

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 
5
5
#include "base58.h"
6
6
#include "chain.h"
7
 
#include "rpcserver.h"
 
7
#include "rpc/server.h"
8
8
#include "init.h"
9
9
#include "main.h"
10
10
#include "script/script.h"
13
13
#include "util.h"
14
14
#include "utiltime.h"
15
15
#include "wallet.h"
 
16
#include "merkleblock.h"
 
17
#include "core_io.h"
16
18
 
17
19
#include <fstream>
18
20
#include <stdint.h>
165
167
        if (!pwalletMain->HaveCScript(script) && !pwalletMain->AddCScript(script))
166
168
            throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet");
167
169
        ImportAddress(CBitcoinAddress(CScriptID(script)), strLabel);
 
170
    } else {
 
171
        CTxDestination destination;
 
172
        if (ExtractDestination(script, destination)) {
 
173
            pwalletMain->SetAddressBook(destination, strLabel, "receive");
 
174
        }
168
175
    }
169
176
}
170
177
 
192
199
            "3. rescan               (boolean, optional, default=true) Rescan the wallet for transactions\n"
193
200
            "4. p2sh                 (boolean, optional, default=false) Add the P2SH version of the script as well\n"
194
201
            "\nNote: This call can take minutes to complete if rescan is true.\n"
195
 
            "If you have the full public key, you should call importpublickey instead of this.\n"
 
202
            "If you have the full public key, you should call importpubkey instead of this.\n"
 
203
            "\nNote: If you import a non-standard raw script in hex form, outputs sending to it will be treated\n"
 
204
            "as change, and not show up in many RPCs.\n"
196
205
            "\nExamples:\n"
197
206
            "\nImport a script with rescan\n"
198
207
            + HelpExampleCli("importaddress", "\"myscript\"") +
243
252
    return NullUniValue;
244
253
}
245
254
 
 
255
UniValue importprunedfunds(const UniValue& params, bool fHelp)
 
256
{
 
257
    if (!EnsureWalletIsAvailable(fHelp))
 
258
        return NullUniValue;
 
259
 
 
260
    if (fHelp || params.size() < 2 || params.size() > 3)
 
261
        throw runtime_error(
 
262
            "importprunedfunds\n"
 
263
            "\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"
 
264
            "\nArguments:\n"
 
265
            "1. \"rawtransaction\" (string, required) A raw transaction in hex funding an already-existing address in wallet\n"
 
266
            "2. \"txoutproof\"     (string, required) The hex output from gettxoutproof that contains the transaction\n"
 
267
            "3. \"label\"          (string, optional) An optional label\n"
 
268
        );
 
269
 
 
270
    CTransaction tx;
 
271
    if (!DecodeHexTx(tx, params[0].get_str()))
 
272
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
 
273
    uint256 hashTx = tx.GetHash();
 
274
    CWalletTx wtx(pwalletMain,tx);
 
275
 
 
276
    CDataStream ssMB(ParseHexV(params[1], "proof"), SER_NETWORK, PROTOCOL_VERSION);
 
277
    CMerkleBlock merkleBlock;
 
278
    ssMB >> merkleBlock;
 
279
 
 
280
    string strLabel = "";
 
281
    if (params.size() == 3)
 
282
        strLabel = params[2].get_str();
 
283
 
 
284
    //Search partial merkle tree in proof for our transaction and index in valid block
 
285
    vector<uint256> vMatch;
 
286
    vector<unsigned int> vIndex;
 
287
    unsigned int txnIndex = 0;
 
288
    if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) == merkleBlock.header.hashMerkleRoot) {
 
289
 
 
290
        LOCK(cs_main);
 
291
 
 
292
        if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()]))
 
293
            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
 
294
 
 
295
        vector<uint256>::const_iterator it;
 
296
        if ((it = std::find(vMatch.begin(), vMatch.end(), hashTx))==vMatch.end()) {
 
297
            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction given doesn't exist in proof");
 
298
        }
 
299
 
 
300
        txnIndex = vIndex[it - vMatch.begin()];
 
301
    }
 
302
    else {
 
303
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Something wrong with merkleblock");
 
304
    }
 
305
 
 
306
    wtx.nIndex = txnIndex;
 
307
    wtx.hashBlock = merkleBlock.header.GetHash();
 
308
 
 
309
    LOCK2(cs_main, pwalletMain->cs_wallet);
 
310
 
 
311
    if (pwalletMain->IsMine(tx)) {
 
312
        CWalletDB walletdb(pwalletMain->strWalletFile, "r+", false);
 
313
        pwalletMain->AddToWallet(wtx, false, &walletdb);
 
314
        return NullUniValue;
 
315
    }
 
316
 
 
317
    throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No addresses in wallet correspond to included transaction");
 
318
}
 
319
 
 
320
UniValue removeprunedfunds(const UniValue& params, bool fHelp)
 
321
{
 
322
    if (!EnsureWalletIsAvailable(fHelp))
 
323
        return NullUniValue;
 
324
 
 
325
    if (fHelp || params.size() != 1)
 
326
        throw runtime_error(
 
327
            "removeprunedfunds \"txid\"\n"
 
328
            "\nDeletes the specified transaction from the wallet. Meant for use with pruned wallets and as a companion to importprunedfunds. This will effect wallet balances.\n"
 
329
            "\nArguments:\n"
 
330
            "1. \"txid\"           (string, required) The hex-encoded id of the transaction you are deleting\n"
 
331
            "\nExamples:\n"
 
332
            + HelpExampleCli("removeprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"") +
 
333
            "\nAs a JSON-RPC call\n"
 
334
            + HelpExampleRpc("removprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"")
 
335
        );
 
336
 
 
337
    LOCK2(cs_main, pwalletMain->cs_wallet);
 
338
 
 
339
    uint256 hash;
 
340
    hash.SetHex(params[0].get_str());
 
341
    vector<uint256> vHash;
 
342
    vHash.push_back(hash);
 
343
    vector<uint256> vHashOut;
 
344
 
 
345
    if(pwalletMain->ZapSelectTx(vHash, vHashOut) != DB_LOAD_OK) {
 
346
        throw JSONRPCError(RPC_INTERNAL_ERROR, "Could not properly delete the transaction.");
 
347
    }
 
348
 
 
349
    if(vHashOut.empty()) {
 
350
        throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction does not exist in wallet.");
 
351
    }
 
352
 
 
353
    ThreadFlushWalletDB(pwalletMain->strWalletFile);
 
354
 
 
355
    return NullUniValue;
 
356
}
 
357
 
246
358
UniValue importpubkey(const UniValue& params, bool fHelp)
247
359
{
248
360
    if (!EnsureWalletIsAvailable(fHelp))
485
597
    std::sort(vKeyBirth.begin(), vKeyBirth.end());
486
598
 
487
599
    // produce output
488
 
    file << strprintf("# Wallet dump created by Bitcoin %s (%s)\n", CLIENT_BUILD, CLIENT_DATE);
 
600
    file << strprintf("# Wallet dump created by Bitcoin %s\n", CLIENT_BUILD);
489
601
    file << strprintf("# * Created on %s\n", EncodeDumpTime(GetTime()));
490
602
    file << strprintf("# * Best block at time of backup was %i (%s),\n", chainActive.Height(), chainActive.Tip()->GetBlockHash().ToString());
491
603
    file << strprintf("#   mined on %s\n", EncodeDumpTime(chainActive.Tip()->GetBlockTime()));
492
604
    file << "\n";
 
605
 
 
606
    // add the base58check encoded extended master if the wallet uses HD 
 
607
    CKeyID masterKeyID = pwalletMain->GetHDChain().masterKeyID;
 
608
    if (!masterKeyID.IsNull())
 
609
    {
 
610
        CKey key;
 
611
        if (pwalletMain->GetKey(masterKeyID, key))
 
612
        {
 
613
            CExtKey masterKey;
 
614
            masterKey.SetMaster(key.begin(), key.size());
 
615
 
 
616
            CBitcoinExtKey b58extkey;
 
617
            b58extkey.SetKey(masterKey);
 
618
 
 
619
            file << "# extended private masterkey: " << b58extkey.ToString() << "\n\n";
 
620
        }
 
621
    }
493
622
    for (std::vector<std::pair<int64_t, CKeyID> >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) {
494
623
        const CKeyID &keyid = it->second;
495
624
        std::string strTime = EncodeDumpTime(it->first);
496
625
        std::string strAddr = CBitcoinAddress(keyid).ToString();
497
626
        CKey key;
498
627
        if (pwalletMain->GetKey(keyid, key)) {
 
628
            file << strprintf("%s %s ", CBitcoinSecret(key).ToString(), strTime);
499
629
            if (pwalletMain->mapAddressBook.count(keyid)) {
500
 
                file << strprintf("%s %s label=%s # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, EncodeDumpString(pwalletMain->mapAddressBook[keyid].name), strAddr);
 
630
                file << strprintf("label=%s", EncodeDumpString(pwalletMain->mapAddressBook[keyid].name));
 
631
            } else if (keyid == masterKeyID) {
 
632
                file << "hdmaster=1";
501
633
            } else if (setKeyPool.count(keyid)) {
502
 
                file << strprintf("%s %s reserve=1 # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, strAddr);
 
634
                file << "reserve=1";
 
635
            } else if (pwalletMain->mapKeyMetadata[keyid].hdKeypath == "m") {
 
636
                file << "inactivehdmaster=1";
503
637
            } else {
504
 
                file << strprintf("%s %s change=1 # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, strAddr);
 
638
                file << "change=1";
505
639
            }
 
640
            file << strprintf(" # addr=%s%s\n", strAddr, (pwalletMain->mapKeyMetadata[keyid].hdKeypath.size() > 0 ? " hdkeypath="+pwalletMain->mapKeyMetadata[keyid].hdKeypath : ""));
506
641
        }
507
642
    }
508
643
    file << "\n";