diff --git a/db.cpp b/db.cpp index df500cadb..a7c18a6ff 100644 --- a/db.cpp +++ b/db.cpp @@ -465,7 +465,7 @@ bool CTxDB::LoadBlockIndex() CBlockIndex* pindexFork = NULL; for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev) { - if (pindex->nHeight < 74000 && !mapArgs.count("-checkblocks")) + if (pindex->nHeight < nBestHeight-2500 && !mapArgs.count("-checkblocks")) break; CBlock block; if (!block.ReadFromDisk(pindex)) diff --git a/init.cpp b/init.cpp index 95204ad3a..45d79d71b 100644 --- a/init.cpp +++ b/init.cpp @@ -203,7 +203,7 @@ bool AppInit2(int argc, char* argv[]) if (!fDebug && !pszSetDataDir[0]) ShrinkDebugFile(); printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); - printf("Bitcoin version %d.%d.%d%s beta\n", VERSION/10000, (VERSION/100)%100, VERSION%100, pszSubVer); + printf("Bitcoin version %s%s beta\n", FormatVersion(VERSION).c_str(), pszSubVer); #ifdef GUI printf("OS version %s\n", ((string)wxGetOsDescription()).c_str()); printf("System default language is %d %s\n", g_locale.GetSystemLanguage(), ((string)g_locale.GetSysName()).c_str()); diff --git a/locale/de/LC_MESSAGES/bitcoin.mo b/locale/de/LC_MESSAGES/bitcoin.mo index 5d7eeb2b8..a9ead65cc 100644 Binary files a/locale/de/LC_MESSAGES/bitcoin.mo and b/locale/de/LC_MESSAGES/bitcoin.mo differ diff --git a/locale/de/LC_MESSAGES/bitcoin.po b/locale/de/LC_MESSAGES/bitcoin.po index 427aebc45..91c79f99a 100644 --- a/locale/de/LC_MESSAGES/bitcoin.po +++ b/locale/de/LC_MESSAGES/bitcoin.po @@ -321,8 +321,8 @@ msgstr "Beim schließen &Minimieren" #: ../../../ui.cpp:1595 #, c-format -msgid "version 0.%d.%d beta" -msgstr "Version 0.%d.%d Beta" +msgid "version %s%s beta" +msgstr "Version %s%s Beta" #: ../../../ui.cpp:1681 msgid "Will appear as \"From: Unknown\"" diff --git a/locale/es/LC_MESSAGES/bitcoin.mo b/locale/es/LC_MESSAGES/bitcoin.mo index da857ffd4..5df54f4aa 100644 Binary files a/locale/es/LC_MESSAGES/bitcoin.mo and b/locale/es/LC_MESSAGES/bitcoin.mo differ diff --git a/locale/es/LC_MESSAGES/bitcoin.po b/locale/es/LC_MESSAGES/bitcoin.po index 37297eec1..239f63bd3 100644 --- a/locale/es/LC_MESSAGES/bitcoin.po +++ b/locale/es/LC_MESSAGES/bitcoin.po @@ -350,8 +350,8 @@ msgstr "&Minimizar al cerrar" #: ../../../ui.cpp:1610 #, c-format -msgid "version %d.%d.%d beta" -msgstr "version %d.%d.%d beta" +msgid "version %s%s beta" +msgstr "version %s%s beta" #: ../../../ui.cpp:1696 msgid "Will appear as \"From: Unknown\"" diff --git a/locale/fr/LC_MESSAGES/bitcoin.mo b/locale/fr/LC_MESSAGES/bitcoin.mo index 59d28be89..137e0bdf1 100644 Binary files a/locale/fr/LC_MESSAGES/bitcoin.mo and b/locale/fr/LC_MESSAGES/bitcoin.mo differ diff --git a/locale/fr/LC_MESSAGES/bitcoin.po b/locale/fr/LC_MESSAGES/bitcoin.po index 735914cf7..09b7e37ae 100644 --- a/locale/fr/LC_MESSAGES/bitcoin.po +++ b/locale/fr/LC_MESSAGES/bitcoin.po @@ -351,8 +351,8 @@ msgstr "&Réduire à la fermeture" #: ../../../ui.cpp:1610 #, c-format -msgid "version %d.%d.%d beta" -msgstr "version %d.%d.%d beta" +msgid "version %s%s beta" +msgstr "version %s%s beta" #: ../../../ui.cpp:1696 msgid "Will appear as \"From: Unknown\"" diff --git a/locale/it/LC_MESSAGES/bitcoin.mo b/locale/it/LC_MESSAGES/bitcoin.mo index 2ce12e2fb..73979c78c 100644 Binary files a/locale/it/LC_MESSAGES/bitcoin.mo and b/locale/it/LC_MESSAGES/bitcoin.mo differ diff --git a/locale/it/LC_MESSAGES/bitcoin.po b/locale/it/LC_MESSAGES/bitcoin.po index c24174432..42f913a67 100644 --- a/locale/it/LC_MESSAGES/bitcoin.po +++ b/locale/it/LC_MESSAGES/bitcoin.po @@ -319,8 +319,8 @@ msgstr "&Minimizza se chiuso" #: ../../../ui.cpp:1595 #, c-format -msgid "version 0.%d.%d beta" -msgstr "versione 0.%d.%d beta" +msgid "version %s%s beta" +msgstr "versione %s%s beta" #: ../../../ui.cpp:1681 msgid "Will appear as \"From: Unknown\"" diff --git a/locale/nl/LC_MESSAGES/bitcoin.mo b/locale/nl/LC_MESSAGES/bitcoin.mo index 66015f314..05c03ab14 100644 Binary files a/locale/nl/LC_MESSAGES/bitcoin.mo and b/locale/nl/LC_MESSAGES/bitcoin.mo differ diff --git a/locale/nl/LC_MESSAGES/bitcoin.po b/locale/nl/LC_MESSAGES/bitcoin.po index cfb05fb3c..20e8de1d5 100644 --- a/locale/nl/LC_MESSAGES/bitcoin.po +++ b/locale/nl/LC_MESSAGES/bitcoin.po @@ -320,8 +320,8 @@ msgstr "&Minimalizeer bij sluiten" #: ../../../ui.cpp:1595 #, c-format -msgid "version 0.%d.%d beta" -msgstr "versie 0.%d.%d beta" +msgid "version %s%s beta" +msgstr "versie %s%s beta" #: ../../../ui.cpp:1681 msgid "Will appear as \"From: Unknown\"" diff --git a/locale/pt/LC_MESSAGES/bitcoin.mo b/locale/pt/LC_MESSAGES/bitcoin.mo index fc97f3956..e432d97ee 100644 Binary files a/locale/pt/LC_MESSAGES/bitcoin.mo and b/locale/pt/LC_MESSAGES/bitcoin.mo differ diff --git a/locale/pt/LC_MESSAGES/bitcoin.po b/locale/pt/LC_MESSAGES/bitcoin.po index c0e4fd65a..2e5ec5305 100644 --- a/locale/pt/LC_MESSAGES/bitcoin.po +++ b/locale/pt/LC_MESSAGES/bitcoin.po @@ -319,8 +319,8 @@ msgstr "&Minimizar ao fechar" #: ../../../ui.cpp:1595 #, c-format -msgid "version 0.%d.%d beta" -msgstr "versão 0.%d.%d beta" +msgid "version %s%s beta" +msgstr "versão %s%s beta" #: ../../../ui.cpp:1681 msgid "Will appear as \"From: Unknown\"" diff --git a/main.cpp b/main.cpp index 10931f9d1..a70dd7cc1 100644 --- a/main.cpp +++ b/main.cpp @@ -487,18 +487,56 @@ void CWalletTx::AddSupportingTransactions(CTxDB& txdb) +bool CTransaction::CheckTransaction() const +{ + // Basic checks that don't depend on any context + if (vin.empty() || vout.empty()) + return error("CTransaction::CheckTransaction() : vin or vout empty"); + + // Size limits + if (::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE) + return error("CTransaction::CheckTransaction() : size limits failed"); + + // Check for negative or overflow output values + int64 nValueOut = 0; + foreach(const CTxOut& txout, vout) + { + if (txout.nValue < 0) + return error("CTransaction::CheckTransaction() : txout.nValue negative"); + if (txout.nValue > MAX_MONEY) + return error("CTransaction::CheckTransaction() : txout.nValue too high"); + nValueOut += txout.nValue; + if (!MoneyRange(nValueOut)) + return error("CTransaction::CheckTransaction() : txout total out of range"); + } + + if (IsCoinBase()) + { + if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100) + return error("CTransaction::CheckTransaction() : coinbase script size"); + } + else + { + foreach(const CTxIn& txin, vin) + if (txin.prevout.IsNull()) + return error("CTransaction::CheckTransaction() : prevout is null"); + } + + return true; +} + bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs) { if (pfMissingInputs) *pfMissingInputs = false; + if (!CheckTransaction()) + return error("AcceptToMemoryPool() : CheckTransaction failed"); + // Coinbase is only valid in a block, not as a loose transaction if (IsCoinBase()) return error("AcceptToMemoryPool() : coinbase as individual tx"); - if (!CheckTransaction()) - return error("AcceptToMemoryPool() : CheckTransaction failed"); - // To help v0.1.5 clients who would see it as a negative number if ((int64)nLockTime > INT_MAX) return error("AcceptToMemoryPool() : not accepting nLockTime beyond 2038 yet"); @@ -815,7 +853,7 @@ uint256 GetOrphanRoot(const CBlock* pblock) return pblock->GetHash(); } -int64 CBlock::GetBlockValue(int nHeight, int64 nFees) const +int64 GetBlockValue(int nHeight, int64 nFees) { int64 nSubsidy = 50 * COIN; @@ -1024,6 +1062,11 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map& mapTestPoo if (!txindex.vSpent[prevout.n].IsNull()) return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,6).c_str(), txindex.vSpent[prevout.n].ToString().c_str()); + // Check for negative or overflow input values + nValueIn += txPrev.vout[prevout.n].nValue; + if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn)) + return error("ConnectInputs() : txin values out of range"); + // Mark outpoints as spent txindex.vSpent[prevout.n] = posThisTx; @@ -1032,12 +1075,6 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map& mapTestPoo txdb.UpdateTxIndex(prevout.hash, txindex); else if (fMiner) mapTestPool[prevout.hash] = txindex; - - nValueIn += txPrev.vout[prevout.n].nValue; - - // Check for negative or overflow input values - if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn)) - return error("ConnectInputs() : txin values out of range"); } if (nValueIn < GetValueOut()) @@ -2967,7 +3004,7 @@ void BitcoinMiner() } } pblock->nBits = nBits; - pblock->vtx[0].vout[0].nValue = pblock->GetBlockValue(pindexPrev->nHeight+1, nFees); + pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees); printf("Running BitcoinMiner with %d transactions in block\n", pblock->vtx.size()); @@ -3169,6 +3206,8 @@ int64 GetBalance() CWalletTx* pcoin = &(*it).second; if (!pcoin->IsFinal() || pcoin->fSpent) continue; + if (pcoin->GetDepthInMainChain() < 1 && pcoin->GetDebit() <= 0) + continue; nTotal += pcoin->GetCredit(true); } } @@ -3200,6 +3239,8 @@ bool SelectCoins(int64 nTargetValue, set& setCoinsRet) { if (!pcoin->IsFinal() || pcoin->fSpent) continue; + if (pcoin->GetDepthInMainChain() < 1 && pcoin->GetDebit() <= 0) + continue; int64 n = pcoin->GetCredit(); if (n <= 0) continue; diff --git a/main.h b/main.h index 95e946a89..c5a0127c4 100644 --- a/main.h +++ b/main.h @@ -469,44 +469,6 @@ public: return (vin.size() == 1 && vin[0].prevout.IsNull()); } - bool CheckTransaction() const - { - // Basic checks that don't depend on any context - if (vin.empty() || vout.empty()) - return error("CTransaction::CheckTransaction() : vin or vout empty"); - - // Size limits - if (::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE) - return error("CTransaction::CheckTransaction() : size limits failed"); - - // Check for negative or overflow output values - int64 nValueOut = 0; - foreach(const CTxOut& txout, vout) - { - if (txout.nValue < 0) - return error("CTransaction::CheckTransaction() : txout.nValue negative"); - if (txout.nValue > MAX_MONEY) - return error("CTransaction::CheckTransaction() : txout.nValue too high"); - nValueOut += txout.nValue; - if (!MoneyRange(nValueOut)) - return error("CTransaction::CheckTransaction() : txout total out of range"); - } - - if (IsCoinBase()) - { - if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100) - return error("CTransaction::CheckTransaction() : coinbase script size"); - } - else - { - foreach(const CTxIn& txin, vin) - if (txin.prevout.IsNull()) - return error("CTransaction::CheckTransaction() : prevout is null"); - } - - return true; - } - int GetSigOpCount() const { int n = 0; @@ -655,20 +617,17 @@ public: } - bool DisconnectInputs(CTxDB& txdb); bool ConnectInputs(CTxDB& txdb, map& mapTestPool, CDiskTxPos posThisTx, CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0); bool ClientConnectInputs(); - + bool CheckTransaction() const; bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL); - bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL) { CTxDB txdb("r"); return AcceptToMemoryPool(txdb, fCheckInputs, pfMissingInputs); } - protected: bool AddToMemoryPoolUnchecked(); public: @@ -690,9 +649,7 @@ public: int nIndex; // memory only - mutable bool fMerkleVerified; - mutable bool fGetCreditCached; - mutable int64 nGetCreditCached; + mutable char fMerkleVerified; CMerkleTx() @@ -710,8 +667,6 @@ public: hashBlock = 0; nIndex = -1; fMerkleVerified = false; - fGetCreditCached = false; - nGetCreditCached = 0; } IMPLEMENT_SERIALIZE @@ -723,20 +678,6 @@ public: READWRITE(nIndex); ) - int64 GetCredit(bool fUseCache=false) const - { - // Must wait until coinbase is safely deep enough in the chain before valuing it - if (IsCoinBase() && GetBlocksToMaturity() > 0) - return 0; - - // GetBalance can assume transactions in mapWallet won't change - if (fUseCache && fGetCreditCached) - return nGetCreditCached; - nGetCreditCached = CTransaction::GetCredit(); - fGetCreditCached = true; - return nGetCreditCached; - } - int SetMerkleBranch(const CBlock* pblock=NULL); int GetDepthInMainChain(int& nHeightRet) const; @@ -767,9 +708,16 @@ public: char fSpent; //// probably need to sign the order info so know it came from payer + // memory only + mutable char fDebitCached; + mutable char fCreditCached; + mutable int64 nDebitCached; + mutable int64 nCreditCached; + // memory only UI hints mutable unsigned int nTimeDisplayed; mutable int nLinesDisplayed; + mutable char fConfirmedDisplayed; CWalletTx() @@ -793,6 +741,10 @@ public: nTimeReceived = 0; fFromMe = false; fSpent = false; + fDebitCached = false; + fCreditCached = false; + nDebitCached = 0; + nCreditCached = 0; nTimeDisplayed = 0; nLinesDisplayed = 0; } @@ -810,6 +762,31 @@ public: READWRITE(fSpent); ) + int64 GetDebit() const + { + if (vin.empty()) + return 0; + if (fDebitCached) + return nDebitCached; + nDebitCached = CTransaction::GetDebit(); + fDebitCached = true; + return nDebitCached; + } + + int64 GetCredit(bool fUseCache=false) const + { + // Must wait until coinbase is safely deep enough in the chain before valuing it + if (IsCoinBase() && GetBlocksToMaturity() > 0) + return 0; + + // GetBalance can assume transactions in mapWallet won't change + if (fUseCache && fCreditCached) + return nCreditCached; + nCreditCached = CTransaction::GetCredit(); + fCreditCached = true; + return nCreditCached; + } + bool WriteToDisk() { return CWalletDB().WriteTx(GetHash(), *this); @@ -1103,7 +1080,6 @@ public: } - int64 GetBlockValue(int nHeight, int64 nFees) const; bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex); bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex); bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true); diff --git a/script.cpp b/script.cpp index 9b30d5a1a..730c4986d 100644 --- a/script.cpp +++ b/script.cpp @@ -778,6 +778,14 @@ bool EvalScript(vector >& stack, const CScript& script, co int nKeysCount = CastToBigNum(stacktop(-i)).getint(); if (nKeysCount < 0) return false; + if (nBestHeight > 84000) + { + if (nKeysCount > 20) + return false; + nOpCount += nKeysCount; + if (nOpCount > 201) + return false; + } int ikey = ++i; i += nKeysCount; if (stack.size() < i) diff --git a/serialize.h b/serialize.h index 792b9096d..2eb525b97 100644 --- a/serialize.h +++ b/serialize.h @@ -22,8 +22,8 @@ class CDataStream; class CAutoFile; static const unsigned int MAX_SIZE = 0x02000000; -static const int VERSION = 312; -static const char* pszSubVer = ".8"; +static const int VERSION = 31300; +static const char* pszSubVer = ""; @@ -85,13 +85,6 @@ enum #define READWRITE(obj) (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action)) -#define READWRITEVER(obj) \ - do { \ - READWRITE((obj)); \ - if ((obj) == 10300) \ - (obj) = 300; \ - } while (false) - @@ -163,7 +156,7 @@ template inline void Unserialize(Stream& s, bool& a, int, int=0 // inline unsigned int GetSizeOfCompactSize(uint64 nSize) { - if (nSize < UCHAR_MAX-2) return sizeof(unsigned char); + if (nSize < 253) return sizeof(unsigned char); else if (nSize <= USHRT_MAX) return sizeof(unsigned char) + sizeof(unsigned short); else if (nSize <= UINT_MAX) return sizeof(unsigned char) + sizeof(unsigned int); else return sizeof(unsigned char) + sizeof(uint64); @@ -172,30 +165,31 @@ inline unsigned int GetSizeOfCompactSize(uint64 nSize) template void WriteCompactSize(Stream& os, uint64 nSize) { - if (nSize < UCHAR_MAX-2) + if (nSize < 253) { unsigned char chSize = nSize; WRITEDATA(os, chSize); } else if (nSize <= USHRT_MAX) { - unsigned char chSize = UCHAR_MAX-2; + unsigned char chSize = 253; unsigned short xSize = nSize; WRITEDATA(os, chSize); WRITEDATA(os, xSize); } else if (nSize <= UINT_MAX) { - unsigned char chSize = UCHAR_MAX-1; + unsigned char chSize = 254; unsigned int xSize = nSize; WRITEDATA(os, chSize); WRITEDATA(os, xSize); } else { - unsigned char chSize = UCHAR_MAX; + unsigned char chSize = 255; + uint64 xSize = nSize; WRITEDATA(os, chSize); - WRITEDATA(os, nSize); + WRITEDATA(os, xSize); } return; } @@ -206,27 +200,27 @@ uint64 ReadCompactSize(Stream& is) unsigned char chSize; READDATA(is, chSize); uint64 nSizeRet = 0; - if (chSize < UCHAR_MAX-2) + if (chSize < 253) { nSizeRet = chSize; } - else if (chSize == UCHAR_MAX-2) + else if (chSize == 253) { - unsigned short nSize; - READDATA(is, nSize); - nSizeRet = nSize; + unsigned short xSize; + READDATA(is, xSize); + nSizeRet = xSize; } - else if (chSize == UCHAR_MAX-1) + else if (chSize == 254) { - unsigned int nSize; - READDATA(is, nSize); - nSizeRet = nSize; + unsigned int xSize; + READDATA(is, xSize); + nSizeRet = xSize; } else { - uint64 nSize; - READDATA(is, nSize); - nSizeRet = nSize; + uint64 xSize; + READDATA(is, xSize); + nSizeRet = xSize; } if (nSizeRet > (uint64)MAX_SIZE) throw std::ios_base::failure("ReadCompactSize() : size too large"); diff --git a/setup.nsi b/setup.nsi index 78d83d4e5..32ea5dd5b 100644 --- a/setup.nsi +++ b/setup.nsi @@ -7,7 +7,7 @@ RequestExecutionLevel highest # General Symbol Definitions !define REGKEY "SOFTWARE\$(^Name)" -!define VERSION 0.3.12 +!define VERSION 0.3.13 !define COMPANY "Bitcoin project" !define URL http://www.bitcoin.org/ @@ -42,12 +42,12 @@ Var StartMenuGroup !insertmacro MUI_LANGUAGE English # Installer attributes -OutFile bitcoin-0.3.12-win32-setup.exe +OutFile bitcoin-0.3.13-win32-setup.exe InstallDir $PROGRAMFILES\Bitcoin CRCCheck on XPStyle on ShowInstDetails show -VIProductVersion 0.3.12.0 +VIProductVersion 0.3.13.0 VIAddVersionKey ProductName Bitcoin VIAddVersionKey ProductVersion "${VERSION}" VIAddVersionKey CompanyName "${COMPANY}" diff --git a/ui.cpp b/ui.cpp index 80cf08841..800bbfdf0 100644 --- a/ui.cpp +++ b/ui.cpp @@ -103,6 +103,16 @@ int InsertLine(wxListCtrl* listCtrl, void* pdata, const wxString& str0, const wx return nIndex; } +void SetItemTextColour(wxListCtrl* listCtrl, int nIndex, const wxColour& colour) +{ + // Repaint on Windows is more flickery if the colour has ever been set, + // so don't want to set it unless it's different. Default colour has + // alpha 0 transparent, so our colours don't match using operator==. + wxColour c1 = listCtrl->GetItemTextColour(nIndex); + if (colour.Red() != c1.Red() || colour.Green() != c1.Green() || colour.Blue() != c1.Blue()) + listCtrl->SetItemTextColour(nIndex, colour); +} + void SetSelection(wxListCtrl* listCtrl, int nIndex) { int nSize = listCtrl->GetItemCount(); @@ -434,7 +444,7 @@ int CMainFrame::GetSortIndex(const string& strSort) #endif } -void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5, const wxString& str6) +void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxColour& colour, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5, const wxString& str6) { strSort = " " + strSort; // leading space to workaround wx2.9.0 ubuntu 9.10 bug long nData = *(long*)&hashKey; // where first char of hidden column is displayed @@ -470,6 +480,7 @@ void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSo m_listCtrl->SetItem(nIndex, 5, str5); m_listCtrl->SetItem(nIndex, 6, str6); m_listCtrl->SetItemData(nIndex, nData); + SetItemTextColour(m_listCtrl, nIndex, colour); } bool CMainFrame::DeleteLine(uint256 hashKey) @@ -489,9 +500,10 @@ bool CMainFrame::DeleteLine(uint256 hashKey) return nIndex != -1; } -string FormatTxStatus(const CWalletTx& wtx) +string FormatTxStatus(const CWalletTx& wtx, bool& fConfirmed) { // Status + fConfirmed = false; if (!wtx.IsFinal()) { if (wtx.nLockTime < 500000000) @@ -502,6 +514,8 @@ string FormatTxStatus(const CWalletTx& wtx) else { int nDepth = wtx.GetDepthInMainChain(); + if (nDepth >= 1 || wtx.GetDebit() > 0) + fConfirmed = true; if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) return strprintf(_("%d/offline?"), nDepth); else if (nDepth < 6) @@ -511,6 +525,12 @@ string FormatTxStatus(const CWalletTx& wtx) } } +string FormatTxStatus(const CWalletTx& wtx) +{ + bool fConfirmed; + return FormatTxStatus(wtx, fConfirmed); +} + string SingleLine(const string& strIn) { string strOut; @@ -539,7 +559,10 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) int64 nDebit = wtx.GetDebit(); int64 nNet = nCredit - nDebit; uint256 hash = wtx.GetHash(); - string strStatus = FormatTxStatus(wtx); + bool fConfirmed; + string strStatus = FormatTxStatus(wtx, fConfirmed); + wtx.fConfirmedDisplayed = fConfirmed; + wxColour colour = (fConfirmed ? wxColour(0,0,0) : wxColour(128,128,128)); map mapValue = wtx.mapValue; wtx.nLinesDisplayed = 1; nListViewUpdated++; @@ -658,12 +681,16 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) } } - InsertLine(fNew, nIndex, hash, strSort, + string strCredit = FormatMoney(nNet, true); + if (!fConfirmed) + strCredit = "[" + strCredit + "]"; + + InsertLine(fNew, nIndex, hash, strSort, colour, strStatus, nTime ? DateTimeStr(nTime) : "", SingleLine(strDescription), "", - FormatMoney(nNet, true)); + strCredit); } else { @@ -679,7 +706,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) { // Payment to self int64 nValue = wtx.vout[0].nValue; - InsertLine(fNew, nIndex, hash, strSort, + InsertLine(fNew, nIndex, hash, strSort, colour, strStatus, nTime ? DateTimeStr(nTime) : "", _("Payment to yourself"), @@ -738,7 +765,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) nTxFee = 0; } - InsertLine(fNew, nIndex, hash, strprintf("%s-%d", strSort.c_str(), nOut), + InsertLine(fNew, nIndex, hash, strprintf("%s-%d", strSort.c_str(), nOut), colour, strStatus, nTime ? DateTimeStr(nTime) : "", SingleLine(strDescription), @@ -758,7 +785,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) foreach(const CTxIn& txin, wtx.vin) fAllMine = fAllMine && txin.IsMine(); - InsertLine(fNew, nIndex, hash, strSort, + InsertLine(fNew, nIndex, hash, strSort, colour, strStatus, nTime ? DateTimeStr(nTime) : "", "", @@ -885,13 +912,17 @@ void CMainFrame::RefreshStatusColumn() continue; } CWalletTx& wtx = (*mi).second; - if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed) + bool fConfirmed; + string strStatus = FormatTxStatus(wtx, fConfirmed); + if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed || fConfirmed != wtx.fConfirmedDisplayed) { if (!InsertTransaction(wtx, false, nIndex)) m_listCtrl->DeleteItem(nIndex--); } else - m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx)); + { + m_listCtrl->SetItem(nIndex, 2, strStatus); + } } } } @@ -1772,7 +1803,7 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) { - m_staticTextVersion->SetLabel(strprintf(_("version %d.%d.%d%s beta"), VERSION/10000, (VERSION/100)%100, VERSION%100, pszSubVer)); + m_staticTextVersion->SetLabel(strprintf(_("version %s%s beta"), FormatVersion(VERSION).c_str(), pszSubVer)); // Change (c) into UTF-8 or ANSI copyright symbol wxString str = m_staticTextMain->GetLabel(); diff --git a/ui.h b/ui.h index 9769fd700..d2847c509 100644 --- a/ui.h +++ b/ui.h @@ -11,7 +11,6 @@ extern wxLocale g_locale; void HandleCtrlA(wxKeyEvent& event); -string FormatTxStatus(const CWalletTx& wtx); void UIThreadCall(boost::function0); int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent); @@ -96,7 +95,7 @@ public: void OnUIThreadCall(wxCommandEvent& event); int GetSortIndex(const string& strSort); - void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5); + void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxColour& colour, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5); bool DeleteLine(uint256 hashKey); bool InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); void RefreshListCtrl(); diff --git a/util.h b/util.h index 2e6bf2a60..09af956d7 100644 --- a/util.h +++ b/util.h @@ -416,6 +416,14 @@ inline int64 GetArg(const string& strArg, int64 nDefault) return nDefault; } +inline string FormatVersion(int nVersion) +{ + if (nVersion%100 == 0) + return strprintf("%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100); + else + return strprintf("%d.%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100, nVersion%100); +} +