@@ -757,7 +757,7 @@ CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
757
757
const CWalletTx& prev = (*mi).second ;
758
758
if (txin.prevout .n < prev.vout .size ())
759
759
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 ) );
761
761
}
762
762
}
763
763
return 0 ;
@@ -867,11 +867,21 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
867
867
if (nDebit > 0 ) // debit>0 means we signed/sent this transaction
868
868
nFee = nTxFee;
869
869
870
+ CTxDestination addressUnaccounted = CNoDestination ();
871
+ int voutUnaccounted = -1 ;
872
+ CAmount nValueUnaccounted = nDebit - nFee;
873
+ int nUnaccountedOutputs = 0 ;
874
+
870
875
// Sent/received.
871
876
for (unsigned int i = 0 ; i < vout.size (); ++i)
872
877
{
878
+ CAmount nValueOut = GetValueOut (i);
879
+
880
+ if (nValueOut >= 0 ) {
881
+ nValueUnaccounted -= nValueOut;
882
+ }
873
883
const CTxOut& txout = vout[i];
874
- isminetype fIsMine = pwallet->IsMine (txout);
884
+ isminetype fIsMine = nValueOut >= 0 ? pwallet->IsMine (txout) : ISMINE_NO ;
875
885
// Only need to handle txouts if AT LEAST one of these is true:
876
886
// 1) they debit from us (sent)
877
887
// 2) the output is to us (received)
@@ -893,12 +903,18 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
893
903
address = CNoDestination ();
894
904
}
895
905
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 ;
900
914
}
901
915
916
+ COutputEntry output = {address, nValueOut, (int )i, GetBlindingKey (i)};
917
+
902
918
// If we are debited by the transaction, add the output as a "sent" entry
903
919
if (nDebit > 0 )
904
920
listSent.push_back (output);
@@ -908,6 +924,17 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
908
924
listReceived.push_back (output);
909
925
}
910
926
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
+ }
911
938
}
912
939
913
940
void CWalletTx::GetAccountAmounts (const string& strAccount, CAmount& nReceived,
0 commit comments