1313
1414#include < QDateTime>
1515
16+ using wallet::ISMINE_NO;
1617using wallet::ISMINE_SPENDABLE;
1718using wallet::ISMINE_WATCH_ONLY;
1819using wallet::isminetype;
@@ -39,99 +40,52 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const interface
3940 uint256 hash = wtx.tx ->GetHash ();
4041 std::map<std::string, std::string> mapValue = wtx.value_map ;
4142
42- if (nNet > 0 || wtx.is_coinbase )
43- {
44- //
45- // Credit
46- //
47- for (unsigned int i = 0 ; i < wtx.tx ->vout .size (); i++)
48- {
49- const CTxOut& txout = wtx.tx ->vout [i];
50- isminetype mine = wtx.txout_is_mine [i];
51- if (mine)
52- {
53- TransactionRecord sub (hash, nTime);
54- sub.idx = i; // vout index
55- sub.credit = txout.nValue ;
56- sub.involvesWatchAddress = mine & ISMINE_WATCH_ONLY;
57- if (wtx.txout_address_is_mine [i])
58- {
59- // Received by Bitcoin Address
60- sub.type = TransactionRecord::RecvWithAddress;
61- sub.address = EncodeDestination (wtx.txout_address [i]);
62- }
63- else
64- {
65- // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
66- sub.type = TransactionRecord::RecvFromOther;
67- sub.address = mapValue[" from" ];
68- }
69- if (wtx.is_coinbase )
70- {
71- // Generated
72- sub.type = TransactionRecord::Generated;
73- }
74-
75- parts.append (sub);
76- }
77- }
78- }
79- else
80- {
81- bool involvesWatchAddress = false ;
82- isminetype fAllFromMe = ISMINE_SPENDABLE;
43+ bool involvesWatchAddress = false ;
44+ isminetype fAllFromMe = ISMINE_SPENDABLE;
45+ bool any_from_me = false ;
46+ if (wtx.is_coinbase ) {
47+ fAllFromMe = ISMINE_NO;
48+ } else {
8349 for (const isminetype mine : wtx.txin_is_mine )
8450 {
8551 if (mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true ;
8652 if (fAllFromMe > mine) fAllFromMe = mine;
53+ if (mine) any_from_me = true ;
8754 }
55+ }
8856
89- isminetype fAllToMe = ISMINE_SPENDABLE;
57+ if ( fAllFromMe || !any_from_me) {
9058 for (const isminetype mine : wtx.txout_is_mine )
9159 {
9260 if (mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true ;
93- if (fAllToMe > mine) fAllToMe = mine;
9461 }
9562
96- if (fAllFromMe && fAllToMe )
97- {
98- // Payment to self
99- std::string address;
100- for (auto it = wtx.txout_address .begin (); it != wtx.txout_address .end (); ++it) {
101- if (it != wtx.txout_address .begin ()) address += " , " ;
102- address += EncodeDestination (*it);
103- }
63+ CAmount nTxFee = nDebit - wtx.tx ->GetValueOut ();
10464
105- CAmount nChange = wtx.change ;
106- parts.append (TransactionRecord (hash, nTime, TransactionRecord::SendToSelf, address, -(nDebit - nChange), nCredit - nChange));
107- parts.last ().involvesWatchAddress = involvesWatchAddress; // maybe pass to TransactionRecord as constructor argument
108- }
109- else if (fAllFromMe )
65+ for (unsigned int i = 0 ; i < wtx.tx ->vout .size (); i++)
11066 {
111- //
112- // Debit
113- //
114- CAmount nTxFee = nDebit - wtx.tx ->GetValueOut ();
115-
116- for (unsigned int nOut = 0 ; nOut < wtx.tx ->vout .size (); nOut++)
117- {
118- const CTxOut& txout = wtx.tx ->vout [nOut];
119- TransactionRecord sub (hash, nTime);
120- sub.idx = nOut;
121- sub.involvesWatchAddress = involvesWatchAddress;
67+ const CTxOut& txout = wtx.tx ->vout [i];
12268
123- if (wtx. txout_is_mine [nOut])
124- {
125- // Ignore parts sent to self, as this is usually the change
126- // from a transaction sent back to our own address.
69+ if ( fAllFromMe ) {
70+ // Change is only really possible if we're the sender
71+ // Otherwise, someone just sent bitcoins to a change address, which should be shown
72+ if (wtx. txout_is_change [i]) {
12773 continue ;
12874 }
12975
130- if (!std::get_if<CNoDestination>(&wtx.txout_address [nOut]))
76+ //
77+ // Debit
78+ //
79+
80+ TransactionRecord sub (hash, nTime);
81+ sub.idx = i;
82+ sub.involvesWatchAddress = involvesWatchAddress;
83+
84+ if (!std::get_if<CNoDestination>(&wtx.txout_address [i]))
13185 {
13286 // Sent to Bitcoin Address
13387 sub.type = TransactionRecord::SendToAddress;
134- sub.address = EncodeDestination (wtx.txout_address [nOut ]);
88+ sub.address = EncodeDestination (wtx.txout_address [i ]);
13589 }
13690 else
13791 {
@@ -151,15 +105,45 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const interface
151105
152106 parts.append (sub);
153107 }
108+
109+ isminetype mine = wtx.txout_is_mine [i];
110+ if (mine)
111+ {
112+ //
113+ // Credit
114+ //
115+
116+ TransactionRecord sub (hash, nTime);
117+ sub.idx = i; // vout index
118+ sub.credit = txout.nValue ;
119+ sub.involvesWatchAddress = mine & ISMINE_WATCH_ONLY;
120+ if (wtx.txout_address_is_mine [i])
121+ {
122+ // Received by Bitcoin Address
123+ sub.type = TransactionRecord::RecvWithAddress;
124+ sub.address = EncodeDestination (wtx.txout_address [i]);
125+ }
126+ else
127+ {
128+ // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
129+ sub.type = TransactionRecord::RecvFromOther;
130+ sub.address = mapValue[" from" ];
131+ }
132+ if (wtx.is_coinbase )
133+ {
134+ // Generated
135+ sub.type = TransactionRecord::Generated;
136+ }
137+
138+ parts.append (sub);
139+ }
154140 }
155- else
156- {
157- //
158- // Mixed debit transaction, can't break down payees
159- //
160- parts.append (TransactionRecord (hash, nTime, TransactionRecord::Other, " " , nNet, 0 ));
161- parts.last ().involvesWatchAddress = involvesWatchAddress;
162- }
141+ } else {
142+ //
143+ // Mixed debit transaction, can't break down payees
144+ //
145+ parts.append (TransactionRecord (hash, nTime, TransactionRecord::Other, " " , nNet, 0 ));
146+ parts.last ().involvesWatchAddress = involvesWatchAddress;
163147 }
164148
165149 return parts;
@@ -170,11 +154,21 @@ void TransactionRecord::updateStatus(const interfaces::WalletTxStatus& wtx, cons
170154 // Determine transaction status
171155
172156 // Sort order, unrecorded transactions sort to the top
173- status.sortKey = strprintf (" %010d-%01d-%010u-%03d" ,
157+ int typesort;
158+ switch (type) {
159+ case SendToAddress: case SendToOther:
160+ typesort = 2 ; break ;
161+ case RecvWithAddress: case RecvFromOther:
162+ typesort = 3 ; break ;
163+ default :
164+ typesort = 9 ;
165+ }
166+ status.sortKey = strprintf (" %010d-%01d-%010u-%03d-%d" ,
174167 wtx.block_height ,
175168 wtx.is_coinbase ? 1 : 0 ,
176169 wtx.time_received ,
177- idx);
170+ idx,
171+ typesort);
178172 status.countsForBalance = wtx.is_trusted && !(wtx.blocks_to_maturity > 0 );
179173 status.depth = wtx.depth_in_main_chain ;
180174 status.m_cur_block_hash = block_hash;
0 commit comments