Skip to content

Commit f1bb13c

Browse files
committed
Added companion removeprunedfunds call.
1 parent 7eb7029 commit f1bb13c

File tree

7 files changed

+127
-0
lines changed

7 files changed

+127
-0
lines changed

qa/rpc-tests/importprunedfunds.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,5 +115,26 @@ def run_test (self):
115115
assert_equal(address_info['iswatchonly'], False)
116116
assert_equal(address_info['ismine'], True)
117117

118+
#Remove transactions
119+
120+
try:
121+
self.nodes[1].removeprunedfunds(txnid1)
122+
except JSONRPCException,e:
123+
errorString = e.error['message']
124+
125+
assert('does not exist' in errorString)
126+
127+
balance1 = Decimal(self.nodes[1].getbalance("", 0, True))
128+
assert_equal(balance1, Decimal('0.075'))
129+
130+
131+
self.nodes[1].removeprunedfunds(txnid2)
132+
balance2 = Decimal(self.nodes[1].getbalance("", 0, True))
133+
assert_equal(balance2, Decimal('0.025'))
134+
135+
self.nodes[1].removeprunedfunds(txnid3)
136+
balance3 = Decimal(self.nodes[1].getbalance("", 0, True))
137+
assert_equal(balance3, Decimal('0.0'))
138+
118139
if __name__ == '__main__':
119140
ImportPrunedFundsTest ().main ()

src/wallet/rpcdump.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,44 @@ UniValue importprunedfunds(const UniValue& params, bool fHelp)
310310
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No addresses in wallet correspond to included transaction");
311311
}
312312

313+
UniValue removeprunedfunds(const UniValue& params, bool fHelp)
314+
{
315+
if (!EnsureWalletIsAvailable(fHelp))
316+
return NullUniValue;
317+
318+
if (fHelp || params.size() != 1)
319+
throw runtime_error(
320+
"removeprunedfunds \"txid\"\n"
321+
"\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"
322+
"\nArguments:\n"
323+
"1. \"txid\" (string, required) The hex-encoded id of the transaction you are deleting\n"
324+
"\nExamples:\n"
325+
+ HelpExampleCli("removeprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"") +
326+
"\nAs a JSON-RPC call\n"
327+
+ HelpExampleRpc("removprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"")
328+
);
329+
330+
LOCK2(cs_main, pwalletMain->cs_wallet);
331+
332+
uint256 hash;
333+
hash.SetHex(params[0].get_str());
334+
vector<uint256> vHash;
335+
vHash.push_back(hash);
336+
vector<uint256> vHashOut;
337+
338+
if(pwalletMain->ZapSelectTx(vHash, vHashOut) != DB_LOAD_OK) {
339+
throw JSONRPCError(RPC_INTERNAL_ERROR, "Could not properly delete the transaction.");
340+
}
341+
342+
if(vHashOut.empty()) {
343+
throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction does not exist in wallet.");
344+
}
345+
346+
ThreadFlushWalletDB(pwalletMain->strWalletFile);
347+
348+
return NullUniValue;
349+
}
350+
313351
UniValue importpubkey(const UniValue& params, bool fHelp)
314352
{
315353
if (!EnsureWalletIsAvailable(fHelp))

src/wallet/rpcwallet.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2504,6 +2504,7 @@ extern UniValue importpubkey(const UniValue& params, bool fHelp);
25042504
extern UniValue dumpwallet(const UniValue& params, bool fHelp);
25052505
extern UniValue importwallet(const UniValue& params, bool fHelp);
25062506
extern UniValue importprunedfunds(const UniValue& params, bool fHelp);
2507+
extern UniValue removeprunedfunds(const UniValue& params, bool fHelp);
25072508

25082509
const CRPCCommand vWalletRPCCommands[] =
25092510
{ // category name actor (function) okSafeMode
@@ -2552,6 +2553,7 @@ const CRPCCommand vWalletRPCCommands[] =
25522553
{ "wallet", "walletlock", &walletlock, true },
25532554
{ "wallet", "walletpassphrasechange", &walletpassphrasechange, true },
25542555
{ "wallet", "walletpassphrase", &walletpassphrase, true },
2556+
{ "wallet", "removeprunedfunds", &removeprunedfunds, true },
25552557
};
25562558

25572559
void walletRegisterRPCCommands()

src/wallet/wallet.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2362,6 +2362,31 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
23622362
return DB_LOAD_OK;
23632363
}
23642364

2365+
DBErrors CWallet::ZapSelectTx(vector<uint256>& vHashIn, vector<uint256>& vHashOut)
2366+
{
2367+
if (!fFileBacked)
2368+
return DB_LOAD_OK;
2369+
DBErrors nZapSelectTxRet = CWalletDB(strWalletFile,"cr+").ZapSelectTx(this, vHashIn, vHashOut);
2370+
if (nZapSelectTxRet == DB_NEED_REWRITE)
2371+
{
2372+
if (CDB::Rewrite(strWalletFile, "\x04pool"))
2373+
{
2374+
LOCK(cs_wallet);
2375+
setKeyPool.clear();
2376+
// Note: can't top-up keypool here, because wallet is locked.
2377+
// User will be prompted to unlock wallet the next operation
2378+
// that requires a new key.
2379+
}
2380+
}
2381+
2382+
if (nZapSelectTxRet != DB_LOAD_OK)
2383+
return nZapSelectTxRet;
2384+
2385+
MarkDirty();
2386+
2387+
return DB_LOAD_OK;
2388+
2389+
}
23652390

23662391
DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
23672392
{

src/wallet/wallet.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
792792

793793
DBErrors LoadWallet(bool& fFirstRunRet);
794794
DBErrors ZapWalletTx(std::vector<CWalletTx>& vWtx);
795+
DBErrors ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut);
795796

796797
bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& purpose);
797798

src/wallet/walletdb.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,45 @@ DBErrors CWalletDB::FindWalletTx(CWallet* pwallet, vector<uint256>& vTxHash, vec
785785
return result;
786786
}
787787

788+
DBErrors CWalletDB::ZapSelectTx(CWallet* pwallet, vector<uint256>& vTxHashIn, vector<uint256>& vTxHashOut)
789+
{
790+
// build list of wallet TXs and hashes
791+
vector<uint256> vTxHash;
792+
vector<CWalletTx> vWtx;
793+
DBErrors err = FindWalletTx(pwallet, vTxHash, vWtx);
794+
if (err != DB_LOAD_OK) {
795+
return err;
796+
}
797+
798+
std::sort(vTxHash.begin(), vTxHash.end());
799+
std::sort(vTxHashIn.begin(), vTxHashIn.end());
800+
801+
// erase each matching wallet TX
802+
bool delerror = false;
803+
vector<uint256>::iterator it = vTxHashIn.begin();
804+
BOOST_FOREACH (uint256 hash, vTxHash) {
805+
while (it < vTxHashIn.end() && (*it) < hash) {
806+
it++;
807+
}
808+
if (it == vTxHashIn.end()) {
809+
break;
810+
}
811+
else if ((*it) == hash) {
812+
pwallet->mapWallet.erase(hash);
813+
if(!EraseTx(hash)) {
814+
LogPrint("db", "Transaction was found for deletion but returned database error: %s\n", hash.GetHex());
815+
delerror = true;
816+
}
817+
vTxHashOut.push_back(hash);
818+
}
819+
}
820+
821+
if (delerror) {
822+
return DB_CORRUPT;
823+
}
824+
return DB_LOAD_OK;
825+
}
826+
788827
DBErrors CWalletDB::ZapWalletTx(CWallet* pwallet, vector<CWalletTx>& vWtx)
789828
{
790829
// build list of wallet TXs

src/wallet/walletdb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ class CWalletDB : public CDB
130130
DBErrors LoadWallet(CWallet* pwallet);
131131
DBErrors FindWalletTx(CWallet* pwallet, std::vector<uint256>& vTxHash, std::vector<CWalletTx>& vWtx);
132132
DBErrors ZapWalletTx(CWallet* pwallet, std::vector<CWalletTx>& vWtx);
133+
DBErrors ZapSelectTx(CWallet* pwallet, std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut);
133134
static bool Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKeys);
134135
static bool Recover(CDBEnv& dbenv, const std::string& filename);
135136

0 commit comments

Comments
 (0)