Skip to content

Commit 082f597

Browse files
committed
Fix for self-transactions in listtransactions
1 parent 5f1ff3f commit 082f597

File tree

1 file changed

+42
-5
lines changed

1 file changed

+42
-5
lines changed

src/wallet/wallet.cpp

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -778,8 +778,16 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived, list<COutputEntry>&
778778

779779
strSentAccount = strFromAccount;
780780

781+
// This is the same as nDebit > 0, i.e. we sent the transaction.
781782
bool fIsFromMe = IsFromMe();
782783

784+
// This will be true if this is a self-transaction.
785+
bool fIsAllToMe = true;
786+
for (auto const& txout : vout)
787+
{
788+
fIsAllToMe = fIsAllToMe && (pwallet->IsMine(txout) != ISMINE_NO);
789+
}
790+
783791
// Used for coinstake rollup.
784792
int64_t amount = 0;
785793

@@ -790,11 +798,11 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived, list<COutputEntry>&
790798

791799
// Compute fee:
792800
int64_t nDebit = GetDebit(filter);
793-
// debit > 0 means we signed/sent this transaction, we do not record a fee for
801+
// fIsFromMe true means we signed/sent this transaction, we do not record a fee for
794802
// coinstakes. The fees collected from other transactions in the block are added
795803
// to the staker's output(s) that are the staker's. Therefore fees only need
796804
// to be shown for non-coinstake send transactions.
797-
if (nDebit > 0 && !fIsCoinStake)
805+
if (fIsFromMe && !fIsCoinStake)
798806
{
799807
int64_t nValueOut = GetValueOut();
800808
nFee = nDebit - nValueOut;
@@ -808,7 +816,7 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived, list<COutputEntry>&
808816
// Only need to handle txouts if AT LEAST one of these is true:
809817
// 1) they debit from us (sent)
810818
// 2) the output is to us (received)
811-
if (nDebit > 0)
819+
if (fIsFromMe)
812820
{
813821
// If not a coinstake, don't report 'change' txouts. Txouts on change addresses for coinstakes
814822
// must be reported because a change address itself can stake, and there is no "change" on a
@@ -829,8 +837,9 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived, list<COutputEntry>&
829837
// OR (not a coinstake and nDebit > 0, i.e. a normal send transaction)), add the output as a "sent" entry.
830838
// We exclude coinstake outputs 0 and 1 from sends, because output 0 is empty and output 1 MUST go back to
831839
// the staker (i.e. is not a send by definition). Notice that for a normal self-transaction, the send and
832-
// receive details will be suppressed; however, the fee will be reported in the nFee parameter.
833-
if (fIsMine == ISMINE_NO && ((i > 1 && fIsCoinStakeMine) || (!fIsCoinStake && nDebit > 0)))
840+
// receive details will be suppressed in this block. There is a separate section to deal with self-transactions
841+
// below.
842+
if (fIsMine == ISMINE_NO && ((i > 1 && fIsCoinStakeMine) || (!fIsCoinStake && fIsFromMe)))
834843
{
835844
if (!ExtractDestination(txout.scriptPubKey, address))
836845
{
@@ -888,6 +897,34 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived, list<COutputEntry>&
888897
output = {address, txout.nValue, (int) i};
889898
listReceived.push_back(output);
890899
}
900+
901+
// Self-transactions...
902+
903+
if (fIsFromMe && fIsAllToMe)
904+
{
905+
if (!ExtractDestination(txout.scriptPubKey, address))
906+
{
907+
if (txout.scriptPubKey[0] != OP_RETURN)
908+
{
909+
LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s",
910+
this->GetHash().ToString().c_str());
911+
}
912+
913+
address = CNoDestination();
914+
}
915+
916+
// For a self-transaction, the output has to be both a send and a receive. Note that an
917+
// unfortunate side-effect of this solution for self-transaction listing is that the fee
918+
// will be reported on both the send and receive transactions in the ListTransactions that
919+
// normally calls this function, but that is better than simply reporting the receive side only
920+
// of a self-transaction, which is typically what is done.
921+
//
922+
// Also, a mixed transaction where some of the outputs are back to oneself, and others are to
923+
// other addressees, does not qualify here. Those only the output sends will be reported.
924+
output = {address, txout.nValue, (int) i};
925+
listSent.push_back(output);
926+
listReceived.push_back(output);
927+
}
891928
}
892929
}
893930

0 commit comments

Comments
 (0)