Skip to content

client/asset: correct available and locked balance calculations#548

Merged
chappjc merged 3 commits into
decred:masterfrom
itswisdomagain:balance-report-correction
Aug 14, 2020
Merged

client/asset: correct available and locked balance calculations#548
chappjc merged 3 commits into
decred:masterfrom
itswisdomagain:balance-report-correction

Conversation

@itswisdomagain
Copy link
Copy Markdown
Member

@itswisdomagain itswisdomagain commented Jul 15, 2020

Recent testing with the simnet trade harness uncovered this bug with balance reporting.

  • Available balance should exclude locked balance.
  • Restrict locked balance for dcr to the configured account, to match available balance reporting that uses configured account's available balance rather than the entire wallet's available balance.

dcr wallet's listlockedunspent was previously found to sometimes return spent outputs, which causes the calculated locked balance amount to be higher than it actually is (see #453). This has been fixed in decred/dcrwallet#1753, ensuring that listlockedunspent only returns unspent outputs. Thus, the locked balance calculation in dcr.lockedAtoms() now fully relies on the results of the listlockedunspent cmd to determine locked unspent outputs, instead of cross-checking the returned results against the dcr.fundingCoins map and the gettxout rpc.

The confs arg is also removed from the dcr.fund method as it was pretty much made obsolete when the fundConf requirement was eliminated in #499. The method's doc is updated to indicate that utxos with 1+ confs are given preference when selecting new tx inputs, and unconfirmed utxos are included in the selection if confirmed utxos are insufficient.

Comment thread client/asset/dcr/dcr.go
Comment thread client/asset/dcr/dcr.go
@itswisdomagain itswisdomagain force-pushed the balance-report-correction branch from a27994b to a424c1c Compare August 7, 2020 01:07
@itswisdomagain itswisdomagain marked this pull request as draft August 7, 2020 01:09
@itswisdomagain itswisdomagain force-pushed the balance-report-correction branch from 67dc9f0 to 69dcbb3 Compare August 7, 2020 02:52
@itswisdomagain itswisdomagain marked this pull request as ready for review August 8, 2020 03:59
@itswisdomagain itswisdomagain changed the title client/asset: exclude locked amounts from Available balance client/asset: correct available and locked balance calculations Aug 8, 2020
Copy link
Copy Markdown
Member

@chappjc chappjc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good and tests well. But please squash and address the two review comments with notes in both the squashed commit message (where appropriate), and in the PR description.

Comment thread client/asset/dcr/dcr.go
Comment on lines -1436 to -1582
dcr.fundingMtx.Lock()
defer dcr.fundingMtx.Unlock()
for _, outPoint := range lockedOutpoints {
opID := outpointID(&outPoint.Hash, outPoint.Index)
utxo, found := dcr.fundingCoins[opID]
if found {
sum += utxo.op.value
continue
}
txOut, err := dcr.node.GetTxOut(&outPoint.Hash, outPoint.Index, true)
if err != nil {
return 0, err
}
if txOut == nil {
// Must be spent now?
dcr.log.Debugf("ignoring output from listlockunspent that wasn't found with gettxout. %s", opID)
continue
Copy link
Copy Markdown
Member

@chappjc chappjc Aug 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was a dcrwallet fix that fixed this issue, making this gettxout check no longer necessary, correct? Can you please call that out in github comments and a commit message to justify change? Just note that git commit messages may refer to commit hashes, but not github links.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. Went back to review the related discussion in #471 and #453 and maybe I should bring back the gettxout check, especially because of your last comment on 471.

It seems dcrwallet's listlockunspent still returns coins that are already spent, although that should have been fixed. If that's the case, calling gettxout for each coin returned from listlockunspent helps to prevent including a spent output in the locked balance calculation.

Worth noting again though, especially as per this comment on 453, gettxout may not identify spent outputs if the spending tx is still in mempool, so even with gettxout, we might still have cases where listlockunspent returns a spent output and gettxout does not call this out. If gettxout does return nil for such output, we'd know it's spent and ignore it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I no longer see the issue in #471. Has been a while actually.

@buck54321 may need to weight in here as the new logSplitFunds probably enters into this.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fixed via decred/dcrwallet#1753, but I'm nervous about a regression. Let's go with it as-is here and see if we run into any trouble

Comment thread client/asset/dcr/dcr.go Outdated
Comment thread client/asset/dcr/dcr.go Outdated
Also, remove the now-obsolete `confs` arg from the `dcr.fund` method.
Can be restored later if necessary, but the fundConf requirement was
retired in commit 5d54e9d, allowing
0-conf utxos to be selected in funding transactions.
dcrwallet's listlockedunspent was previously found to sometimes
return spent outputs, which causes the calculated locked balance
amount to be higher than it actually is. This has been fixed upstream
in 57a9016623fbf5033a7dffd748b63d44218529ba, ensuring that
listlockedunspent only returns unspent outputs. Thus, the locked
balance calculation in dcr.lockedAtoms() now fully relies on the results
of the listlockedunspent cmd to determine locked unspent outputs,
instead of cross-checking the returned results against the gettxout rpc.
@itswisdomagain itswisdomagain force-pushed the balance-report-correction branch from 69dcbb3 to defe372 Compare August 14, 2020 09:43
@chappjc chappjc merged commit ba97a44 into decred:master Aug 14, 2020
@itswisdomagain itswisdomagain deleted the balance-report-correction branch August 14, 2020 15:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants