Skip to content

Commit 1e20db4

Browse files
committed
Merge #85: Deal better with unknown amounts in balances
27d32fc Deal better with unknown amounts in balances (Pieter Wuille)
2 parents 574817b + 27d32fc commit 1e20db4

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

src/wallet.cpp

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,7 @@ CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
757757
const CWalletTx& prev = (*mi).second;
758758
if (txin.prevout.n < prev.vout.size())
759759
if (IsMine(prev.vout[txin.prevout.n]) & filter)
760-
return prev.GetValueOut(txin.prevout.n);
760+
return std::max<CAmount>(0, prev.GetValueOut(txin.prevout.n));
761761
}
762762
}
763763
return 0;
@@ -867,11 +867,21 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
867867
if (nDebit > 0) // debit>0 means we signed/sent this transaction
868868
nFee = nTxFee;
869869

870+
CTxDestination addressUnaccounted = CNoDestination();
871+
int voutUnaccounted = -1;
872+
CAmount nValueUnaccounted = nDebit - nFee;
873+
int nUnaccountedOutputs = 0;
874+
870875
// Sent/received.
871876
for (unsigned int i = 0; i < vout.size(); ++i)
872877
{
878+
CAmount nValueOut = GetValueOut(i);
879+
880+
if (nValueOut >= 0) {
881+
nValueUnaccounted -= nValueOut;
882+
}
873883
const CTxOut& txout = vout[i];
874-
isminetype fIsMine = pwallet->IsMine(txout);
884+
isminetype fIsMine = nValueOut >= 0 ? pwallet->IsMine(txout) : ISMINE_NO;
875885
// Only need to handle txouts if AT LEAST one of these is true:
876886
// 1) they debit from us (sent)
877887
// 2) the output is to us (received)
@@ -893,12 +903,18 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
893903
address = CNoDestination();
894904
}
895905

896-
COutputEntry output = {address, GetValueOut(i), (int)i, CPubKey()};
897-
898-
if (!txout.nValue.IsAmount() && GetValueOut(i) > 0) {
899-
output.confidentiality_pubkey = GetBlindingKey(i);
906+
if (nDebit > 0 && nValueOut < 0) {
907+
// This is an output we'd add to listSent, but we don't know its value.
908+
// Instead just remember its details so we can reconstruct it or
909+
// correct for it afterwards.
910+
addressUnaccounted = address;
911+
voutUnaccounted = i;
912+
nUnaccountedOutputs++;
913+
continue;
900914
}
901915

916+
COutputEntry output = {address, nValueOut, (int)i, GetBlindingKey(i)};
917+
902918
// If we are debited by the transaction, add the output as a "sent" entry
903919
if (nDebit > 0)
904920
listSent.push_back(output);
@@ -908,6 +924,17 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
908924
listReceived.push_back(output);
909925
}
910926

927+
if (nValueUnaccounted != 0 && nDebit > 0) {
928+
if (nValueUnaccounted > 0 && nUnaccountedOutputs == 1) {
929+
// There is exactly one sent output with unknown value. Reconstruct it.
930+
COutputEntry unaccounted = {addressUnaccounted, nValueUnaccounted, voutUnaccounted, CPubKey()};
931+
listSent.push_back(unaccounted);
932+
} else {
933+
// It's not simple. Create a synthetic unknown output entry to correct.
934+
COutputEntry unaccounted = {CNoDestination(), nValueUnaccounted, -1, CPubKey()};
935+
listSent.push_back(unaccounted);
936+
}
937+
}
911938
}
912939

913940
void CWalletTx::GetAccountAmounts(const string& strAccount, CAmount& nReceived,

0 commit comments

Comments
 (0)