Skip to content

Commit

Permalink
wallet: Avoid dropping confirmed coins
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcoFalke committed Jan 25, 2022
1 parent 888841e commit fa272ea
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 10 deletions.
2 changes: 0 additions & 2 deletions src/wallet/receive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,6 @@ bool CachedTxIsFromMe(const CWallet& wallet, const CWalletTx& wtx, const isminef
bool CachedTxIsTrusted(const CWallet& wallet, const CWalletTx& wtx, std::set<uint256>& trusted_parents)
{
AssertLockHeld(wallet.cs_wallet);
// Quick answer in most cases
if (!wallet.chain().checkFinalTx(*wtx.tx)) return false;
int nDepth = wallet.GetTxDepthInMainChain(wtx);
if (nDepth >= 1) return true;
if (nDepth < 0) return false;
Expand Down
4 changes: 2 additions & 2 deletions src/wallet/rpc/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool b
if (depth < min_depth
// Coinbase with less than 1 confirmation is no longer in the main chain
|| (wtx.IsCoinBase() && (depth < 1 || !include_coinbase))
|| (wallet.IsTxImmatureCoinBase(wtx) && !include_immature_coinbase)
|| !wallet.chain().checkFinalTx(*wtx.tx)) {
|| (wallet.IsTxImmatureCoinBase(wtx) && !include_immature_coinbase))
{
continue;
}

Expand Down
4 changes: 2 additions & 2 deletions src/wallet/rpc/transactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ static UniValue ListReceived(const CWallet& wallet, const UniValue& params, cons

// Coinbase with less than 1 confirmation is no longer in the main chain
if ((wtx.IsCoinBase() && (nDepth < 1 || !include_coinbase))
|| (wallet.IsTxImmatureCoinBase(wtx) && !include_immature_coinbase)
|| !wallet.chain().checkFinalTx(*wtx.tx)) {
|| (wallet.IsTxImmatureCoinBase(wtx) && !include_immature_coinbase))
{
continue;
}

Expand Down
4 changes: 0 additions & 4 deletions src/wallet/spend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,6 @@ void AvailableCoins(const CWallet& wallet, std::vector<COutput>& vCoins, const C
const uint256& wtxid = entry.first;
const CWalletTx& wtx = entry.second;

if (!wallet.chain().checkFinalTx(*wtx.tx)) {
continue;
}

if (wallet.IsTxImmatureCoinBase(wtx))
continue;

Expand Down
1 change: 1 addition & 0 deletions test/functional/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@
'feature_coinstatsindex.py --legacy-wallet',
'feature_coinstatsindex.py --descriptors',
'wallet_orphanedreward.py',
'wallet_timelock.py',
'p2p_node_network_limited.py',
'p2p_permissions.py',
'feature_blocksdir.py',
Expand Down
50 changes: 50 additions & 0 deletions test/functional/wallet_timelock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env python3
# Copyright (c) 2022 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal


class WalletLocktimeTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1

def skip_test_if_missing_module(self):
self.skip_if_no_wallet()

def run_test(self):
node = self.nodes[0]

mtp_tip = node.getblockheader(node.getbestblockhash())["mediantime"]

self.log.info("Get new address with label")
label = "timelock⌛🔓"
address = node.getnewaddress(label=label)

self.log.info("Send to new address with locktime")
node.send(
outputs={address: 5},
options={"locktime": mtp_tip - 1},
)
self.generate(node, 1)

self.log.info("Check that clock can not change finality of confirmed txs")
amount_before_ad = node.getreceivedbyaddress(address)
amount_before_lb = node.getreceivedbylabel(label)
list_before_ad = node.listreceivedbyaddress(address_filter=address)
list_before_lb = node.listreceivedbylabel(include_empty=False)
balance_before = node.getbalances()["mine"]["trusted"]
coin_before = node.listunspent(maxconf=1)
node.setmocktime(mtp_tip - 1)
assert_equal(node.getreceivedbyaddress(address), amount_before_ad)
assert_equal(node.getreceivedbylabel(label), amount_before_lb)
assert_equal(node.listreceivedbyaddress(address_filter=address), list_before_ad)
assert_equal(node.listreceivedbylabel(include_empty=False), list_before_lb)
assert_equal(node.getbalances()["mine"]["trusted"], balance_before)
assert_equal(node.listunspent(maxconf=1), coin_before)


if __name__ == "__main__":
WalletLocktimeTest().main()

0 comments on commit fa272ea

Please sign in to comment.