Compare commits

..

1 Commits

Author SHA1 Message Date
s_nakamoto
8c9479c6bb cleanup,
catch some recoverable exceptions and continue
-- version 0.3.12 release

git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@148 1a98c847-1fd6-4fd8-948a-caf3550aa51b
2010-09-07 01:12:53 +00:00
28 changed files with 280 additions and 557 deletions

View File

@@ -184,8 +184,8 @@ public:
void deallocate(void *p, size_type n)
{
//// Bitcoin: don't know why this trips, probably a false alarm, depends on the compiler used.
//assert(false);
//// Bitcoin: can't figure out why this is tripping on a few compiles.
//assert(false);
}
size_type max_size() const {return 0;}

3
db.cpp
View File

@@ -77,6 +77,7 @@ CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL)
DB_INIT_MPOOL |
DB_INIT_TXN |
DB_THREAD |
DB_PRIVATE |
DB_RECOVER,
S_IRUSR | S_IWUSR);
if (ret > 0)
@@ -465,7 +466,7 @@ bool CTxDB::LoadBlockIndex()
CBlockIndex* pindexFork = NULL;
for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev)
{
if (pindex->nHeight < nBestHeight-2500 && !mapArgs.count("-checkblocks"))
if (pindex->nHeight < 74000 && !mapArgs.count("-checkblocks"))
break;
CBlock block;
if (!block.ReadFromDisk(pindex))

View File

@@ -11,7 +11,7 @@
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0500
#define _WIN32_WINNT 0x0400
#ifdef _WIN32_IE
#undef _WIN32_IE
#endif
@@ -99,7 +99,6 @@
#include <net/if.h>
#include <ifaddrs.h>
#include <fcntl.h>
#include <signal.h>
#endif
#ifdef BSD
#include <netinet/in.h>

View File

@@ -10,6 +10,7 @@
//////////////////////////////////////////////////////////////////////////////
//
// Shutdown
@@ -56,11 +57,6 @@ void Shutdown(void* parg)
}
}
void HandleSIGTERM(int)
{
fRequestShutdown = true;
}
@@ -134,14 +130,6 @@ bool AppInit2(int argc, char* argv[])
#ifndef __WXMSW__
umask(077);
#endif
#ifndef __WXMSW__
// Clean shutdown on SIGTERM
struct sigaction sa;
sa.sa_handler = HandleSIGTERM;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGTERM, &sa, NULL);
#endif
//
// Parameters
@@ -203,7 +191,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 %s%s beta\n", FormatVersion(VERSION).c_str(), pszSubVer);
printf("Bitcoin version %d.%d.%d%s beta\n", VERSION/10000, (VERSION/100)%100, VERSION%100, 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());

Binary file not shown.

View File

@@ -321,8 +321,8 @@ msgstr "Beim schließen &Minimieren"
#: ../../../ui.cpp:1595
#, c-format
msgid "version %s%s beta"
msgstr "Version %s%s Beta"
msgid "version 0.%d.%d beta"
msgstr "Version 0.%d.%d Beta"
#: ../../../ui.cpp:1681
msgid "Will appear as \"From: Unknown\""

Binary file not shown.

View File

@@ -350,8 +350,8 @@ msgstr "&Minimizar al cerrar"
#: ../../../ui.cpp:1610
#, c-format
msgid "version %s%s beta"
msgstr "version %s%s beta"
msgid "version %d.%d.%d beta"
msgstr "version %d.%d.%d beta"
#: ../../../ui.cpp:1696
msgid "Will appear as \"From: Unknown\""

Binary file not shown.

View File

@@ -351,8 +351,8 @@ msgstr "&Réduire à la fermeture"
#: ../../../ui.cpp:1610
#, c-format
msgid "version %s%s beta"
msgstr "version %s%s beta"
msgid "version %d.%d.%d beta"
msgstr "version %d.%d.%d beta"
#: ../../../ui.cpp:1696
msgid "Will appear as \"From: Unknown\""

Binary file not shown.

View File

@@ -319,8 +319,8 @@ msgstr "&Minimizza se chiuso"
#: ../../../ui.cpp:1595
#, c-format
msgid "version %s%s beta"
msgstr "versione %s%s beta"
msgid "version 0.%d.%d beta"
msgstr "versione 0.%d.%d beta"
#: ../../../ui.cpp:1681
msgid "Will appear as \"From: Unknown\""

Binary file not shown.

View File

@@ -320,8 +320,8 @@ msgstr "&Minimalizeer bij sluiten"
#: ../../../ui.cpp:1595
#, c-format
msgid "version %s%s beta"
msgstr "versie %s%s beta"
msgid "version 0.%d.%d beta"
msgstr "versie 0.%d.%d beta"
#: ../../../ui.cpp:1681
msgid "Will appear as \"From: Unknown\""

Binary file not shown.

View File

@@ -319,8 +319,8 @@ msgstr "&Minimizar ao fechar"
#: ../../../ui.cpp:1595
#, c-format
msgid "version %s%s beta"
msgstr "versão %s%s beta"
msgid "version 0.%d.%d beta"
msgstr "versão 0.%d.%d beta"
#: ../../../ui.cpp:1681
msgid "Will appear as \"From: Unknown\""

364
main.cpp
View File

@@ -487,56 +487,18 @@ 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");
@@ -853,7 +815,7 @@ uint256 GetOrphanRoot(const CBlock* pblock)
return pblock->GetHash();
}
int64 GetBlockValue(int nHeight, int64 nFees)
int64 CBlock::GetBlockValue(int nHeight, int64 nFees) const
{
int64 nSubsidy = 50 * COIN;
@@ -1062,11 +1024,6 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& 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;
@@ -1075,6 +1032,12 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& 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())
@@ -1411,13 +1374,9 @@ bool CBlock::CheckBlock() const
// that can be verified before saving an orphan block.
// Size limits
if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE)
if (vtx.empty() || vtx.size() > MAX_SIZE || ::GetSerializeSize(*this, SER_NETWORK) > MAX_SIZE)
return error("CheckBlock() : size limits failed");
// Check proof of work matches claimed amount
if (!CheckProofOfWork(GetHash(), nBits))
return error("CheckBlock() : proof of work failed");
// Check timestamp
if (GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
return error("CheckBlock() : block timestamp too far in the future");
@@ -1434,9 +1393,9 @@ bool CBlock::CheckBlock() const
if (!tx.CheckTransaction())
return error("CheckBlock() : CheckTransaction failed");
// Check that it's not full of nonstandard transactions
if (GetSigOpCount() > MAX_BLOCK_SIGOPS)
return error("CheckBlock() : too many nonstandard transactions");
// Check proof of work matches claimed amount
if (!CheckProofOfWork(GetHash(), nBits))
return error("CheckBlock() : proof of work failed");
// Check merkleroot
if (hashMerkleRoot != BuildMerkleTree())
@@ -1459,9 +1418,13 @@ bool CBlock::AcceptBlock()
CBlockIndex* pindexPrev = (*mi).second;
int nHeight = pindexPrev->nHeight+1;
// Check proof of work
if (nBits != GetNextWorkRequired(pindexPrev))
return error("AcceptBlock() : incorrect proof of work");
// Check size
if (nHeight > 79400 && ::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE)
return error("AcceptBlock() : over size limit");
// Check that it's not full of nonstandard transactions
if (nHeight > 79400 && GetSigOpCount() > MAX_BLOCK_SIGOPS)
return error("AcceptBlock() : too many nonstandard transactions");
// Check timestamp against prev
if (GetBlockTime() <= pindexPrev->GetMedianTimePast())
@@ -1472,6 +1435,10 @@ bool CBlock::AcceptBlock()
if (!tx.IsFinal(nHeight, GetBlockTime()))
return error("AcceptBlock() : contains a non-final transaction");
// Check proof of work
if (nBits != GetNextWorkRequired(pindexPrev))
return error("AcceptBlock() : incorrect proof of work");
// Check that the block chain matches the known block chain up to a checkpoint
if ((nHeight == 11111 && hash != uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) ||
(nHeight == 33333 && hash != uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) ||
@@ -2425,11 +2392,13 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
else if (strCommand == "getaddr")
{
// Nodes rebroadcast an addr every 24 hours
// This includes all nodes that are currently online,
// since they rebroadcast an addr every 24 hours
pfrom->vAddrToSend.clear();
int64 nSince = GetAdjustedTime() - 6 * 60 * 60; // in the last 6 hours
int64 nSince = GetAdjustedTime() - 12 * 60 * 60; // in the last 12 hours
CRITICAL_BLOCK(cs_mapAddresses)
{
unsigned int nSize = mapAddresses.size();
foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
{
if (fShutdown)
@@ -2448,12 +2417,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
CWalletTx order;
vRecv >> hashReply >> order;
if (!mapArgs.count("-allowreceivebyip") || mapArgs["-allowreceivebyip"] == "0")
{
pfrom->PushMessage("reply", hashReply, (int)2, string(""));
return true;
}
/// we have a chance to check the order here
// Keep giving the same key to the same ip until they use it
@@ -2474,12 +2437,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
vRecv >> hashReply >> wtxNew;
wtxNew.fFromMe = false;
if (!mapArgs.count("-allowreceivebyip") || mapArgs["-allowreceivebyip"] == "0")
{
pfrom->PushMessage("reply", hashReply, (int)2);
return true;
}
// Broadcast
if (!wtxNew.AcceptWalletTransaction())
{
@@ -2781,68 +2738,6 @@ void ThreadBitcoinMiner(void* parg)
printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[3]);
}
#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE)
void CallCPUID(int in, int& aret, int& cret)
{
int a, c;
asm (
"mov %2, %%eax; " // in into eax
"cpuid;"
"mov %%eax, %0;" // eax into a
"mov %%ecx, %1;" // eax into c
:"=r"(a),"=r"(c) /* output */
:"r"(in) /* input */
:"%eax","%ecx" /* clobbered register */
);
aret = a;
cret = c;
}
bool Detect128BitSSE2()
{
int a, c, nBrand;
CallCPUID(0, a, nBrand);
bool fIntel = (nBrand == 0x6c65746e); // ntel
bool fAMD = (nBrand == 0x444d4163); // cAMD
struct
{
unsigned int nStepping : 4;
unsigned int nModel : 4;
unsigned int nFamily : 4;
unsigned int nProcessorType : 2;
unsigned int nUnused : 2;
unsigned int nExtendedModel : 4;
unsigned int nExtendedFamily : 8;
}
cpu;
CallCPUID(1, a, c);
memcpy(&cpu, &a, sizeof(cpu));
int nFamily = cpu.nExtendedFamily + cpu.nFamily;
int nModel = cpu.nExtendedModel*16 + cpu.nModel;
// We need Intel Nehalem or AMD K10 or better for 128bit SSE2
// Nehalem = i3/i5/i7 and some Xeon
// K10 = Opterons with 4 or more cores, Phenom, Phenom II, Athlon II
// Intel Core i5 family 6, model 26 or 30
// Intel Core i7 family 6, model 26 or 30
// Intel Core i3 family 6, model 37
// AMD Phenom family 16, model 10
bool fUseSSE2 = ((fIntel && nFamily * 10000 + nModel >= 60026) ||
(fAMD && nFamily * 10000 + nModel >= 160010));
static bool fPrinted;
if (!fPrinted)
{
fPrinted = true;
printf("CPUID %08x family %d, model %d, stepping %d, fUseSSE2=%d\n", nBrand, nFamily, nModel, cpu.nStepping, fUseSSE2);
}
return fUseSSE2;
}
#else
bool Detect128BitSSE2() { return false; }
#endif
int FormatHashBlocks(void* pbuffer, unsigned int len)
{
unsigned char* pdata = (unsigned char*)pbuffer;
@@ -2869,40 +2764,8 @@ inline void SHA256Transform(void* pstate, void* pinput, const void* pinit)
CryptoPP::SHA256::Transform((CryptoPP::word32*)pstate, (CryptoPP::word32*)pinput);
}
//
// ScanHash scans nonces looking for a hash with at least some zero bits.
// It operates on big endian data. Caller does the byte reversing.
// All input buffers are 16-byte aligned. nNonce is usually preserved
// between calls, but periodically or if nNonce is above 0xff000000,
// the block is rebuilt and nNonce starts over at zero.
//
unsigned int ScanHash_CryptoPP(char* pmidstate, char* pblock, char* phash1, char* phash, unsigned int& nHashesDone)
{
unsigned int& nNonce = *(unsigned int*)(pblock + 12);
for (;;)
{
// Crypto++ SHA-256
// Hash pblock using pmidstate as the starting state into
// preformatted buffer phash1, then hash phash1 into phash
nNonce++;
SHA256Transform(phash1, pblock, pmidstate);
SHA256Transform(phash, phash1, pSHA256InitState);
// Return the nonce if the hash has at least some zero bits,
// caller will check if it has enough to reach the target
if (((unsigned short*)phash)[14] == 0)
return nNonce;
// If nothing found after trying for a while, return -1
if ((nNonce & 0xffff) == 0)
{
nHashesDone = 0xffff+1;
return -1;
}
}
}
extern unsigned int ScanHash_4WaySSE2(char* pmidstate, char* pblock, char* phash1, char* phash, unsigned int& nHashesDone);
static const int NPAR = 32;
extern void Double_BlockSHA256(const void* pin, void* pout, const void* pinit, unsigned int hash[8][NPAR], const void* init2);
@@ -2911,9 +2774,6 @@ void BitcoinMiner()
{
printf("BitcoinMiner started\n");
SetThreadPriority(THREAD_PRIORITY_LOWEST);
bool f4WaySSE2 = Detect128BitSSE2();
if (mapArgs.count("-4way"))
f4WaySSE2 = (mapArgs["-4way"] != "0");
CKey key;
key.MakeNewKey();
@@ -2958,7 +2818,7 @@ void BitcoinMiner()
// Add our coinbase tx as first transaction
pblock->vtx.push_back(txNew);
// Collect memory pool transactions into the block
// Collect the latest transactions into the block
int64 nFees = 0;
CRITICAL_BLOCK(cs_main)
CRITICAL_BLOCK(cs_mapTransactions)
@@ -2966,9 +2826,9 @@ void BitcoinMiner()
CTxDB txdb("r");
map<uint256, CTxIndex> mapTestPool;
vector<char> vfAlreadyAdded(mapTransactions.size());
uint64 nBlockSize = 1000;
int nBlockSigOps = 100;
bool fFoundSomething = true;
uint64 nBlockSize = 10000;
int nBlockSigOps = 100;
while (fFoundSomething)
{
fFoundSomething = false;
@@ -2981,7 +2841,7 @@ void BitcoinMiner()
if (tx.IsCoinBase() || !tx.IsFinal())
continue;
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK);
if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE_GEN)
if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE)
continue;
int nTxSigOps = tx.GetSigOpCount();
if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
@@ -3004,7 +2864,7 @@ void BitcoinMiner()
}
}
pblock->nBits = nBits;
pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees);
pblock->vtx[0].vout[0].nValue = pblock->GetBlockValue(pindexPrev->nHeight+1, nFees);
printf("Running BitcoinMiner with %d transactions in block\n", pblock->vtx.size());
@@ -3053,34 +2913,53 @@ void BitcoinMiner()
//
// Search
//
bool f4WaySSE2 = mapArgs.count("-4way");
int64 nStart = GetTime();
uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
uint256 hashbuf[2];
uint256& hash = *alignup<16>(hashbuf);
loop
{
unsigned int nHashesDone = 0;
unsigned int nNonceFound;
#ifdef FOURWAYSSE2
if (f4WaySSE2)
// tcatm's 4-way 128-bit SSE2 SHA-256
nNonceFound = ScanHash_4WaySSE2((char*)&midstate, (char*)&tmp.block + 64, (char*)&tmp.hash1, (char*)&hash, nHashesDone);
{
// tcatm's 4-way SSE2 SHA-256
tmp.block.nNonce += NPAR;
unsigned int thashbuf[9][NPAR];
unsigned int (&thash)[9][NPAR] = *alignup<16>(&thashbuf);
Double_BlockSHA256((char*)&tmp.block + 64, &tmp.hash1, &midstate, thash, pSHA256InitState);
((unsigned short*)&hash)[14] = 0xffff;
for (int j = 0; j < NPAR; j++)
{
if (thash[7][j] == 0)
{
for (int i = 0; i < sizeof(hash)/4; i++)
((unsigned int*)&hash)[i] = thash[i][j];
pblock->nNonce = ByteReverse(tmp.block.nNonce + j);
}
}
}
else
#endif
// Crypto++ SHA-256
nNonceFound = ScanHash_CryptoPP((char*)&midstate, (char*)&tmp.block + 64, (char*)&tmp.hash1, (char*)&hash, nHashesDone);
// Check if something found
if (nNonceFound != -1)
{
// Crypto++ SHA-256
tmp.block.nNonce++;
SHA256Transform(&tmp.hash1, (char*)&tmp.block + 64, &midstate);
SHA256Transform(&hash, &tmp.hash1, pSHA256InitState);
}
if (((unsigned short*)&hash)[14] == 0)
{
// Byte swap the result after preliminary check
for (int i = 0; i < sizeof(hash)/4; i++)
((unsigned int*)&hash)[i] = ByteReverse(((unsigned int*)&hash)[i]);
if (hash <= hashTarget)
{
// Found a solution
pblock->nNonce = ByteReverse(nNonceFound);
#ifdef FOURWAYSSE2
if (!f4WaySSE2)
#endif
pblock->nNonce = ByteReverse(tmp.block.nNonce);
assert(hash == pblock->GetHash());
//// debug print
@@ -3116,57 +2995,62 @@ void BitcoinMiner()
}
}
// Meter hashes/sec
static int64 nHashCounter;
if (nHPSTimerStart == 0)
// Update nTime every few seconds
const unsigned int nMask = 0xffff;
const int nHashesPerCycle = (nMask+1);
if ((tmp.block.nNonce & nMask) == 0)
{
nHPSTimerStart = GetTimeMillis();
nHashCounter = 0;
}
else
nHashCounter += nHashesDone;
if (GetTimeMillis() - nHPSTimerStart > 4000)
{
static CCriticalSection cs;
CRITICAL_BLOCK(cs)
// Meter hashes/sec
static int nCycleCounter;
if (nHPSTimerStart == 0)
{
if (GetTimeMillis() - nHPSTimerStart > 4000)
nHPSTimerStart = GetTimeMillis();
nCycleCounter = 0;
}
else
nCycleCounter++;
if (GetTimeMillis() - nHPSTimerStart > 4000)
{
static CCriticalSection cs;
CRITICAL_BLOCK(cs)
{
dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart);
nHPSTimerStart = GetTimeMillis();
nHashCounter = 0;
string strStatus = strprintf(" %.0f khash/s", dHashesPerSec/1000.0);
UIThreadCall(bind(CalledSetStatusBar, strStatus, 0));
static int64 nLogTime;
if (GetTime() - nLogTime > 30 * 60)
if (GetTimeMillis() - nHPSTimerStart > 4000)
{
nLogTime = GetTime();
printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[3], dHashesPerSec/1000.0);
dHashesPerSec = 1000.0 * nHashesPerCycle * nCycleCounter / (GetTimeMillis() - nHPSTimerStart);
nHPSTimerStart = GetTimeMillis();
nCycleCounter = 0;
string strStatus = strprintf(" %.0f khash/s", dHashesPerSec/1000.0);
UIThreadCall(bind(CalledSetStatusBar, strStatus, 0));
static int64 nLogTime;
if (GetTime() - nLogTime > 30 * 60)
{
nLogTime = GetTime();
printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[3], dHashesPerSec/1000.0);
}
}
}
}
// Check for stop or if block needs to be rebuilt
if (fShutdown)
return;
if (!fGenerateBitcoins)
return;
if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors)
return;
if (vNodes.empty())
break;
if (tmp.block.nNonce == 0)
break;
if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)
break;
if (pindexPrev != pindexBest)
break;
pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
tmp.block.nTime = ByteReverse(pblock->nTime);
}
// Check for stop or if block needs to be rebuilt
if (fShutdown)
return;
if (!fGenerateBitcoins)
return;
if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors)
return;
if (vNodes.empty())
break;
if (tmp.block.nNonce >= 0xff000000)
break;
if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)
break;
if (pindexPrev != pindexBest)
break;
// Update nTime every few seconds
pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
tmp.block.nTime = ByteReverse(pblock->nTime);
}
}
}
@@ -3206,8 +3090,6 @@ int64 GetBalance()
CWalletTx* pcoin = &(*it).second;
if (!pcoin->IsFinal() || pcoin->fSpent)
continue;
if (pcoin->GetDepthInMainChain() < 1 && pcoin->GetDebit() <= 0)
continue;
nTotal += pcoin->GetCredit(true);
}
}
@@ -3217,6 +3099,11 @@ int64 GetBalance()
}
int GetRandInt(int nMax)
{
return GetRand(nMax);
}
bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet)
{
setCoinsRet.clear();
@@ -3239,8 +3126,6 @@ bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet)
{
if (!pcoin->IsFinal() || pcoin->fSpent)
continue;
if (pcoin->GetDepthInMainChain() < 1 && pcoin->GetDebit() <= 0)
continue;
int64 n = pcoin->GetCredit();
if (n <= 0)
continue;
@@ -3362,8 +3247,7 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK
wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey));
// Fill a vout back to self with any change
int64 nChange = nValueIn - nTotalValue;
if (nChange >= CENT)
if (nValueIn > nTotalValue)
{
// Note: We use a new key here to keep it from being obvious which side is the change.
// The drawback is that by not reusing a previous key, the change may be lost if a
@@ -3382,7 +3266,7 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK
scriptChange.SetBitcoinAddress(keyRet.GetPubKey());
else
scriptChange << keyRet.GetPubKey() << OP_CHECKSIG;
wtxNew.vout.push_back(CTxOut(nChange, scriptChange));
wtxNew.vout.push_back(CTxOut(nValueIn - nTotalValue, scriptChange));
}
// Fill a vout to the payee
@@ -3403,10 +3287,6 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK
if (!SignSignature(*pcoin, wtxNew, nIn++))
return false;
// Limit size
if (::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK) >= MAX_BLOCK_SIZE_GEN/5)
return false;
// Check that enough fee is included
if (nFee < wtxNew.GetMinFee())
{

134
main.h
View File

@@ -15,7 +15,6 @@ class CWalletTx;
class CKeyItem;
static const unsigned int MAX_BLOCK_SIZE = 1000000;
static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
static const int64 COIN = 100000000;
static const int64 CENT = 1000000;
@@ -469,6 +468,44 @@ 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_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;
@@ -527,16 +564,15 @@ public:
{
// Base fee is 1 cent per kilobyte
unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
unsigned int nNewBlockSize = nBlockSize + nBytes;
int64 nMinFee = (1 + (int64)nBytes / 1000) * CENT;
// Transactions under 25K are free as long as block size is under 40K
// (about 11,000bc if made of 50bc inputs)
if (nBytes < 25000 && nNewBlockSize < 40000)
// Transactions under 60K are free as long as block size is under 80K
// (about 27,000bc if made of 50bc inputs)
if (nBytes < 60000 && nBlockSize < 80000)
nMinFee = 0;
// Transactions under 3K are free as long as block size is under 50K
if (nBytes < 3000 && nNewBlockSize < 50000)
// Transactions under 3K are free as long as block size is under 200K
if (nBytes < 3000 && nBlockSize < 200000)
nMinFee = 0;
// To limit dust spam, require a 0.01 fee if any output is less than 0.01
@@ -546,15 +582,11 @@ public:
nMinFee = CENT;
// Raise the price as the block approaches full
if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
{
if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN)
return MAX_MONEY;
nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize);
}
if (MAX_BLOCK_SIZE/2 <= nBlockSize && nBlockSize < MAX_BLOCK_SIZE)
nMinFee *= MAX_BLOCK_SIZE / (MAX_BLOCK_SIZE - nBlockSize);
if (!MoneyRange(nMinFee))
nMinFee = MAX_MONEY;
return nMinFee;
}
@@ -617,17 +649,20 @@ public:
}
bool DisconnectInputs(CTxDB& txdb);
bool ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& 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:
@@ -649,7 +684,9 @@ public:
int nIndex;
// memory only
mutable char fMerkleVerified;
mutable bool fMerkleVerified;
mutable bool fGetCreditCached;
mutable int64 nGetCreditCached;
CMerkleTx()
@@ -667,6 +704,8 @@ public:
hashBlock = 0;
nIndex = -1;
fMerkleVerified = false;
fGetCreditCached = false;
nGetCreditCached = 0;
}
IMPLEMENT_SERIALIZE
@@ -678,6 +717,20 @@ 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;
@@ -708,16 +761,9 @@ 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()
@@ -741,10 +787,6 @@ public:
nTimeReceived = 0;
fFromMe = false;
fSpent = false;
fDebitCached = false;
fCreditCached = false;
nDebitCached = 0;
nCreditCached = 0;
nTimeDisplayed = 0;
nLinesDisplayed = 0;
}
@@ -762,31 +804,6 @@ 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);
@@ -1080,6 +1097,7 @@ 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);
@@ -1167,11 +1185,9 @@ public:
CBigNum GetBlockWork() const
{
CBigNum bnTarget;
bnTarget.SetCompact(nBits);
if (bnTarget <= 0)
if (CBigNum().SetCompact(nBits) <= 0)
return 0;
return (CBigNum(1)<<256) / (bnTarget+1);
return (CBigNum(1)<<256) / (CBigNum().SetCompact(nBits)+1);
}
bool IsInMainChain() const
@@ -1453,10 +1469,10 @@ public:
//// todo: add something to note what created it (user, getnewaddress, change)
//// maybe should have a map<string, string> property map
CWalletKey(int64 nExpires=0)
CWalletKey(int64 nTimeExpiresIn=0)
{
nTimeCreated = (nExpires ? GetTime() : 0);
nTimeExpires = nExpires;
nTimeCreated = (nTimeExpiresIn ? GetTime() : 0);
nTimeExpires = nTimeExpiresIn;
}
IMPLEMENT_SERIALIZE

View File

@@ -1160,13 +1160,9 @@ void ThreadMessageHandler2(void* parg)
pnode->Release();
}
// Wait and allow messages to bunch up.
// Reduce vnThreadsRunning so StopNode has permission to exit while
// we're sleeping, but we must always check fShutdown after doing this.
// Wait and allow messages to bunch up
vnThreadsRunning[2]--;
Sleep(100);
if (fRequestShutdown)
Shutdown(NULL);
vnThreadsRunning[2]++;
if (fShutdown)
return;

24
rpc.cpp
View File

@@ -783,9 +783,8 @@ int ReadHTTPStatus(tcp::iostream& stream)
getline(stream, str);
vector<string> vWords;
boost::split(vWords, str, boost::is_any_of(" "));
if (vWords.size() < 2)
return 500;
return atoi(vWords[1].c_str());
int nStatus = atoi(vWords[1].c_str());
return nStatus;
}
int ReadHTTPHeader(tcp::iostream& stream, map<string, string>& mapHeadersRet)
@@ -919,17 +918,6 @@ string JSONRPCReply(const Value& result, const Value& error, const Value& id)
return write_string(Value(reply), false) + "\n";
}
bool ClientAllowed(const string& strAddress)
{
if (strAddress == asio::ip::address_v4::loopback().to_string())
return true;
const vector<string>& vAllow = mapMultiArgs["-rpcallowip"];
foreach(string strAllow, vAllow)
if (WildcardMatch(strAddress, strAllow))
return true;
return false;
}
@@ -974,7 +962,7 @@ void ThreadRPCServer2(void* parg)
// Bind to loopback 127.0.0.1 so the socket can only be accessed locally
boost::asio::io_service io_service;
tcp::endpoint endpoint(mapArgs.count("-rpcallowip") ? asio::ip::address_v4::any() : asio::ip::address_v4::loopback(), 8332);
tcp::endpoint endpoint(boost::asio::ip::address_v4::loopback(), 8332);
tcp::acceptor acceptor(io_service, endpoint);
loop
@@ -988,8 +976,8 @@ void ThreadRPCServer2(void* parg)
if (fShutdown)
return;
// Restrict callers by IP
if (!ClientAllowed(peer.address().to_string()))
// Shouldn't be possible for anyone else to connect, but just in case
if (peer.address().to_string() != "127.0.0.1")
continue;
// Receive request
@@ -1102,7 +1090,7 @@ Object CallRPC(const string& strMethod, const Array& params)
GetConfigFile().c_str()));
// Connect to localhost
tcp::iostream stream(GetArg("-rpcconnect", "127.0.0.1"), "8332");
tcp::iostream stream("127.0.0.1", "8332");
if (stream.fail())
throw runtime_error("couldn't connect to server");

View File

@@ -778,14 +778,6 @@ bool EvalScript(vector<vector<unsigned char> >& 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)

View File

@@ -22,8 +22,8 @@ class CDataStream;
class CAutoFile;
static const unsigned int MAX_SIZE = 0x02000000;
static const int VERSION = 31300;
static const char* pszSubVer = "";
static const int VERSION = 312;
static const char* pszSubVer = ".1";
@@ -85,6 +85,13 @@ 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)
@@ -156,7 +163,7 @@ template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0
//
inline unsigned int GetSizeOfCompactSize(uint64 nSize)
{
if (nSize < 253) return sizeof(unsigned char);
if (nSize < UCHAR_MAX-2) 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);
@@ -165,31 +172,30 @@ inline unsigned int GetSizeOfCompactSize(uint64 nSize)
template<typename Stream>
void WriteCompactSize(Stream& os, uint64 nSize)
{
if (nSize < 253)
if (nSize < UCHAR_MAX-2)
{
unsigned char chSize = nSize;
WRITEDATA(os, chSize);
}
else if (nSize <= USHRT_MAX)
{
unsigned char chSize = 253;
unsigned char chSize = UCHAR_MAX-2;
unsigned short xSize = nSize;
WRITEDATA(os, chSize);
WRITEDATA(os, xSize);
}
else if (nSize <= UINT_MAX)
{
unsigned char chSize = 254;
unsigned char chSize = UCHAR_MAX-1;
unsigned int xSize = nSize;
WRITEDATA(os, chSize);
WRITEDATA(os, xSize);
}
else
{
unsigned char chSize = 255;
uint64 xSize = nSize;
unsigned char chSize = UCHAR_MAX;
WRITEDATA(os, chSize);
WRITEDATA(os, xSize);
WRITEDATA(os, nSize);
}
return;
}
@@ -200,27 +206,27 @@ uint64 ReadCompactSize(Stream& is)
unsigned char chSize;
READDATA(is, chSize);
uint64 nSizeRet = 0;
if (chSize < 253)
if (chSize < UCHAR_MAX-2)
{
nSizeRet = chSize;
}
else if (chSize == 253)
else if (chSize == UCHAR_MAX-2)
{
unsigned short xSize;
READDATA(is, xSize);
nSizeRet = xSize;
unsigned short nSize;
READDATA(is, nSize);
nSizeRet = nSize;
}
else if (chSize == 254)
else if (chSize == UCHAR_MAX-1)
{
unsigned int xSize;
READDATA(is, xSize);
nSizeRet = xSize;
unsigned int nSize;
READDATA(is, nSize);
nSizeRet = nSize;
}
else
{
uint64 xSize;
READDATA(is, xSize);
nSizeRet = xSize;
uint64 nSize;
READDATA(is, nSize);
nSizeRet = nSize;
}
if (nSizeRet > (uint64)MAX_SIZE)
throw std::ios_base::failure("ReadCompactSize() : size too large");

View File

@@ -7,7 +7,7 @@ RequestExecutionLevel highest
# General Symbol Definitions
!define REGKEY "SOFTWARE\$(^Name)"
!define VERSION 0.3.13
!define VERSION 0.3.12
!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.13-win32-setup.exe
OutFile bitcoin-0.3.12-win32-setup.exe
InstallDir $PROGRAMFILES\Bitcoin
CRCCheck on
XPStyle on
ShowInstDetails show
VIProductVersion 0.3.13.0
VIProductVersion 0.3.12.0
VIAddVersionKey ProductName Bitcoin
VIAddVersionKey ProductVersion "${VERSION}"
VIAddVersionKey CompanyName "${COMPANY}"

View File

@@ -2,8 +2,6 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
// tcatm's 4-way 128-bit SSE2 SHA-256
#ifdef FOURWAYSSE2
#include <string.h>
@@ -15,8 +13,6 @@
#define NPAR 32
extern void DoubleBlockSHA256(const void* pin, void* pout, const void* pinit, unsigned int hash[8][NPAR], const void* init2);
static const unsigned int sha256_consts[] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, /* 0 */
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
@@ -92,54 +88,8 @@ static inline void dumpreg(__m128i x, char *msg) {
#define dumpstate()
#endif
// Align by increasing pointer, must have extra space at end of buffer
template <size_t nBytes, typename T>
T* alignup(T* p)
{
union
{
T* ptr;
size_t n;
} u;
u.ptr = p;
u.n = (u.n + (nBytes-1)) & ~(nBytes-1);
return u.ptr;
}
static const unsigned int pSHA256InitState[8] =
{0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
unsigned int ScanHash_4WaySSE2(char* pmidstate, char* pblock, char* phash1, char* phash, unsigned int& nHashesDone)
{
unsigned int& nNonce = *(unsigned int*)(pblock + 12);
for (;;)
{
nNonce += NPAR;
unsigned int thashbuf[9][NPAR];
unsigned int (&thash)[9][NPAR] = *alignup<16>(&thashbuf);
DoubleBlockSHA256(pblock, phash1, pmidstate, thash, pSHA256InitState);
for (int j = 0; j < NPAR; j++)
{
if (thash[7][j] == 0)
{
for (int i = 0; i < 32/4; i++)
((unsigned int*)phash)[i] = thash[i][j];
return nNonce + j;
}
}
if ((nNonce & 0xffff) == 0)
{
nHashesDone = 0xffff+1;
return -1;
}
}
}
void DoubleBlockSHA256(const void* pin, void* pad, const void *pre, unsigned int thash[9][NPAR], const void *init)
void Double_BlockSHA256(const void* pin, void* pad, const void *pre, unsigned int thash[9][NPAR], const void *init)
{
unsigned int* In = (unsigned int*)pin;
unsigned int* Pad = (unsigned int*)pad;

65
ui.cpp
View File

@@ -103,18 +103,6 @@ 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 (!c1.IsOk())
c1 = wxColour(0,0,0);
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();
@@ -196,7 +184,7 @@ int ThreadSafeMessageBox(const string& message, const string& caption, int style
bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent)
{
if (nFeeRequired < CENT || fDaemon)
if (nFeeRequired == 0 || fDaemon)
return true;
string strMessage = strprintf(
_("This transaction is over the size limit. You can still send it for a fee of %s, "
@@ -446,7 +434,7 @@ int CMainFrame::GetSortIndex(const string& strSort)
#endif
}
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)
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)
{
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
@@ -482,7 +470,6 @@ 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)
@@ -502,10 +489,9 @@ bool CMainFrame::DeleteLine(uint256 hashKey)
return nIndex != -1;
}
string FormatTxStatus(const CWalletTx& wtx, bool& fConfirmed)
string FormatTxStatus(const CWalletTx& wtx)
{
// Status
fConfirmed = false;
if (!wtx.IsFinal())
{
if (wtx.nLockTime < 500000000)
@@ -516,8 +502,6 @@ string FormatTxStatus(const CWalletTx& wtx, bool& fConfirmed)
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)
@@ -527,12 +511,6 @@ string FormatTxStatus(const CWalletTx& wtx, bool& fConfirmed)
}
}
string FormatTxStatus(const CWalletTx& wtx)
{
bool fConfirmed;
return FormatTxStatus(wtx, fConfirmed);
}
string SingleLine(const string& strIn)
{
string strOut;
@@ -561,10 +539,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
int64 nDebit = wtx.GetDebit();
int64 nNet = nCredit - nDebit;
uint256 hash = wtx.GetHash();
bool fConfirmed;
string strStatus = FormatTxStatus(wtx, fConfirmed);
wtx.fConfirmedDisplayed = fConfirmed;
wxColour colour = (fConfirmed ? wxColour(0,0,0) : wxColour(128,128,128));
string strStatus = FormatTxStatus(wtx);
map<string, string> mapValue = wtx.mapValue;
wtx.nLinesDisplayed = 1;
nListViewUpdated++;
@@ -683,16 +658,12 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
}
}
string strCredit = FormatMoney(nNet, true);
if (!fConfirmed)
strCredit = "[" + strCredit + "]";
InsertLine(fNew, nIndex, hash, strSort, colour,
InsertLine(fNew, nIndex, hash, strSort,
strStatus,
nTime ? DateTimeStr(nTime) : "",
SingleLine(strDescription),
"",
strCredit);
FormatMoney(nNet, true));
}
else
{
@@ -708,7 +679,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, colour,
InsertLine(fNew, nIndex, hash, strSort,
strStatus,
nTime ? DateTimeStr(nTime) : "",
_("Payment to yourself"),
@@ -767,7 +738,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
nTxFee = 0;
}
InsertLine(fNew, nIndex, hash, strprintf("%s-%d", strSort.c_str(), nOut), colour,
InsertLine(fNew, nIndex, hash, strprintf("%s-%d", strSort.c_str(), nOut),
strStatus,
nTime ? DateTimeStr(nTime) : "",
SingleLine(strDescription),
@@ -787,7 +758,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, colour,
InsertLine(fNew, nIndex, hash, strSort,
strStatus,
nTime ? DateTimeStr(nTime) : "",
"",
@@ -914,17 +885,13 @@ void CMainFrame::RefreshStatusColumn()
continue;
}
CWalletTx& wtx = (*mi).second;
bool fConfirmed;
string strStatus = FormatTxStatus(wtx, fConfirmed);
if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed || fConfirmed != wtx.fConfirmedDisplayed)
if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed)
{
if (!InsertTransaction(wtx, false, nIndex))
m_listCtrl->DeleteItem(nIndex--);
}
else
{
m_listCtrl->SetItem(nIndex, 2, strStatus);
}
m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx));
}
}
}
@@ -1805,7 +1772,7 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event)
CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent)
{
m_staticTextVersion->SetLabel(strprintf(_("version %s%s beta"), FormatVersion(VERSION).c_str(), pszSubVer));
m_staticTextVersion->SetLabel(strprintf(_("version %d.%d.%d%s beta"), VERSION/10000, (VERSION/100)%100, VERSION%100, pszSubVer));
// Change (c) into UTF-8 or ANSI copyright symbol
wxString str = m_staticTextMain->GetLabel();
@@ -2219,12 +2186,8 @@ void CSendingDialog::OnReply2(CDataStream& vRecv)
if (nRet > 0)
{
string strMessage;
if (!vRecv.empty())
vRecv >> strMessage;
if (nRet == 2)
Error(_("Recipient is not accepting transactions sent by IP address"));
else
Error(_("Transfer was not accepted"));
vRecv >> strMessage;
Error(_("Transfer was not accepted"));
//// todo: enlarge the window and enable a hidden white box to put seller's message
return;
}

3
ui.h
View File

@@ -11,6 +11,7 @@ extern wxLocale g_locale;
void HandleCtrlA(wxKeyEvent& event);
string FormatTxStatus(const CWalletTx& wtx);
void UIThreadCall(boost::function0<void>);
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);
@@ -95,7 +96,7 @@ public:
void OnUIThreadCall(wxCommandEvent& event);
int GetSortIndex(const string& strSort);
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);
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);
bool DeleteLine(uint256 hashKey);
bool InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1);
void RefreshListCtrl();

View File

@@ -11,7 +11,6 @@ bool fDebug = false;
bool fPrintToConsole = false;
bool fPrintToDebugger = false;
char pszSetDataDir[MAX_PATH] = "";
bool fRequestShutdown = false;
bool fShutdown = false;
bool fDaemon = false;
bool fCommandLine = false;
@@ -127,11 +126,6 @@ uint64 GetRand(uint64 nMax)
return (nRand % nMax);
}
int GetRandInt(int nMax)
{
return GetRand(nMax);
}
@@ -410,7 +404,7 @@ vector<unsigned char> ParseHex(const char* psz)
return vch;
}
vector<unsigned char> ParseHex(const string& str)
vector<unsigned char> ParseHex(const std::string& str)
{
return ParseHex(str.c_str());
}
@@ -478,34 +472,6 @@ const char* wxGetTranslation(const char* pszEnglish)
}
bool WildcardMatch(const char* psz, const char* mask)
{
loop
{
switch (*mask)
{
case '\0':
return (*psz == '\0');
case '*':
return WildcardMatch(psz, mask+1) || (*psz && WildcardMatch(psz+1, mask));
case '?':
if (*psz == '\0')
return false;
break;
default:
if (*psz != *mask)
return false;
break;
}
psz++;
mask++;
}
}
bool WildcardMatch(const string& str, const string& mask)
{
return WildcardMatch(str.c_str(), mask.c_str());
}
@@ -683,7 +649,7 @@ string GetDataDir()
string GetConfigFile()
{
namespace fs = boost::filesystem;
fs::path pathConfig(GetArg("-conf", "bitcoin.conf"));
fs::path pathConfig(mapArgs.count("-conf") ? mapArgs["-conf"] : string("bitcoin.conf"));
if (!pathConfig.is_complete())
pathConfig = fs::path(GetDataDir()) / pathConfig;
return pathConfig.string();
@@ -751,10 +717,13 @@ void ShrinkDebugFile()
//
// "Never go to sea with two chronometers; take one or three."
// Our three time sources are:
// Our three chronometers are:
// - System clock
// - Median of other nodes's clocks
// - The user (asking the user to fix the system clock if the first two disagree)
// - Median of other server's clocks
// - NTP servers
//
// note: NTP isn't implemented yet, so until then we just use the median
// of other nodes clocks to correct ours.
//
int64 GetTime()
{
@@ -798,7 +767,7 @@ void AddTimeData(unsigned int ip, int64 nTime)
// If nobody else has the same time as us, give a warning
bool fMatch = false;
foreach(int64 nOffset, vTimeOffsets)
if (nOffset != 0 && abs64(nOffset) < 5 * 60)
if (nOffset != 0 && abs64(nOffset) < 10 * 60)
fMatch = true;
static bool fDone;
if (!fMatch && !fDone)

28
util.h
View File

@@ -140,7 +140,6 @@ extern bool fDebug;
extern bool fPrintToConsole;
extern bool fPrintToDebugger;
extern char pszSetDataDir[MAX_PATH];
extern bool fRequestShutdown;
extern bool fShutdown;
extern bool fDaemon;
extern bool fCommandLine;
@@ -160,11 +159,9 @@ string FormatMoney(int64 n, bool fPlus=false);
bool ParseMoney(const string& str, int64& nRet);
bool ParseMoney(const char* pszIn, int64& nRet);
vector<unsigned char> ParseHex(const char* psz);
vector<unsigned char> ParseHex(const string& str);
vector<unsigned char> ParseHex(const std::string& str);
void ParseParameters(int argc, char* argv[]);
const char* wxGetTranslation(const char* psz);
bool WildcardMatch(const char* psz, const char* mask);
bool WildcardMatch(const string& str, const string& mask);
int GetFilesize(FILE* file);
void GetDataDir(char* pszDirRet);
string GetConfigFile();
@@ -175,7 +172,6 @@ string MyGetSpecialFolderPath(int nFolder, bool fCreate);
string GetDefaultDataDir();
string GetDataDir();
void ShrinkDebugFile();
int GetRandInt(int nMax);
uint64 GetRand(uint64 nMax);
int64 GetTime();
int64 GetAdjustedTime();
@@ -402,28 +398,6 @@ inline bool IsSwitchChar(char c)
#endif
}
inline string GetArg(const string& strArg, const string& strDefault)
{
if (mapArgs.count(strArg))
return mapArgs[strArg];
return strDefault;
}
inline int64 GetArg(const string& strArg, int64 nDefault)
{
if (mapArgs.count(strArg))
return atoi64(mapArgs[strArg]);
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);
}