From 386de78bcbcaee6db11909ced9e00898d8dba20e Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Fri, 23 Aug 2019 21:02:33 +0300 Subject: [PATCH] Fix SelectCoinsMinConf to allow instant respends (#3061) * Modify tests to check for instant respends This should fail atm... * Fix SelectCoinsMinConf to allow instant respends Now tests should pass again. --- src/wallet/wallet.cpp | 8 ++++++-- test/functional/p2p-instantsend.py | 6 ++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index a2b8f5ba7b..edfaaa41d3 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2895,6 +2895,8 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const int nConfMin std::sort(vCoins.begin(), vCoins.end(), less_then_denom); } + int nMaxChainLength = std::min(gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT), gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT)); + // try to find nondenom first to prevent unneeded spending of mixed coins for (unsigned int tryDenom = tryDenomStart; tryDenom < 2; tryDenom++) { @@ -2908,11 +2910,13 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const int nConfMin const CWalletTx *pcoin = output.tx; + bool fLockedByIS = pcoin->IsLockedByInstantSend(); + // if (logCategories != BCLog::NONE) LogPrint(BCLog::SELECTCOINS, "value %s confirms %d\n", FormatMoney(pcoin->vout[output.i].nValue), output.nDepth); - if (output.nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs)) + if (output.nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs) && !fLockedByIS) continue; - if (!mempool.TransactionWithinChainLimit(pcoin->GetHash(), nMaxAncestors)) + if (!mempool.TransactionWithinChainLimit(pcoin->GetHash(), fLockedByIS ? nMaxChainLength : nMaxAncestors)) continue; int i = output.i; diff --git a/test/functional/p2p-instantsend.py b/test/functional/p2p-instantsend.py index eef56ade48..ef8488d48d 100755 --- a/test/functional/p2p-instantsend.py +++ b/test/functional/p2p-instantsend.py @@ -71,6 +71,9 @@ class InstantSendTest(DashTestFramework): assert (res['hash'] != wrong_block) # wait for long time only for first node timeout = 1 + # send coins back to the controller node without waiting for confirmations + receiver.sendtoaddress(self.nodes[0].getnewaddress(), 0.9, "", "", True) + assert_equal(receiver.getwalletinfo()["balance"], 0) # mine more blocks # TODO: mine these blocks on an isolated node self.bump_mocktime(1) @@ -109,6 +112,9 @@ class InstantSendTest(DashTestFramework): for node in self.nodes: self.wait_for_instantlock(is_id, node) assert_raises_jsonrpc(-5, "No such mempool or blockchain transaction", isolated.getrawtransaction, dblspnd_txid) + # send coins back to the controller node without waiting for confirmations + receiver.sendtoaddress(self.nodes[0].getnewaddress(), 0.9, "", "", True) + assert_equal(receiver.getwalletinfo()["balance"], 0) if __name__ == '__main__': InstantSendTest().main()