Fix getbalance handling of spent, unconfirmed change #3661

pull gavinandresen wants to merge 2 commits into bitcoin:master from gavinandresen:getbalance_fix changing 9 files +203 −10
  1. gavinandresen commented at 6:55 PM on February 12, 2014: contributor

    First: txnmall.sh is the start of an integration test for wallet handling of mutated (malleable) transaction handling.

    Second is a one-line change to IsConfirmed that adds a condition when considering change outputs : only consider them confirmed if they are in the memory pool (inspired by a comment sipa made yesterday).

    This makes getbalance, getbalance '*', and listunspent all agree when run on the txnmall.sh test wallets. Before this fix, those three would return three different results.

    Before: listunspent: one 49BTC output getbalance: 96 BTC (change counted twice) getbalance '*': 46 BTC (spends counted twice)

    After: all agree, 49 BTC available to spend.

  2. gavinandresen commented at 8:15 PM on February 12, 2014: contributor

    Can you fix all of the bash nits in qa/rpc-tests/wallet.sh, test with directories with spaces/etc. and submit a pull request for that? I based the txnmall.sh code on wallet.sh, and, frankly, making it work if you've got a wacky directory hierarchy is not high on my TODO list.

  3. b6393ce9-d324-4fe1-996b-acf82dbc3d53 commented at 8:19 PM on February 12, 2014: none

    Sorry, I didn't realize line comments would become so obtrusive; I'll remove them presently.

    That being said, there is a real danger here, particularly with your EXIT trap.

  4. laanwj commented at 8:24 PM on February 12, 2014: member

    Agree with @gavinandresen, perfecting the hacky test script is not the first priority. Feel free to do this in a separate pull though!

    The focus of testing and review should be the change in wallet.h here.

    Edit: @b6393ce9-d324-4fe1-996b-acf82dbc3d53 the rm -rf in the EXIT trap can indeed lead to problems if you have a datadir with a space in it, it's could be dangerous if it results in a recursive remove of the wrong directory. Putting "$D" there would be wise precaution :)

  5. b6393ce9-d324-4fe1-996b-acf82dbc3d53 commented at 10:21 PM on February 12, 2014: none

    I'm uncomfortable with considering as "confirmed" what we are all already acknowledging as "unconfirmed" transactions.

    What the Bitcoin world has come to understand recently is that even a transaction created by a trusted party—namely by yourself—is not necessarily ever going to get into the blockchain; thus, it's fairly risky to base any calculation on any transaction that is not already buried in the blockchain.

    More to the point of this commit, though: Your "confirmed" balance is meaningless unless you can spend that value, and yet that value cannot be spent unless the Bitcoin network—yes, the third-party payment processor—says you can spend it; your personal, individual client really has very little say in the matter, a point that is compounded by mutable (malleable) transactions.

    So, I don't think either CWalletTx::IsConfirmed() or the balance of confirmed value is the proper place to be accounting for unconfirmed change. These issues need to be handled altogether differently.

  6. sipa commented at 10:33 PM on February 12, 2014: member

    That's a confusion that afaik as existed forever in the source code: IsConfirmed should be called IsTrusted or something instead (it means confirmed OR from ourselves).

  7. b6393ce9-d324-4fe1-996b-acf82dbc3d53 commented at 1:43 AM on February 13, 2014: none

    But the larger point is that a transaction from oneself cannot actually be trusted; due to transaction mutability, any source other than the blockchain itself is irrelevant (for various degrees of risk aversion). So, this is not just a question of naming; it's a question of real risk.

    When you think about it, you cannot be terribly miffed about this larger point, because that's all Bitcoin ever proffered, anyway: "Data buried in the blockchain is what can be trusted." It's better to work with that reality rather than against it.

  8. Make qa/rpc-tests/ compatible with OSX
    Reworked send.sh, so it works properly on my Mac (killall send.sh
    doesn't work, because the process name is 'bash' not 'send.sh').
    So now send.sh writes a .send.pid file, and invoking it as
    send.sh -STOP (as the bitcoind -walletnotify) signals that PID.
    b7b8fd5d31
  9. BitcoinPullTester commented at 4:45 PM on February 13, 2014: none

    Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/efd8eb3f371369914a84d489ec86873cbc327285 for binaries and test log. This test script verifies pulls every time they are updated. It, however, dies sometimes and fails to test properly. If you are waiting on a test, please check timestamps to verify that the test.log is moving at http://jenkins.bluematt.me/pull-tester/current/ Contact BlueMatt on freenode if something looks broken.

  10. Handle "dead" transactions properly
    Extend CMerkleTx::GetDepthInMainChain with the concept of
    a "dead" transaction-- a transaction generated by the wallet
    that is not in the main chain or in the mempool, and, therefore,
    will likely never be confirmed.
    
    GetDepthInMainChain() now returns -1 for dead transactions
    (0 for unconfirmed-but-in-the-mempool, and >1 for confirmed).
    
    This makes getbalance, getbalance '*', and listunspent all agree when there are
    mutated transactions in the wallet.
    
    Before:
     listunspent: one 49BTC output
     getbalance: 96 BTC (change counted twice)
     getbalance '*': 46 BTC (spends counted twice)
    
    After: all agree, 49 BTC available to spend.
    f0898f67b5
  11. gavinandresen commented at 5:32 PM on February 13, 2014: contributor

    Replaced with a deeper level fix (make GetDepthInMainChain() return -1 for transactions that are unconfirmed and no longer in the memory pool).

  12. gavinandresen closed this on Feb 13, 2014

  13. gavinandresen deleted the branch on Mar 13, 2014
  14. DrahtBot locked this on Sep 8, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-15 15:15 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me