From a790fa46f40d751307f86c37a709eb119768ce5b Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 30 Sep 2010 16:23:07 +0000 Subject: [PATCH] don't count or spend payments until they have 1 confirmation, misc cleanup, changed internal version number from 312 to 31300 -- version 0.3.13 git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@158 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- db.cpp | 2 +- init.cpp | 2 +- locale/de/LC_MESSAGES/bitcoin.mo | Bin 16116 -> 16110 bytes locale/de/LC_MESSAGES/bitcoin.po | 4 +- locale/es/LC_MESSAGES/bitcoin.mo | Bin 15040 -> 15032 bytes locale/es/LC_MESSAGES/bitcoin.po | 4 +- locale/fr/LC_MESSAGES/bitcoin.mo | Bin 15771 -> 15763 bytes locale/fr/LC_MESSAGES/bitcoin.po | 4 +- locale/it/LC_MESSAGES/bitcoin.mo | Bin 15643 -> 15637 bytes locale/it/LC_MESSAGES/bitcoin.po | 4 +- locale/nl/LC_MESSAGES/bitcoin.mo | Bin 14946 -> 14940 bytes locale/nl/LC_MESSAGES/bitcoin.po | 4 +- locale/pt/LC_MESSAGES/bitcoin.mo | Bin 15684 -> 15678 bytes locale/pt/LC_MESSAGES/bitcoin.po | 4 +- main.cpp | 63 +++++++++++++++---- main.h | 100 ++++++++++++------------------- script.cpp | 8 +++ serialize.h | 48 +++++++-------- setup.nsi | 6 +- ui.cpp | 53 ++++++++++++---- ui.h | 3 +- util.h | 8 +++ 22 files changed, 187 insertions(+), 130 deletions(-) diff --git a/db.cpp b/db.cpp index df500cad..a7c18a6f 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 95204ad3..45d79d71 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 5d7eeb2b873101f76bcf96a195d47dd6ce5e7758..a9ead65cc7ead136e97b0220bbe6ccea34233e65 100644 GIT binary patch delta 1450 zcmXZcOGwmF6vy#nKF7DIH7aSPj+*&O9j!DXdk8IxAc&&KGO9&IXpo^!QAB}34+x47 zH)TSBI8c&E3yU%cr7S62w5U+Q3bKVz+4tA~zxv#B{oi}fIromUZQt5@JHi7=X4aE! zb}Ynf0ON=Ya?Ms_6~^L8T!!tq5WCQWL5##fH-3&@;t@>5Nest1Ou%{6x&)uIZ<@~n z|0jG*XyZ~;LUkB}J24p>Pzz6C6b9V*5-uUW?#8_sPy7TUa2S=qC~DvL?))UC5r6ju zoP#`hW*JPRq94mp6&yizparAxq8ndB9n^_A_z=_a4N|1dpbARPcMkTUI#}(x8&?pw z1{kQqZdB_BPz#4q2Tx!MPN6dXi)y8}z)3tG)qx7s`W>kK_TyS?#z^c%70~bgeF&9k zV4Q(k{Rj1-hqR(F3DuEwRO|exgX=LGci}cXh#m~O^MkmO_$4mJU#R`#3h5GWEDiNW zUhokG2J909-O&u{!=KI{Y#y~iY>|^t4yrRn$UC+5cpMwu`M0Qwz9O|)Y_S=)V186V z`*0%(97ZMnpv0`4^X)eSB~V)GR*LFGJ+hZ=N8N2Zw&N{)%tqcar;^cC&ecqzt}3+L zNz{v4SBUE5W{kxHScxaFnDgx}10^tq(fAR=@Cz=&Y1G1y3bO?mkExi1n$N?dSb?gv z6SYq_CSo5Z;}B}yI4ZFj46I`iMLHB^TTly6qc%E^YH0`R4fMJ5&yZh`y+&QxENY#8 zIyxu@Q!xwUuoCrM9j4$mR7V>9^j~*+mWc?wf$?}7N3aKLXmv{!-5`EcZT182@ZU+5 zU0Gwc2|KYBKjU(~Z{X>xgBNPdw&G>f!S7IyZyNPRLTl;2GA*ig?ywH^xb~tJoI}0t zo0y4RsGs3e%)$?--~Sx$!A#nz{m!^vMXkSwTG#8wuTXDnEQ*0zI}!B6-1mm%Hsv-2 R`?E_jqBUB&;ZSpf{R7xmpc4Q9 delta 1456 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 diff --git a/locale/fr/LC_MESSAGES/bitcoin.po b/locale/fr/LC_MESSAGES/bitcoin.po index 735914cf..09b7e37a 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 2ce12e2fb619f84a5a9a9f57b013eea36f210df9..73979c78c4e7809ef101520d16feeb5b4585756f 100644 GIT binary patch delta 1450 zcmXZcSxD4T6vy$Sxy_7AZt2))BkpM`n&nbqk_9G+82S`Ah0uc!i6UgnJV&Bb^w35S z5%y3hLWt1B*0C^SpL9Mp5=sP}3M zExbK(l!<&MPNEh*kBN8*wcs_>3-{5BkKOSElCw?Yb^`A2%NWi4I_|_R)Oy|`Cm}!X zVH_+9I~z7Kk;X(TmSG50`3NeZd#D7)Fa{^w-=|QC&tfjFxZ{Lkr{XHq#!aXV+gO@(k*#I_Uh=rz62?eU0iYjmy z;}%rnA=J?fy52+;GLAICo?{;S+jjyl##B2dqY?_BD$PZ8qyZ!G1nM(vLEW8h)KT=I zj&KHbr0-FM%%c)o!c<&Gy&t=u{x=b16R6T|R3am&7jL5~c!=uEYt+JX?))OgGu}Ww zA6erh%B^turc*7k(Lsc+~ zI@?dEyYLH(G4c=>6HBoRThWh?P|v+Wy}y9!><`y9RL8dB2-JbdNsn(VGpeA!pnq~I OuhZ{U6g<;25VHS$i=7St delta 1456 zcmXZc+e=hY6vy$UHR_D_TX}7i@tWo}%hIAU$s&^?lzPgv5DI!|2(-)e2S{RMFBL@) zCA}D9L4;8Wkr0JMBpHNsfiRR_M9`@3&vQWd?6v3Yz1Ld%9EbXD^o{g;LTP3;95A~S zVfGv|iMJJ+ZN?6a#{ta1TbPbdFc#lp3{IgJXD}IOF$e!*6lN8fC1O76xoXt9h9V2C zOzdW&fQbXBjn85NhEN+`K`pq0J{)%AQ6y&@!<7Ww-)GUo`~oK7GHSp0Vke;-^b-e) zL(YLsOsErWSdQJO$_G&i-9{zw5TkI^{rwp#@d?bwIX6x!aVoAu9o&pM@UUwT%ZRUq z7%0ORr~@Zat@?^Ocplf`66Ru7sk31{suO!qtv-Ztcm`AO0;)3u=*2LqlVg~Q?{Nc$ zzA^AJNM3IijoBE30o0wBqZTxyHaLPlJcS4G9P0Tu?))UGgI`b`@lxhmEW-ibu_nwS z{=h?=7qU49tC?6pwRQ9R3Txc3HB5NoNqrE_|RMHn1)KokE*l))sgKOiThBWVJjwK7wRg4s4IMp zy3%*3LZ(m&&0s1npw{~~(*Ioy@))SnE>t3esD(FC72HF0<`rt=Nq2r4YbKn zY%$wUT#M)NGS1;LuEN=^PGR$?%5xi>E2>6)jx7!JKaD{T6MBg*Vm1!B@gr0P6R5lW zi25piV+nd1=^j>K2ex4*-bX$661Dy_s!uj!x)DLT@Ry| zb`NHwbDSVZa1k}(9n{`Fzzz5uy%^1C>i6MN%tDp08kJZpj&p_%peo}pv56IfBiMolz{oUHi3?AJR{I4euY};JgR>IH9=g3-Rm4oqFsf$Uyng-MpdQ_ z)3Fbg_z>#(3pk0_@jdRThLAKTk&!9d|K^|6GGL_QfJpDa+h; vEh@21sEM~l&LnhtJY$ici6tJ7iRAhQ(xO8>p`OT8IwkqXL(qQ|~J{(tzhpEL8HojG%6c0WfKqm!-P*h(|I zQf$`cF}s5qw3ABAYA}d?Y{d{Bz!expA6~!|yo%X4hDrDUHBTJVaK`n$>jJK&|67U0 zER(<+b|%chEZW7WiK|fwG@vHhgR5}A+dl1j4mJKFdT|7m=&0MCzyjJ2F&*EbHZ&iO znN<=j)1ie*);SARq9$y>RBS@+s2xl32a)E7Rw@4q6C{o=!mxf`7Eg{TA~xDo3y8IQW2!W7#5 zn2)g-L4e>UYQaaSvwen*_!d(znc38ziL0>yRl@D4#5!@3JJgM;Od#SU7D2tQK;5-Q z)KPXg{V_XCpwgYhejGwokKhcM&!R5hu5u^SPSgY^Farlsi4CJlcMG-96C_uAg&ep2bo&Dp z&cY!~q(6+ROeyL}c47kSTML1XpbeF27q(#^YNt<8M=*naoW(5sgevI|SKZ_tw1cQh zb)rgr9#io$7UC#sV^bK@i#G(i#UD^RT}Jg=m9sz^>a2?}9qUln9?9-jDk@pP`=ZLI0;jdt08LDQ0( diff --git a/locale/nl/LC_MESSAGES/bitcoin.po b/locale/nl/LC_MESSAGES/bitcoin.po index cfb05fb3..20e8de1d 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 fc97f3956151a84d4bbdd01cb7540df4c7530a84..e432d97ee0b05a4712e0f93d5435091d7b0264b8 100644 GIT binary patch delta 1450 zcmXZcOGwmF6vy$C`Is3sU-`BgQ>U?fq-AB6R*IFHu>XiHqpRe}Ry* z@Ww4>>j~uJeyl_t5%*8=nsuEaV#f*RlB#_wP@{Rg-i$1oFr;|Mhtwauxe ziGtO6A^Sl?Z#0iOzyj(GS5O)76q-d~CMq-8s7#b%2iBu9IEsFpLSmQGjEtj-auW3fi+B#Bx0_XPlXg^mpv1Y+80w8@Q3wBn zx_L~gV-R)G8YCHZ6bsnj+Gr@H_go*L2EM>7eB;JHV;KEu)JES?MY@bF=-uHwMH~9) zUqr3jg^73_lkh%j{t$)^(D+1ydb0SP&ct%mo7P||9z$)^gj%o-^~RS_8S6uhe}dZJ z6{^T4Fa~FEwYE?PSwcOLuZ;X_LUEas@@mu@*Wr6Sg^8p(u!{|_e7EDFJqS=8;zmXn?}uFL1oIzkBj=LsEp)#Xe7`m81P2-r-kRW=CuyI&IzUa L)bckrwVk&AgNUBs delta 1456 zcmXZcNl4XE6vy$?;Ox`#si|c?^EstC<&oO5u zkVAkmR)TSO47G7HCg5d^#+#@G?x7ZVh(Ubn^@maOzM#f^$F(?(N?;blaRCEpxsJPV zX0DkkQHXo73YCb1ns^sA@exK~rx)+ReERRuk3VrU&U^n)&NGXrA4FBI9FwsgHLuB` zp^~+sHhPTfum^SW0aRk2Q6-&3Ex3eQ$j2(GKoAwLLnU$o`Pe1?MBxKeyaP3_50$7h zN<$}`#R#0kNL<8JT(i|pFx|5lqli~wJsv`hZ};L)Fq3{aZov`Uh<|X1Hx^yszNN9k zm3fZ+qM>e6`Z6M6@OFeo@fMh$J409|DsMF zU*=kXI%q9Y3_Fa4>~AeJRMKaj&rt*4;wJpy#lPWd`je=QW>AlG3D0BfcK0e;Fq-~# z)Vgh$fcMdlU8wm3=Nv zM>dABIE5>33zf(s>WX|J>aPi9A-Ci;s5?G_pRf@VD0Ti0Ho(fAt_OCxi8bstJIJ`x zcn)9S5T@>NzYRZ78~sMTnS=^Au>#cFsIH*?Ni>=X=oju92CyAM9p7DRVtPr7xmLn70HdHkw~MsH!7wpC8DG#`xKwvzAPuz M=XC-no3Aw4e}NUC(*OVf diff --git a/locale/pt/LC_MESSAGES/bitcoin.po b/locale/pt/LC_MESSAGES/bitcoin.po index c0e4fd65..2e5ec530 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 10931f9d..a70dd7cc 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 95e946a8..c5a0127c 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 9b30d5a1..730c4986 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 792b9096..2eb525b9 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 78d83d4e..32ea5dd5 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 80cf0884..800bbfdf 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 9769fd70..d2847c50 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 2e6bf2a6..09af956d 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); +} +