Fixes #1345 so that UTXO debit and credits are computed correctly for a transaction.
This commit is contained in:
@@ -1328,6 +1328,7 @@ int CWalletTx::GetRequestCount() const
|
||||
return nRequests;
|
||||
}
|
||||
|
||||
// GetAmounts will determine the transparent debits and credits for a given wallet tx.
|
||||
void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
|
||||
list<COutputEntry>& listSent, CAmount& nFee, string& strSentAccount, const isminefilter& filter) const
|
||||
{
|
||||
@@ -1336,12 +1337,77 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
|
||||
listSent.clear();
|
||||
strSentAccount = strFromAccount;
|
||||
|
||||
// Compute fee:
|
||||
// Is this tx sent/signed by me?
|
||||
CAmount nDebit = GetDebit(filter);
|
||||
if (nDebit > 0) // debit>0 means we signed/sent this transaction
|
||||
{
|
||||
CAmount nValueOut = GetValueOut();
|
||||
nFee = nDebit - nValueOut;
|
||||
bool isFromMyTaddr = nDebit > 0; // debit>0 means we signed/sent this transaction
|
||||
|
||||
// Does this tx spend my notes?
|
||||
bool isFromMyZaddr = false;
|
||||
for (const JSDescription& js : vjoinsplit) {
|
||||
for (const uint256& nullifier : js.nullifiers) {
|
||||
if (pwallet->IsFromMe(nullifier)) {
|
||||
isFromMyZaddr = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isFromMyZaddr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute fee if we sent this transaction.
|
||||
if (isFromMyTaddr) {
|
||||
CAmount nValueOut = GetValueOut(); // transparent outputs plus all vpub_old
|
||||
CAmount nValueIn = 0;
|
||||
for (const JSDescription & js : vjoinsplit) {
|
||||
nValueIn += js.vpub_new;
|
||||
}
|
||||
nFee = nDebit - nValueOut + nValueIn;
|
||||
}
|
||||
|
||||
// Create output entry for vpub_old/new, if we sent utxos from this transaction
|
||||
if (isFromMyTaddr) {
|
||||
CAmount myVpubOld = 0;
|
||||
CAmount myVpubNew = 0;
|
||||
for (const JSDescription& js : vjoinsplit) {
|
||||
bool fMyJSDesc = false;
|
||||
|
||||
// Check input side
|
||||
for (const uint256& nullifier : js.nullifiers) {
|
||||
if (pwallet->IsFromMe(nullifier)) {
|
||||
fMyJSDesc = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check output side
|
||||
if (!fMyJSDesc) {
|
||||
for (const std::pair<JSOutPoint, CNoteData> nd : this->mapNoteData) {
|
||||
if (nd.first.js < vjoinsplit.size() && nd.first.n < vjoinsplit[nd.first.js].ciphertexts.size()) {
|
||||
fMyJSDesc = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fMyJSDesc) {
|
||||
myVpubOld += js.vpub_old;
|
||||
myVpubNew += js.vpub_new;
|
||||
}
|
||||
|
||||
if (!MoneyRange(js.vpub_old) || !MoneyRange(js.vpub_new) || !MoneyRange(myVpubOld) || !MoneyRange(myVpubNew)) {
|
||||
throw std::runtime_error("CWalletTx::GetAmounts: value out of range");
|
||||
}
|
||||
}
|
||||
|
||||
// Create an output for the value taken from or added to the transparent value pool by JoinSplits
|
||||
if (myVpubOld > myVpubNew) {
|
||||
COutputEntry output = {CNoDestination(), myVpubOld - myVpubNew, (int)vout.size()};
|
||||
listSent.push_back(output);
|
||||
} else if (myVpubNew > myVpubOld) {
|
||||
COutputEntry output = {CNoDestination(), myVpubNew - myVpubOld, (int)vout.size()};
|
||||
listReceived.push_back(output);
|
||||
}
|
||||
}
|
||||
|
||||
// Sent/received.
|
||||
|
||||
Reference in New Issue
Block a user