diff options
Diffstat (limited to 'src/wallet/rpcdump.cpp')
-rw-r--r-- | src/wallet/rpcdump.cpp | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 6e50f92428..899ed1b3d7 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -13,6 +13,8 @@ #include "util.h" #include "utiltime.h" #include "wallet.h" +#include "merkleblock.h" +#include "core_io.h" #include <fstream> #include <stdint.h> @@ -243,6 +245,71 @@ UniValue importaddress(const UniValue& params, bool fHelp) return NullUniValue; } +UniValue importprunedfunds(const UniValue& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() < 2 || params.size() > 3) + throw runtime_error( + "importprunedfunds\n" + "\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" + "\nArguments:\n" + "1. \"rawtransaction\" (string, required) A raw transaction in hex funding an already-existing address in wallet\n" + "2. \"txoutproof\" (string, required) The hex output from gettxoutproof that contains the transaction\n" + "3. \"label\" (string, optional) An optional label\n" + ); + + CTransaction tx; + if (!DecodeHexTx(tx, params[0].get_str())) + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); + uint256 hashTx = tx.GetHash(); + CWalletTx wtx(pwalletMain,tx); + + CDataStream ssMB(ParseHexV(params[1], "proof"), SER_NETWORK, PROTOCOL_VERSION); + CMerkleBlock merkleBlock; + ssMB >> merkleBlock; + + string strLabel = ""; + if (params.size() == 3) + strLabel = params[2].get_str(); + + //Search partial merkle tree in proof for our transaction and index in valid block + vector<uint256> vMatch; + vector<unsigned int> vIndex; + unsigned int txnIndex = 0; + if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) == merkleBlock.header.hashMerkleRoot) { + + LOCK(cs_main); + + if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()])) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain"); + + vector<uint256>::const_iterator it; + if ((it = std::find(vMatch.begin(), vMatch.end(), hashTx))==vMatch.end()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction given doesn't exist in proof"); + } + + txnIndex = vIndex[it - vMatch.begin()]; + } + else { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Something wrong with merkleblock"); + } + + wtx.nIndex = txnIndex; + wtx.hashBlock = merkleBlock.header.GetHash(); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + if (pwalletMain->IsMine(tx)) { + CWalletDB walletdb(pwalletMain->strWalletFile, "r+", false); + pwalletMain->AddToWallet(wtx, false, &walletdb); + return NullUniValue; + } + + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No addresses in wallet correspond to included transaction"); +} + UniValue importpubkey(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) |