X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fqt%2Ftransactionrecord.cpp;h=ec4ba10be32883df539cb93b4a041c15b8d538ff;hb=98d23c1aaf2bfe1b1133c0f6adf9bceb586f31b2;hp=8a1f1b677227f7226e8392de81ee6901f7297634;hpb=21d9f36781604e4ca9fc35dc65265593423b73e9;p=novacoin.git diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 8a1f1b6..ec4ba10 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -1,8 +1,9 @@ -#include - #include "transactionrecord.h" -#include "headers.h" +#include "wallet.h" +#include "base58.h" + +extern CWallet* pwalletMain; /* Return positive answer if transaction should be shown in list. */ @@ -10,18 +11,8 @@ bool TransactionRecord::showTransaction(const CWalletTx &wtx) { if (wtx.IsCoinBase()) { - // Don't show generated coin until confirmed by at least one block after it - // so we don't get the user's hopes up until it looks like it's probably accepted. - // - // It is not an error when generated blocks are not accepted. By design, - // some percentage of blocks, like 10% or more, will end up not accepted. - // This is the normal mechanism by which the network copes with latency. - // - // We display regular transactions right away before any confirmation - // because they can always get into some block eventually. Generated coins - // are special because if their block is not accepted, they are not valid. - // - if (wtx.GetDepthInMainChain() < 2) + // Ensures we show generated coins / mined transactions at depth 1 + if (!wtx.IsInMainChain()) { return false; } @@ -35,143 +26,179 @@ bool TransactionRecord::showTransaction(const CWalletTx &wtx) QList TransactionRecord::decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx) { QList parts; - qint64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime(); - qint64 nCredit = wtx.GetCredit(true); - qint64 nDebit = wtx.GetDebit(); - qint64 nNet = nCredit - nDebit; - uint256 hash = wtx.GetHash(); + int64_t nTime = wtx.GetTxTime(); + int64_t nCredit = wtx.GetCredit(MINE_ALL); + int64_t nDebit = wtx.GetDebit(MINE_ALL); + int64_t nNet = nCredit - nDebit; + uint256 hash = wtx.GetHash(), hashPrev = 0; std::map mapValue = wtx.mapValue; - if (showTransaction(wtx)) + if (nNet > 0 || wtx.IsCoinBase() || wtx.IsCoinStake()) { - if (nNet > 0 || wtx.IsCoinBase()) + // + // Credit + // + BOOST_FOREACH(const CTxOut& txout, wtx.vout) { - // - // Credit - // - TransactionRecord sub(hash, nTime); - - sub.credit = nNet; - - if (wtx.IsCoinBase()) + if(wallet->IsMine(txout)) { - // Generated - sub.type = TransactionRecord::Generated; + TransactionRecord sub(hash, nTime); + sub.idx = parts.size(); // sequence number + sub.credit = txout.nValue; - if (nCredit == 0) + if (!fTestNet) { - qint64 nUnmatured = 0; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - nUnmatured += wallet->GetCredit(txout); - sub.credit = nUnmatured; - } - } - else if (!mapValue["from"].empty() || !mapValue["message"].empty()) - { - // Received by IP connection - sub.type = TransactionRecord::RecvFromIP; - if (!mapValue["from"].empty()) - sub.address = mapValue["from"]; - } - else - { - // Received by Bitcoin Address - sub.type = TransactionRecord::RecvWithAddress; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - { - if(wallet->IsMine(txout)) + CTxDestination address; + if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address)) + { + // Received by Bitcoin Address + sub.type = TransactionRecord::RecvWithAddress; + sub.address = CBitcoinAddress(address).ToString(); + } + else { - CBitcoinAddress address; - if (ExtractAddress(txout.scriptPubKey, wallet, address)) + // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction + sub.type = TransactionRecord::RecvFromOther; + sub.address = mapValue["from"]; + } + } + else + { + txnouttype whichType; + std::vector vSolutions; + if (Solver(txout.scriptPubKey, whichType, vSolutions)) + { + CTxDestination address; + if (whichType == TX_PUBKEY) + { + // Pay-to-Pubkey + address = CPubKey(vSolutions[0]).GetID(); + sub.type = TransactionRecord::RecvWithAddress; + sub.address = CBitcoinAddress(address).ToString(); + } + else if (whichType == TX_PUBKEYHASH) + { + // Pay-to-PubkeyHash + address = CKeyID(uint160(vSolutions[0])); + sub.type = TransactionRecord::RecvWithAddress; + sub.address = CBitcoinAddress(address).ToString(); + } + else if (whichType == TX_SCRIPTHASH) + { + // Pay-to-ScriptHash + address = CScriptID(uint160(vSolutions[0])); + sub.type = TransactionRecord::RecvWithAddress; + sub.address = CBitcoinAddress(address).ToString(); + } + else if (whichType == TX_PUBKEY_DROP) { - sub.address = address.ToString(); + // Pay-to-Pubkey-R + sub.type = TransactionRecord::RecvWithAddress; + + CMalleableKeyView view; + pwalletMain->CheckOwnership(CPubKey(vSolutions[0]), CPubKey(vSolutions[1]), view); + sub.address = view.GetMalleablePubKey().ToString(); + } + else + { + // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction + sub.type = TransactionRecord::RecvFromOther; + sub.address = mapValue["from"]; } - break; } } + if (wtx.IsCoinBase()) + { + // Generated (proof-of-work) + sub.type = TransactionRecord::Generated; + } + if (wtx.IsCoinStake()) + { + // Generated (proof-of-stake) + + if (hashPrev == hash) + continue; // last coinstake output + + sub.type = TransactionRecord::Generated; + sub.credit = nNet > 0 ? nNet : wtx.GetValueOut() - nDebit; + hashPrev = hash; + } + + parts.append(sub); } - parts.append(sub); } - else - { - bool fAllFromMe = true; - BOOST_FOREACH(const CTxIn& txin, wtx.vin) - fAllFromMe = fAllFromMe && wallet->IsMine(txin); + } + else + { + bool fAllFromMe = true; + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + fAllFromMe = fAllFromMe && wallet->IsMine(txin); - bool fAllToMe = true; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - fAllToMe = fAllToMe && wallet->IsMine(txout); + bool fAllToMe = true; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + fAllToMe = fAllToMe && wallet->IsMine(txout); - if (fAllFromMe && fAllToMe) - { - // Payment to self - qint64 nChange = wtx.GetChange(); + if (fAllFromMe && fAllToMe) + { + // Payment to self + int64_t nChange = wtx.GetChange(); - parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "", - -(nDebit - nChange), nCredit - nChange)); - } - else if (fAllFromMe) + parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "", + -(nDebit - nChange), nCredit - nChange)); + } + else if (fAllFromMe) + { + // + // Debit + // + int64_t nTxFee = nDebit - wtx.GetValueOut(); + + for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++) { - // - // Debit - // - qint64 nTxFee = nDebit - wtx.GetValueOut(); + const CTxOut& txout = wtx.vout[nOut]; + TransactionRecord sub(hash, nTime); + sub.idx = parts.size(); - for (int nOut = 0; nOut < wtx.vout.size(); nOut++) + if(wallet->IsMine(txout)) { - const CTxOut& txout = wtx.vout[nOut]; - TransactionRecord sub(hash, nTime); - sub.idx = parts.size(); - - if(wallet->IsMine(txout)) - { - // Ignore parts sent to self, as this is usually the change - // from a transaction sent back to our own address. - continue; - } - else if(!mapValue["to"].empty()) - { - // Sent to IP - sub.type = TransactionRecord::SendToIP; - sub.address = mapValue["to"]; - } - else - { - // Sent to Bitcoin Address - sub.type = TransactionRecord::SendToAddress; - CBitcoinAddress address; - if (ExtractAddress(txout.scriptPubKey, 0, address)) - { - sub.address = address.ToString(); - } - } + // Ignore parts sent to self, as this is usually the change + // from a transaction sent back to our own address. + continue; + } - qint64 nValue = txout.nValue; - /* Add fee to first output */ - if (nTxFee > 0) - { - nValue += nTxFee; - nTxFee = 0; - } - sub.debit = -nValue; + CTxDestination address; + if (ExtractDestination(txout.scriptPubKey, address)) + { + // Sent to Bitcoin Address + sub.type = TransactionRecord::SendToAddress; + sub.address = CBitcoinAddress(address).ToString(); + } + else + { + // Sent to IP, or other non-address transaction like OP_EVAL + sub.type = TransactionRecord::SendToOther; + sub.address = mapValue["to"]; + } - parts.append(sub); + int64_t nValue = txout.nValue; + /* Add fee to first output */ + if (nTxFee > 0) + { + nValue += nTxFee; + nTxFee = 0; } - } - else - { - // - // Mixed debit transaction, can't break down payees - // - bool fAllMine = true; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - fAllMine = fAllMine && wallet->IsMine(txout); - BOOST_FOREACH(const CTxIn& txin, wtx.vin) - fAllMine = fAllMine && wallet->IsMine(txin); + sub.debit = -nValue; - parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0)); + parts.append(sub); } } + else + { + // + // Mixed debit transaction, can't break down payees + // + parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0)); + } } return parts; @@ -193,7 +220,7 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx) (wtx.IsCoinBase() ? 1 : 0), wtx.nTimeReceived, idx); - status.confirmed = wtx.IsConfirmed(); + status.confirmed = wtx.IsTrusted(); status.depth = wtx.GetDepthInMainChain(); status.cur_num_blocks = nBestHeight; @@ -229,8 +256,7 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx) // For generated transactions, determine maturity if(type == TransactionRecord::Generated) { - qint64 nCredit = wtx.GetCredit(true); - if (nCredit == 0) + if (wtx.GetBlocksToMaturity() > 0) { status.maturity = TransactionStatus::Immature;