aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/init.cpp40
-rw-r--r--src/main.cpp209
-rw-r--r--src/main.h74
-rw-r--r--src/net.cpp3
-rw-r--r--src/net.h1
-rw-r--r--src/noui.cpp4
-rw-r--r--src/qt/addressbookpage.cpp2
-rw-r--r--src/qt/addressbookpage.h2
-rw-r--r--src/qt/bitcoin.cpp11
-rw-r--r--src/qt/bitcoinstrings.cpp9
-rw-r--r--src/qt/clientmodel.cpp7
-rw-r--r--src/qt/forms/optionsdialog.ui34
-rw-r--r--src/qt/forms/overviewpage.ui3
-rw-r--r--src/qt/forms/signverifymessagedialog.ui14
-rw-r--r--src/qt/locale/bitcoin_en.ts225
-rw-r--r--src/qt/optionsdialog.cpp27
-rw-r--r--src/qt/optionsdialog.h1
-rw-r--r--src/qt/optionsmodel.cpp18
-rw-r--r--src/qt/optionsmodel.h1
-rw-r--r--src/qt/qtipcserver.cpp15
-rw-r--r--src/qt/qtipcserver.h10
-rw-r--r--src/qt/rpcconsole.cpp9
-rw-r--r--src/qt/signverifymessagedialog.cpp4
-rw-r--r--src/qt/signverifymessagedialog.h4
-rw-r--r--src/rpcmining.cpp41
-rw-r--r--src/test/miner_tests.cpp45
-rw-r--r--src/test/util_tests.cpp8
-rw-r--r--src/util.cpp97
-rw-r--r--src/util.h2
-rw-r--r--src/walletdb.cpp2
30 files changed, 592 insertions, 330 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 74533e49e1..29062452cd 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -258,7 +258,7 @@ std::string HelpMessage()
" -onlynet=<net> " + _("Only connect to nodes in network <net> (IPv4, IPv6 or Tor)") + "\n" +
" -discover " + _("Discover own IP address (default: 1 when listening and no -externalip)") + "\n" +
" -irc " + _("Find peers using internet relay chat (default: 0)") + "\n" +
- " -checkpoints " + _("Lock in block chain with compiled-in checkpoints (default: 1)") + "\n" +
+ " -checkpoints " + _("Only accept block chain matching built-in checkpoints (default: 1)") + "\n" +
" -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n" +
" -bind=<addr> " + _("Bind to given address and always listen on it. Use [host]:port notation for IPv6") + "\n" +
" -dnsseed " + _("Find peers using DNS lookup (default: 1 unless -connect)") + "\n" +
@@ -300,8 +300,8 @@ std::string HelpMessage()
" -rescan " + _("Rescan the block chain for missing wallet transactions") + "\n" +
" -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + "\n" +
" -checkblocks=<n> " + _("How many blocks to check at startup (default: 2500, 0 = all)") + "\n" +
- " -checklevel=<n> " + _("How thorough the block verification is (0-6, default: 1)") + "\n" +
- " -loadblock=<file> " + _("Imports blocks from external blk000?.dat file") + "\n" +
+ " -checklevel=<n> " + _("How thorough the block verification is (0-4, default: 3)") + "\n" +
+ " -loadblock=<file> " + _("Imports blocks from external blk000??.dat file") + "\n" +
" -reindex " + _("Rebuild blockchain index from current blk000??.dat files") + "\n" +
"\n" + _("Block creation options:") + "\n" +
@@ -571,7 +571,7 @@ bool AppInit2()
printf("Bitcoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str());
printf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
if (!fLogTimestamps)
- printf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%dT%H:%M:%S", GetTime()).c_str());
+ printf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str());
printf("Default data directory %s\n", GetDefaultDataDir().string().c_str());
printf("Used data directory %s\n", strDataDir.c_str());
std::ostringstream strErrors;
@@ -729,6 +729,33 @@ bool AppInit2()
return InitError(msg);
}
+ // Upgrading to 0.8; hard-link the old blknnnn.dat files into /blocks/
+ filesystem::path blocksDir = GetDataDir() / "blocks";
+ if (!filesystem::exists(blocksDir))
+ {
+ filesystem::create_directories(blocksDir);
+ bool linked = false;
+ for (unsigned int i = 1; i < 10000; i++) {
+ filesystem::path source = GetDataDir() / strprintf("blk%04u.dat", i);
+ if (!filesystem::exists(source)) break;
+ filesystem::path dest = blocksDir / strprintf("blk%05u.dat", i-1);
+ try {
+ filesystem::create_hard_link(source, dest);
+ printf("Hardlinked %s -> %s\n", source.string().c_str(), dest.string().c_str());
+ linked = true;
+ } catch (filesystem::filesystem_error & e) {
+ // Note: hardlink creation failing is not a disaster, it just means
+ // blocks will get re-downloaded from peers.
+ printf("Error hardlinking blk%04u.dat : %s\n", i, e.what());
+ break;
+ }
+ }
+ if (linked)
+ {
+ fReindex = true;
+ }
+ }
+
// cache size calculations
size_t nTotalCache = GetArg("-dbcache", 25) << 20;
if (nTotalCache < (1 << 22))
@@ -752,7 +779,10 @@ bool AppInit2()
pblocktree->WriteReindexing(true);
if (!LoadBlockIndex())
- return InitError(_("Error loading blkindex.dat"));
+ return InitError(_("Error loading block/coin databases"));
+
+ if (!VerifyDB())
+ return InitError(_("Corrupted database detected. Please restart the client with -reindex."));
// as LoadBlockIndex can take several minutes, it's possible the user
// requested to kill bitcoin-qt during the last operation. If so, exit.
diff --git a/src/main.cpp b/src/main.cpp
index 96bdabd586..cb7975af0a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -45,7 +45,7 @@ bool fReindex = false;
bool fBenchmark = false;
unsigned int nCoinCacheSize = 5000;
-CMedianFilter<int> cPeerBlockCounts(5, 0); // Amount of blocks that other nodes claim to have
+CMedianFilter<int> cPeerBlockCounts(8, 0); // Amount of blocks that other nodes claim to have
map<uint256, CBlock*> mapOrphanBlocks;
multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
@@ -467,28 +467,21 @@ CTransaction::GetLegacySigOpCount() const
int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
{
- if (fClient)
- {
- if (hashBlock == 0)
- return 0;
- }
- else
- {
- CBlock blockTmp;
-
- if (pblock == NULL) {
- CCoins coins;
- if (pcoinsTip->GetCoins(GetHash(), coins)) {
- CBlockIndex *pindex = FindBlockByHeight(coins.nHeight);
- if (pindex) {
- if (!blockTmp.ReadFromDisk(pindex))
- return 0;
- pblock = &blockTmp;
- }
+ CBlock blockTmp;
+
+ if (pblock == NULL) {
+ CCoins coins;
+ if (pcoinsTip->GetCoins(GetHash(), coins)) {
+ CBlockIndex *pindex = FindBlockByHeight(coins.nHeight);
+ if (pindex) {
+ if (!blockTmp.ReadFromDisk(pindex))
+ return 0;
+ pblock = &blockTmp;
}
}
+ }
- if (pblock) {
+ if (pblock) {
// Update the tx's hashBlock
hashBlock = pblock->GetHash();
@@ -506,7 +499,6 @@ int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
// Fill in merkle branch
vMerkleBranch = pblock->GetMerkleBranch(nIndex);
- }
}
// Is the tx in a block that's in the main chain
@@ -915,16 +907,7 @@ int CMerkleTx::GetBlocksToMaturity() const
bool CMerkleTx::AcceptToMemoryPool(bool fCheckInputs)
{
- if (fClient)
- {
- if (!IsInMainChain() && !ClientCheckInputs())
- return false;
- return CTransaction::AcceptToMemoryPool(false);
- }
- else
- {
- return CTransaction::AcceptToMemoryPool(fCheckInputs);
- }
+ return CTransaction::AcceptToMemoryPool(fCheckInputs);
}
@@ -1187,11 +1170,11 @@ void static InvalidChainFound(CBlockIndex* pindexNew)
}
printf("InvalidChainFound: invalid block=%s height=%d work=%s date=%s\n",
BlockHashStr(pindexNew->GetBlockHash()).c_str(), pindexNew->nHeight,
- pindexNew->bnChainWork.ToString().c_str(), DateTimeStrFormat("%Y-%m-%dT%H:%M:%S",
+ pindexNew->bnChainWork.ToString().c_str(), DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
pindexNew->GetBlockTime()).c_str());
printf("InvalidChainFound: current best=%s height=%d work=%s date=%s\n",
BlockHashStr(hashBestChain).c_str(), nBestHeight, bnBestChainWork.ToString().c_str(),
- DateTimeStrFormat("%Y-%m-%dT%H:%M:%S", pindexBest->GetBlockTime()).c_str());
+ DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexBest->GetBlockTime()).c_str());
if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6)
printf("InvalidChainFound: Warning: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.\n");
}
@@ -1464,23 +1447,24 @@ bool CTransaction::ClientCheckInputs() const
-bool CBlock::DisconnectBlock(CBlockIndex *pindex, CCoinsViewCache &view)
+bool CBlock::DisconnectBlock(CBlockIndex *pindex, CCoinsViewCache &view, bool *pfClean)
{
assert(pindex == view.GetBestBlock());
+ if (pfClean)
+ *pfClean = false;
+
+ bool fClean = true;
+
CBlockUndo blockUndo;
- {
- CDiskBlockPos pos = pindex->GetUndoPos();
- if (pos.IsNull())
- return error("DisconnectBlock() : no undo data available");
- FILE *file = OpenUndoFile(pos, true);
- if (file == NULL)
- return error("DisconnectBlock() : undo file not available");
- CAutoFile fileUndo(file, SER_DISK, CLIENT_VERSION);
- fileUndo >> blockUndo;
- }
+ CDiskBlockPos pos = pindex->GetUndoPos();
+ if (pos.IsNull())
+ return error("DisconnectBlock() : no undo data available");
+ if (!blockUndo.ReadFromDisk(pos, pindex->pprev->GetBlockHash()))
+ return error("DisconnectBlock() : failure reading undo data");
- assert(blockUndo.vtxundo.size() + 1 == vtx.size());
+ if (blockUndo.vtxundo.size() + 1 != vtx.size())
+ return error("DisconnectBlock() : block and undo data inconsistent");
// undo transactions in reverse order
for (int i = vtx.size() - 1; i >= 0; i--) {
@@ -1488,13 +1472,15 @@ bool CBlock::DisconnectBlock(CBlockIndex *pindex, CCoinsViewCache &view)
uint256 hash = tx.GetHash();
// check that all outputs are available
- if (!view.HaveCoins(hash))
- return error("DisconnectBlock() : outputs still spent? database corrupted");
+ if (!view.HaveCoins(hash)) {
+ fClean = fClean && error("DisconnectBlock() : outputs still spent? database corrupted");
+ view.SetCoins(hash, CCoins());
+ }
CCoins &outs = view.GetCoins(hash);
CCoins outsBlock = CCoins(tx, pindex->nHeight);
if (outs != outsBlock)
- return error("DisconnectBlock() : added transaction mismatch? database corrupted");
+ fClean = fClean && error("DisconnectBlock() : added transaction mismatch? database corrupted");
// remove outputs
outs = CCoins();
@@ -1502,24 +1488,27 @@ bool CBlock::DisconnectBlock(CBlockIndex *pindex, CCoinsViewCache &view)
// restore inputs
if (i > 0) { // not coinbases
const CTxUndo &txundo = blockUndo.vtxundo[i-1];
- assert(txundo.vprevout.size() == tx.vin.size());
+ if (txundo.vprevout.size() != tx.vin.size())
+ return error("DisconnectBlock() : transaction and undo data inconsistent");
for (unsigned int j = tx.vin.size(); j-- > 0;) {
const COutPoint &out = tx.vin[j].prevout;
const CTxInUndo &undo = txundo.vprevout[j];
CCoins coins;
view.GetCoins(out.hash, coins); // this can fail if the prevout was already entirely spent
- if (coins.IsPruned()) {
- if (undo.nHeight == 0)
- return error("DisconnectBlock() : undo data doesn't contain tx metadata? database corrupted");
+ if (undo.nHeight != 0) {
+ // undo data contains height: this is the last output of the prevout tx being spent
+ if (!coins.IsPruned())
+ fClean = fClean && error("DisconnectBlock() : undo data overwriting existing transaction");
+ coins = CCoins();
coins.fCoinBase = undo.fCoinBase;
coins.nHeight = undo.nHeight;
coins.nVersion = undo.nVersion;
} else {
- if (undo.nHeight != 0)
- return error("DisconnectBlock() : undo data contains unneeded tx metadata? database corrupted");
+ if (coins.IsPruned())
+ fClean = fClean && error("DisconnectBlock() : undo data adding output to missing transaction");
}
if (coins.IsAvailable(out.n))
- return error("DisconnectBlock() : prevout output not spent? database corrupted");
+ fClean = fClean && error("DisconnectBlock() : undo data overwriting existing output");
if (coins.vout.size() < out.n+1)
coins.vout.resize(out.n+1);
coins.vout[out.n] = undo.txout;
@@ -1532,7 +1521,12 @@ bool CBlock::DisconnectBlock(CBlockIndex *pindex, CCoinsViewCache &view)
// move best block pointer to prevout block
view.SetBestBlock(pindex->pprev);
- return true;
+ if (pfClean) {
+ *pfClean = fClean;
+ return true;
+ } else {
+ return fClean;
+ }
}
void static FlushBlockFile()
@@ -1651,9 +1645,9 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJust
{
if (pindex->GetUndoPos().IsNull()) {
CDiskBlockPos pos;
- if (!FindUndoPos(pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 8))
+ if (!FindUndoPos(pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
return error("ConnectBlock() : FindUndoPos failed");
- if (!blockundo.WriteToDisk(pos))
+ if (!blockundo.WriteToDisk(pos, pindex->pprev->GetBlockHash()))
return error("ConnectBlock() : CBlockUndo::WriteToDisk failed");
// update nUndoPos in block index
@@ -1828,7 +1822,7 @@ bool SetBestChain(CBlockIndex* pindexNew)
nTransactionsUpdated++;
printf("SetBestChain: new best=%s height=%d work=%s tx=%lu date=%s\n",
BlockHashStr(hashBestChain).c_str(), nBestHeight, bnBestChainWork.ToString().c_str(), (unsigned long)pindexNew->nChainTx,
- DateTimeStrFormat("%Y-%m-%dT%H:%M:%S", pindexBest->GetBlockTime()).c_str());
+ DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexBest->GetBlockTime()).c_str());
// Check the version of the last 100 blocks to see if we need to upgrade:
if (!fIsInitialDownload)
@@ -2375,38 +2369,79 @@ bool static LoadBlockIndexDB()
}
printf("LoadBlockIndex(): hashBestChain=%s height=%d date=%s\n",
BlockHashStr(hashBestChain).c_str(), nBestHeight,
- DateTimeStrFormat("%Y-%m-%dT%H:%M:%S", pindexBest->GetBlockTime()).c_str());
+ DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexBest->GetBlockTime()).c_str());
+
+ return true;
+}
+
+bool VerifyDB() {
+ if (pindexBest == NULL || pindexBest->pprev == NULL)
+ return true;
// Verify blocks in the best chain
- int nCheckLevel = GetArg("-checklevel", 1);
+ int nCheckLevel = GetArg("-checklevel", 3);
int nCheckDepth = GetArg( "-checkblocks", 2500);
if (nCheckDepth == 0)
nCheckDepth = 1000000000; // suffices until the year 19000
if (nCheckDepth > nBestHeight)
nCheckDepth = nBestHeight;
+ nCheckLevel = std::max(0, std::min(4, nCheckLevel));
printf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
- CBlockIndex* pindexFork = NULL;
+ CCoinsViewCache coins(*pcoinsTip, true);
+ CBlockIndex* pindexState = pindexBest;
+ CBlockIndex* pindexFailure = NULL;
+ int nGoodTransactions = 0;
for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev)
{
if (fRequestShutdown || pindex->nHeight < nBestHeight-nCheckDepth)
break;
CBlock block;
+ // check level 0: read from disk
if (!block.ReadFromDisk(pindex))
- return error("LoadBlockIndex() : block.ReadFromDisk failed");
+ return error("VerifyDB() : *** block.ReadFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
// check level 1: verify block validity
- if (nCheckLevel>0 && !block.CheckBlock())
- {
- printf("LoadBlockIndex() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
- pindexFork = pindex->pprev;
+ if (nCheckLevel >= 1 && !block.CheckBlock())
+ return error("VerifyDB() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
+ // check level 2: verify undo validity
+ if (nCheckLevel >= 2 && pindex) {
+ CBlockUndo undo;
+ CDiskBlockPos pos = pindex->GetUndoPos();
+ if (!pos.IsNull()) {
+ if (!undo.ReadFromDisk(pos, pindex->pprev->GetBlockHash()))
+ return error("VerifyDB() : *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
+ }
+ }
+ // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
+ if (nCheckLevel >= 3 && pindex == pindexState && (coins.GetCacheSize() + pcoinsTip->GetCacheSize()) <= 2*nCoinCacheSize + 32000) {
+ bool fClean = true;
+ if (!block.DisconnectBlock(pindex, coins, &fClean))
+ return error("VerifyDB() : *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
+ pindexState = pindex->pprev;
+ if (!fClean) {
+ nGoodTransactions = 0;
+ pindexFailure = pindex;
+ } else
+ nGoodTransactions += block.vtx.size();
}
- // TODO: stronger verifications
}
- if (pindexFork && !fRequestShutdown)
- {
- // TODO: reorg back
- return error("LoadBlockIndex(): chain database corrupted");
+ if (pindexFailure)
+ return error("VerifyDB() : *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", pindexBest->nHeight - pindexFailure->nHeight + 1, nGoodTransactions);
+
+ // check level 4: try reconnecting blocks
+ if (nCheckLevel >= 4) {
+ CBlockIndex *pindex = pindexState;
+ while (pindex != pindexBest && !fRequestShutdown) {
+ pindex = pindex->pnext;
+ CBlock block;
+ if (!block.ReadFromDisk(pindex))
+ return error("VerifyDB() : *** block.ReadFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
+ if (!block.ConnectBlock(pindex, coins))
+ return error("VerifyDB() : *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
+ }
}
+ printf("No coin database inconsistencies in last %i blocks (%i transactions)\n", pindexBest->nHeight - pindexState->nHeight, nGoodTransactions);
+
return true;
}
@@ -2538,7 +2573,7 @@ void PrintBlockTree()
printf("%d (blk%05u.dat:0x%x) %s tx %"PRIszu"",
pindex->nHeight,
pindex->GetBlockPos().nFile, pindex->GetBlockPos().nPos,
- DateTimeStrFormat("%Y-%m-%dT%H:%M:%S", block.GetBlockTime()).c_str(),
+ DateTimeStrFormat("%Y-%m-%d %H:%M:%S", block.GetBlockTime()).c_str(),
block.vtx.size());
PrintWallets(block);
@@ -3732,12 +3767,13 @@ public:
}
};
-CBlock* CreateNewBlock(CReserveKey& reservekey)
+CBlockTemplate* CreateNewBlock(CReserveKey& reservekey)
{
// Create new block
- auto_ptr<CBlock> pblock(new CBlock());
- if (!pblock.get())
+ auto_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate());
+ if(!pblocktemplate.get())
return NULL;
+ CBlock *pblock = &pblocktemplate->block; // pointer for convenience
// Create coinbase tx
CTransaction txNew;
@@ -3748,6 +3784,8 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
// Add our coinbase tx as first transaction
pblock->vtx.push_back(txNew);
+ pblocktemplate->vTxFees.push_back(-1); // updated at end
+ pblocktemplate->vTxSigOps.push_back(-1); // updated at end
// Largest block you're willing to create:
unsigned int nBlockMaxSize = GetArg("-blockmaxsize", MAX_BLOCK_SIZE_GEN/2);
@@ -3925,6 +3963,8 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
// Added
pblock->vtx.push_back(tx);
+ pblocktemplate->vTxFees.push_back(nTxFees);
+ pblocktemplate->vTxSigOps.push_back(nTxSigOps);
nBlockSize += nTxSize;
++nBlockTx;
nBlockSigOps += nTxSigOps;
@@ -3959,13 +3999,15 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
printf("CreateNewBlock(): total size %"PRI64u"\n", nBlockSize);
pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees);
+ pblocktemplate->vTxFees[0] = -nFees;
// Fill in header
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
pblock->UpdateTime(pindexPrev);
- pblock->nBits = GetNextWorkRequired(pindexPrev, pblock.get());
+ pblock->nBits = GetNextWorkRequired(pindexPrev, pblock);
pblock->nNonce = 0;
pblock->vtx[0].vin[0].scriptSig = CScript() << OP_0 << OP_0;
+ pblocktemplate->vTxSigOps[0] = pblock->vtx[0].GetLegacySigOpCount();
CBlockIndex indexDummy(*pblock);
indexDummy.pprev = pindexPrev;
@@ -3975,7 +4017,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
throw std::runtime_error("CreateNewBlock() : ConnectBlock failed");
}
- return pblock.release();
+ return pblocktemplate.release();
}
@@ -4118,10 +4160,11 @@ void static BitcoinMiner(CWallet *pwallet)
unsigned int nTransactionsUpdatedLast = nTransactionsUpdated;
CBlockIndex* pindexPrev = pindexBest;
- auto_ptr<CBlock> pblock(CreateNewBlock(reservekey));
- if (!pblock.get())
+ auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(reservekey));
+ if (!pblocktemplate.get())
return;
- IncrementExtraNonce(pblock.get(), pindexPrev, nExtraNonce);
+ CBlock *pblock = &pblocktemplate->block;
+ IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
printf("Running BitcoinMiner with %"PRIszu" transactions in block (%u bytes)\n", pblock->vtx.size(),
::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
@@ -4134,7 +4177,7 @@ void static BitcoinMiner(CWallet *pwallet)
char pdatabuf[128+16]; char* pdata = alignup<16>(pdatabuf);
char phash1buf[64+16]; char* phash1 = alignup<16>(phash1buf);
- FormatHashBuffers(pblock.get(), pmidstate, pdata, phash1);
+ FormatHashBuffers(pblock, pmidstate, pdata, phash1);
unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4);
unsigned int& nBlockBits = *(unsigned int*)(pdata + 64 + 8);
@@ -4170,7 +4213,7 @@ void static BitcoinMiner(CWallet *pwallet)
assert(hash == pblock->GetHash());
SetThreadPriority(THREAD_PRIORITY_NORMAL);
- CheckWork(pblock.get(), *pwalletMain, reservekey);
+ CheckWork(pblock, *pwalletMain, reservekey);
SetThreadPriority(THREAD_PRIORITY_LOWEST);
break;
}
diff --git a/src/main.h b/src/main.h
index 8bceffbaf9..3290b16318 100644
--- a/src/main.h
+++ b/src/main.h
@@ -108,6 +108,8 @@ class CTxUndo;
class CCoinsView;
class CCoinsViewCache;
+struct CBlockTemplate;
+
/** Register a wallet to receive updates from core */
void RegisterWallet(CWallet* pwalletIn);
/** Unregister a wallet from core */
@@ -117,7 +119,7 @@ void SyncWithWallets(const uint256 &hash, const CTransaction& tx, const CBlock*
/** Process an incoming block */
bool ProcessBlock(CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp = NULL);
/** Check whether enough disk space is available for an incoming block */
-bool CheckDiskSpace(uint64 nAdditionalBytes=0);
+bool CheckDiskSpace(uint64 nAdditionalBytes = 0);
/** Open a block file (blk?????.dat) */
FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly = false);
/** Open an undo file (rev?????.dat) */
@@ -126,6 +128,8 @@ FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly = false);
bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp = NULL);
/** Load the block tree and coins database from disk */
bool LoadBlockIndex();
+/** Verify consistency of the block and coin databases */
+bool VerifyDB();
/** Print the loaded block tree */
void PrintBlockTree();
/** Find a block by height in the currently-connected chain */
@@ -139,7 +143,7 @@ void ThreadImport(void *parg);
/** Run the miner threads */
void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
/** Generate a new block, without valid proof-of-work */
-CBlock* CreateNewBlock(CReserveKey& reservekey);
+CBlockTemplate* CreateNewBlock(CReserveKey& reservekey);
/** Modify the extranonce in a block */
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
/** Do mining precalculation */
@@ -437,7 +441,7 @@ enum CheckSig_mode
};
/** The basic transaction that is broadcasted on the network and contained in
- * blocks. A transaction can contain multiple inputs and outputs.
+ * blocks. A transaction can contain multiple inputs and outputs.
*/
class CTransaction
{
@@ -544,13 +548,11 @@ public:
/** Check for standard transaction types
@param[in] mapInputs Map of previous transactions that have outputs we're spending
@return True if all inputs (scriptSigs) use only standard transaction forms
- @see CTransaction::FetchInputs
*/
bool AreInputsStandard(CCoinsViewCache& mapInputs) const;
/** Count ECDSA signature operations the old-fashioned (pre-0.6) way
@return number of sigops this transaction's outputs will produce when spent
- @see CTransaction::FetchInputs
*/
unsigned int GetLegacySigOpCount() const;
@@ -558,7 +560,6 @@ public:
@param[in] mapInputs Map of previous transactions that have outputs we're spending
@return maximum number of sigops required to validate this transaction's inputs
- @see CTransaction::FetchInputs
*/
unsigned int GetP2SHSigOpCount(CCoinsViewCache& mapInputs) const;
@@ -583,7 +584,6 @@ public:
@param[in] mapInputs Map of previous transactions that have outputs we're spending
@return Sum of value of all inputs (scriptSigs)
- @see CTransaction::FetchInputs
*/
int64 GetValueIn(CCoinsViewCache& mapInputs) const;
@@ -746,7 +746,7 @@ public:
READWRITE(vtxundo);
)
- bool WriteToDisk(CDiskBlockPos &pos)
+ bool WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock)
{
// Open history file to append
CAutoFile fileout = CAutoFile(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
@@ -764,6 +764,12 @@ public:
pos.nPos = (unsigned int)fileOutPos;
fileout << *this;
+ // calculate & write checksum
+ CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
+ hasher << hashBlock;
+ hasher << *this;
+ fileout << hasher.GetHash();
+
// Flush stdio buffers and commit to disk before returning
fflush(fileout);
if (!IsInitialBlockDownload())
@@ -771,6 +777,43 @@ public:
return true;
}
+
+ bool ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock)
+ {
+ // Open history file to read
+ CAutoFile filein = CAutoFile(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
+ if (!filein)
+ return error("CBlockUndo::ReadFromDisk() : OpenBlockFile failed");
+
+ // Read block
+ uint256 hashChecksum;
+ try {
+ filein >> *this;
+ }
+ catch (std::exception &e) {
+ return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__);
+ }
+
+ // for compatibility with pre-release code that didn't write checksums to undo data
+ // TODO: replace by a simply 'filein >> hashChecksum' in the above try block
+ try {
+ filein >> hashChecksum;
+ } catch (std::exception &e) {
+ hashChecksum = 0;
+ }
+ uint32_t hashInit = hashChecksum.Get64(0) & 0xFFFFFFFFUL;
+ if (hashChecksum == 0 || memcmp(&hashInit, pchMessageStart, 4) == 0)
+ return true;
+
+ // Verify checksum
+ CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
+ hasher << hashBlock;
+ hasher << *this;
+ if (hashChecksum != hasher.GetHash())
+ return error("CBlockUndo::ReadFromDisk() : checksum mismatch");
+
+ return true;
+ }
};
/** pruned version of CTransaction: only retains metadata and unspent transaction outputs
@@ -1231,7 +1274,6 @@ public:
return hash;
}
-
bool WriteToDisk(CDiskBlockPos &pos)
{
// Open history file to append
@@ -1305,8 +1347,11 @@ public:
}
- // Undo the effects of this block (with given index) on the UTXO set represented by coins
- bool DisconnectBlock(CBlockIndex *pindex, CCoinsViewCache &coins);
+ /** Undo the effects of this block (with given index) on the UTXO set represented by coins.
+ * In case pfClean is provided, operation will try to be tolerant about errors, and *pfClean
+ * will be true if no problems were found. Otherwise, the return value will be false in case
+ * of problems. Note that in any case, coins may be modified. */
+ bool DisconnectBlock(CBlockIndex *pindex, CCoinsViewCache &coins, bool *pfClean = NULL);
// Apply the effects of this block (with given index) on the UTXO set represented by coins
bool ConnectBlock(CBlockIndex *pindex, CCoinsViewCache &coins, bool fJustCheck=false);
@@ -1975,4 +2020,11 @@ extern CCoinsViewCache *pcoinsTip;
/** Global variable that points to the active block tree (protected by cs_main) */
extern CBlockTreeDB *pblocktree;
+struct CBlockTemplate
+{
+ CBlock block;
+ std::vector<int64_t> vTxFees;
+ std::vector<int64_t> vTxSigOps;
+};
+
#endif
diff --git a/src/net.cpp b/src/net.cpp
index b54f8c15f7..7867c85b7f 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -45,10 +45,9 @@ struct LocalServiceInfo {
//
// Global state variables
//
-bool fClient = false;
bool fDiscover = true;
bool fUseUPnP = false;
-uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
+uint64 nLocalServices = NODE_NETWORK;
static CCriticalSection cs_mapLocalHost;
static map<CNetAddr, LocalServiceInfo> mapLocalHost;
static bool vfReachable[NET_MAX] = {};
diff --git a/src/net.h b/src/net.h
index e37953772e..44c80dac28 100644
--- a/src/net.h
+++ b/src/net.h
@@ -86,7 +86,6 @@ enum threadId
THREAD_MAX
};
-extern bool fClient;
extern bool fDiscover;
extern bool fUseUPnP;
extern uint64 nLocalServices;
diff --git a/src/noui.cpp b/src/noui.cpp
index 204e76aba7..96a8de4ee9 100644
--- a/src/noui.cpp
+++ b/src/noui.cpp
@@ -24,10 +24,10 @@ static int noui_ThreadSafeMessageBox(const std::string& message, const std::stri
strCaption += _("Information");
break;
default:
- strCaption += caption; // Use supplied caption
+ strCaption += caption; // Use supplied caption (can be empty)
}
- printf("%s: %s\n", caption.c_str(), message.c_str());
+ printf("%s: %s\n", strCaption.c_str(), message.c_str());
fprintf(stderr, "%s: %s\n", strCaption.c_str(), message.c_str());
return 4;
}
diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp
index e20358c70e..263fd52790 100644
--- a/src/qt/addressbookpage.cpp
+++ b/src/qt/addressbookpage.cpp
@@ -361,7 +361,7 @@ void AddressBookPage::contextualMenu(const QPoint &point)
}
}
-void AddressBookPage::selectNewAddress(const QModelIndex &parent, int begin, int end)
+void AddressBookPage::selectNewAddress(const QModelIndex &parent, int begin, int /*end*/)
{
QModelIndex idx = proxyModel->mapFromSource(model->index(begin, AddressTableModel::Address, parent));
if(idx.isValid() && (idx.data(Qt::EditRole).toString() == newAddressToSelect))
diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h
index f7d177c513..6d3a734a16 100644
--- a/src/qt/addressbookpage.h
+++ b/src/qt/addressbookpage.h
@@ -75,7 +75,7 @@ private slots:
void onEditAction();
/** New entry/entries were added to address table */
- void selectNewAddress(const QModelIndex &parent, int begin, int end);
+ void selectNewAddress(const QModelIndex &parent, int begin, int /*end*/);
signals:
void signMessage(QString addr);
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index dbdfade0b1..c3701ced7f 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -113,6 +113,14 @@ static void handleRunawayException(std::exception *e)
#ifndef BITCOIN_QT_TEST
int main(int argc, char *argv[])
{
+ // Command-line options take precedence:
+ ParseParameters(argc, argv);
+
+ if(GetBoolArg("-testnet")) // Separate message queue name for testnet
+ strBitcoinURIQueueName = BITCOINURI_QUEUE_NAME_TESTNET;
+ else
+ strBitcoinURIQueueName = BITCOINURI_QUEUE_NAME_MAINNET;
+
// Do this early as we don't want to bother initializing if we are just calling IPC
ipcScanRelay(argc, argv);
@@ -126,9 +134,6 @@ int main(int argc, char *argv[])
// Install global event filter that makes sure that long tooltips can be word-wrapped
app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
- // Command-line options take precedence:
- ParseParameters(argc, argv);
-
// ... then bitcoin.conf:
if (!boost::filesystem::is_directory(GetDataDir(false)))
{
diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp
index 497c05976b..7fcb7acf0e 100644
--- a/src/qt/bitcoinstrings.cpp
+++ b/src/qt/bitcoinstrings.cpp
@@ -84,7 +84,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for -addnode, -seednode and
QT_TRANSLATE_NOOP("bitcoin-core", "Allow JSON-RPC connections from specified IP address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to recover private keys from a corrupt wallet.dat"),
QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin version"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin"),
QT_TRANSLATE_NOOP("bitcoin-core", "Block creation options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot downgrade wallet"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot initialize keypool"),
@@ -102,6 +101,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires newer version of Bitcoin"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error: Disk space is low!"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Transaction creation failed!"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Wallet locked, unable to create transaction!"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: could not start node"),
@@ -114,7 +114,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Get help for a command"),
QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: 2500, 0 = all)"),
QT_TRANSLATE_NOOP("bitcoin-core", "How thorough the block verification is (0-6, default: 1)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Importing blocks from block database..."),
-QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000?.dat file"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000??.dat file"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Information"),
QT_TRANSLATE_NOOP("bitcoin-core", "Insufficient funds"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -tor address: '%s'"),
@@ -128,6 +129,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most <n> connections to peers (default: 125)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Only accept block chain matching built-in checkpoints (default: 1)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (IPv4, IPv6 or Tor)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Output extra debugging information. Implies all other -debug* options"),
@@ -144,7 +146,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Send command to -server or bitcoind"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send commands to node running on <ip> (default: 127.0.0.1)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of debug.log file"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to debugger"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Sending..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: server.cert)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: server.pem)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (default: 25)"),
@@ -173,7 +174,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network"),
QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"),
QT_TRANSLATE_NOOP("bitcoin-core", "Verifying database integrity..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart Bitcoin to complete"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Disk space is low!"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Warning"),
QT_TRANSLATE_NOOP("bitcoin-core", "Warning: This version is obsolete, upgrade required!"),
QT_TRANSLATE_NOOP("bitcoin-core", "wallet.dat corrupt, salvage failed"),
}; \ No newline at end of file
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index ce112803f8..12bd989338 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -15,10 +15,8 @@ static const int64 nClientStartupTime = GetTime();
ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
QObject(parent), optionsModel(optionsModel),
- cachedNumBlocks(0), cachedNumBlocksOfPeers(0), pollTimer(0)
+ cachedNumBlocks(0), cachedNumBlocksOfPeers(0), numBlocksAtStartup(-1), pollTimer(0)
{
- numBlocksAtStartup = -1;
-
pollTimer = new QTimer(this);
pollTimer->setInterval(MODEL_UPDATE_DELAY);
pollTimer->start();
@@ -65,7 +63,8 @@ void ClientModel::updateTimer()
cachedNumBlocks = newNumBlocks;
cachedNumBlocksOfPeers = newNumBlocksOfPeers;
- emit numBlocksChanged(newNumBlocks, newNumBlocksOfPeers);
+ // ensure we return the maximum of newNumBlocksOfPeers and newNumBlocks to not create weird displays in the GUI
+ emit numBlocksChanged(newNumBlocks, std::max(newNumBlocksOfPeers, newNumBlocks));
}
}
diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui
index 6a13361974..3771f9de63 100644
--- a/src/qt/forms/optionsdialog.ui
+++ b/src/qt/forms/optionsdialog.ui
@@ -44,7 +44,7 @@
</widget>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_Main">
+ <layout class="QHBoxLayout" name="horizontalLayout_1_Main">
<item>
<widget class="QLabel" name="transactionFeeLabel">
<property name="text">
@@ -62,7 +62,7 @@
<widget class="BitcoinAmountField" name="transactionFee"/>
</item>
<item>
- <spacer name="horizontalSpacer_Main">
+ <spacer name="horizontalSpacer_1_Main">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -99,6 +99,36 @@
</property>
</spacer>
</item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2_Main">
+ <item>
+ <spacer name="horizontalSpacer_2_Main">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="resetButton">
+ <property name="toolTip">
+ <string>Reset all client options to default.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Reset Options</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
</layout>
</widget>
<widget class="QWidget" name="tabNetwork">
diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui
index 4c4dec6c9c..970e6c671d 100644
--- a/src/qt/forms/overviewpage.ui
+++ b/src/qt/forms/overviewpage.ui
@@ -20,8 +20,7 @@
<bool>false</bool>
</property>
<property name="styleSheet">
- <string notr="true">background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop:0 #F0D0A0, stop:1 #F8D488); color:#000000
-</string>
+ <string notr="true">background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop:0 #F0D0A0, stop:1 #F8D488); color:#000000;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
diff --git a/src/qt/forms/signverifymessagedialog.ui b/src/qt/forms/signverifymessagedialog.ui
index 8128bdf457..279b2a5052 100644
--- a/src/qt/forms/signverifymessagedialog.ui
+++ b/src/qt/forms/signverifymessagedialog.ui
@@ -105,6 +105,16 @@
</widget>
</item>
<item>
+ <widget class="QLabel" name="signatureLabel_SM">
+ <property name="text">
+ <string>Signature</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
<layout class="QHBoxLayout" name="horizontalLayout_2_SM">
<property name="spacing">
<number>0</number>
@@ -148,7 +158,7 @@
<string>Sign the message to prove you own this Bitcoin address</string>
</property>
<property name="text">
- <string>&amp;Sign Message</string>
+ <string>Sign &amp;Message</string>
</property>
<property name="icon">
<iconset resource="../bitcoin.qrc">
@@ -294,7 +304,7 @@
<string>Verify the message to ensure it was signed with the specified Bitcoin address</string>
</property>
<property name="text">
- <string>&amp;Verify Message</string>
+ <string>Verify &amp;Message</string>
</property>
<property name="icon">
<iconset resource="../bitcoin.qrc">
diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts
index c70ea652de..cb6f982d32 100644
--- a/src/qt/locale/bitcoin_en.ts
+++ b/src/qt/locale/bitcoin_en.ts
@@ -300,17 +300,17 @@ This product includes software developed by the OpenSSL Project for use in the O
<context>
<name>BitcoinGUI</name>
<message>
- <location filename="../bitcoingui.cpp" line="+266"/>
+ <location filename="../bitcoingui.cpp" line="+267"/>
<source>Sign &amp;message...</source>
<translation>Sign &amp;message...</translation>
</message>
<message>
- <location line="+241"/>
+ <location line="+254"/>
<source>Synchronizing with network...</source>
<translation>Synchronizing with network...</translation>
</message>
<message>
- <location line="-309"/>
+ <location line="-322"/>
<source>&amp;Overview</source>
<translation>&amp;Overview</translation>
</message>
@@ -400,7 +400,7 @@ This product includes software developed by the OpenSSL Project for use in the O
<translation>&amp;Change Passphrase...</translation>
</message>
<message>
- <location line="+246"/>
+ <location line="+259"/>
<source>Importing blocks from disk...</source>
<translation>Importing blocks from disk...</translation>
</message>
@@ -418,7 +418,7 @@ This product includes software developed by the OpenSSL Project for use in the O
</translation>
</message>
<message>
- <location line="-252"/>
+ <location line="-265"/>
<source>&amp;Export...</source>
<translation>&amp;Export...</translation>
</message>
@@ -464,11 +464,12 @@ This product includes software developed by the OpenSSL Project for use in the O
</message>
<message>
<location line="-196"/>
+ <location line="+538"/>
<source>Bitcoin</source>
<translation>Bitcoin</translation>
</message>
<message>
- <location line="+0"/>
+ <location line="-538"/>
<source>Wallet</source>
<translation>Wallet</translation>
</message>
@@ -534,12 +535,12 @@ This product includes software developed by the OpenSSL Project for use in the O
<translation>[testnet]</translation>
</message>
<message>
- <location line="+60"/>
+ <location line="+63"/>
<source>Bitcoin client</source>
<translation>Bitcoin client</translation>
</message>
<message numerus="yes">
- <location line="+69"/>
+ <location line="+79"/>
<source>%n active connection(s) to Bitcoin network</source>
<translation>
<numerusform>%n active connection to Bitcoin network</numerusform>
@@ -557,12 +558,37 @@ This product includes software developed by the OpenSSL Project for use in the O
<translation>Processed %1 blocks of transaction history.</translation>
</message>
<message>
- <location line="+107"/>
+ <location line="+70"/>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Warning</source>
+ <translation>Warning</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Information</source>
+ <translation>Information</translation>
+ </message>
+ <message>
+ <location line="+66"/>
<source>This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?</source>
<translation>This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?</translation>
</message>
+ <message>
+ <location line="+210"/>
+ <source>Backup Successful</source>
+ <translation>Backup Successful</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>The wallet data was successfully saved to the new location.</source>
+ <translation>The wallet data was successfully saved to the new location.</translation>
+ </message>
<message numerus="yes">
- <location line="-93"/>
+ <location line="-338"/>
<source>%n second(s) ago</source>
<translation>
<numerusform>%n second ago</numerusform>
@@ -609,17 +635,17 @@ This product includes software developed by the OpenSSL Project for use in the O
<translation>Last received block was generated %1.</translation>
</message>
<message>
- <location line="+62"/>
+ <location line="+97"/>
<source>Confirm transaction fee</source>
<translation>Confirm transaction fee</translation>
</message>
<message>
- <location line="+27"/>
+ <location line="+23"/>
<source>Sent transaction</source>
<translation>Sent transaction</translation>
</message>
<message>
- <location line="+1"/>
+ <location line="+0"/>
<source>Incoming transaction</source>
<translation>Incoming transaction</translation>
</message>
@@ -637,19 +663,19 @@ Address: %4
</translation>
</message>
<message>
- <location line="+100"/>
- <location line="+27"/>
+ <location line="+99"/>
+ <location line="+28"/>
<source>URI handling</source>
<translation>URI handling</translation>
</message>
<message>
- <location line="-27"/>
- <location line="+27"/>
+ <location line="-28"/>
+ <location line="+28"/>
<source>URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
<translation>URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</translation>
</message>
<message>
- <location line="+16"/>
+ <location line="+17"/>
<source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
<translation>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</translation>
</message>
@@ -1447,12 +1473,11 @@ Address: %4
</message>
<message>
<location line="+13"/>
- <location line="+124"/>
<source>&amp;Sign Message</source>
<translation>&amp;Sign Message</translation>
</message>
<message>
- <location line="-118"/>
+ <location line="+6"/>
<source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
<translation>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</translation>
</message>
@@ -1499,7 +1524,12 @@ Address: %4
<translation>Sign the message to prove you own this Bitcoin address</translation>
</message>
<message>
- <location line="+17"/>
+ <location line="+3"/>
+ <source>Sign &amp;Message</source>
+ <translation>Sign &amp;Message</translation>
+ </message>
+ <message>
+ <location line="+14"/>
<source>Reset all sign message fields</source>
<translation>Reset all sign message fields</translation>
</message>
@@ -1511,12 +1541,11 @@ Address: %4
</message>
<message>
<location line="-87"/>
- <location line="+70"/>
<source>&amp;Verify Message</source>
<translation>&amp;Verify Message</translation>
</message>
<message>
- <location line="-64"/>
+ <location line="+6"/>
<source>Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack.</source>
<translation>Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack.</translation>
</message>
@@ -1531,7 +1560,12 @@ Address: %4
<translation>Verify the message to ensure it was signed with the specified Bitcoin address</translation>
</message>
<message>
- <location line="+17"/>
+ <location line="+3"/>
+ <source>Verify &amp;Message</source>
+ <translation>Verify &amp;Message</translation>
+ </message>
+ <message>
+ <location line="+14"/>
<source>Reset all verify message fields</source>
<translation>Reset all verify message fields</translation>
</message>
@@ -2103,14 +2137,6 @@ Address: %4
</message>
</context>
<context>
- <name>WalletModel</name>
- <message>
- <location filename="../walletmodel.cpp" line="+192"/>
- <source>Sending...</source>
- <translation>Sending...</translation>
- </message>
-</context>
-<context>
<name>bitcoin-core</name>
<message>
<location filename="../bitcoinstrings.cpp" line="+86"/>
@@ -2118,32 +2144,32 @@ Address: %4
<translation>Bitcoin version</translation>
</message>
<message>
- <location line="+81"/>
+ <location line="+82"/>
<source>Usage:</source>
<translation>Usage:</translation>
</message>
<message>
- <location line="-24"/>
+ <location line="-23"/>
<source>Send command to -server or bitcoind</source>
<translation>Send command to -server or bitcoind</translation>
</message>
<message>
- <location line="-20"/>
+ <location line="-21"/>
<source>List commands</source>
<translation>List commands</translation>
</message>
<message>
- <location line="-10"/>
+ <location line="-11"/>
<source>Get help for a command</source>
<translation>Get help for a command</translation>
</message>
<message>
- <location line="+19"/>
+ <location line="+21"/>
<source>Options:</source>
<translation>Options:</translation>
</message>
<message>
- <location line="+23"/>
+ <location line="+22"/>
<source>Specify configuration file (default: bitcoin.conf)</source>
<translation>Specify configuration file (default: bitcoin.conf)</translation>
</message>
@@ -2153,17 +2179,17 @@ Address: %4
<translation>Specify pid file (default: bitcoind.pid)</translation>
</message>
<message>
- <location line="-46"/>
+ <location line="-47"/>
<source>Generate coins</source>
<translation>Generate coins</translation>
</message>
<message>
- <location line="-14"/>
+ <location line="-15"/>
<source>Don&apos;t generate coins</source>
<translation>Don&apos;t generate coins</translation>
</message>
<message>
- <location line="+59"/>
+ <location line="+61"/>
<source>Specify data directory</source>
<translation>Specify data directory</translation>
</message>
@@ -2183,12 +2209,12 @@ Address: %4
<translation>Maintain at most &lt;n&gt; connections to peers (default: 125)</translation>
</message>
<message>
- <location line="-32"/>
+ <location line="-34"/>
<source>Connect to a node to retrieve peer addresses, and disconnect</source>
<translation>Connect to a node to retrieve peer addresses, and disconnect</translation>
</message>
<message>
- <location line="+63"/>
+ <location line="+65"/>
<source>Specify your own public address</source>
<translation>Specify your own public address</translation>
</message>
@@ -2198,7 +2224,7 @@ Address: %4
<translation>Threshold for disconnecting misbehaving peers (default: 100)</translation>
</message>
<message>
- <location line="-113"/>
+ <location line="-114"/>
<source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source>
<translation>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</translation>
</message>
@@ -2218,17 +2244,17 @@ Address: %4
<translation>Accept command line and JSON-RPC commands</translation>
</message>
<message>
- <location line="+60"/>
+ <location line="+62"/>
<source>Run in the background as a daemon and accept commands</source>
<translation>Run in the background as a daemon and accept commands</translation>
</message>
<message>
- <location line="+32"/>
+ <location line="+31"/>
<source>Use the test network</source>
<translation>Use the test network</translation>
</message>
<message>
- <location line="-91"/>
+ <location line="-92"/>
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
<translation>Accept connections from outside (default: 1 if no -proxy or -connect)</translation>
</message>
@@ -2323,7 +2349,7 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Attempt to recover private keys from a corrupt wallet.dat</translation>
</message>
<message>
- <location line="+3"/>
+ <location line="+2"/>
<source>Block creation options:</source>
<translation>Block creation options:</translation>
</message>
@@ -2339,6 +2365,11 @@ If the file does not exist, create it with owner-readable-only file permissions.
</message>
<message>
<location line="+8"/>
+ <source>Error: Disk space is low!</source>
+ <translation>Error: Disk space is low!</translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Error: Transaction creation failed!</source>
<translation>Error: Transaction creation failed!</translation>
</message>
@@ -2363,7 +2394,17 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Importing blocks from block database...</translation>
</message>
<message>
- <location line="+4"/>
+ <location line="+1"/>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Imports blocks from external blk000??.dat file</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Information</source>
+ <translation>Information</translation>
+ </message>
+ <message>
+ <location line="+3"/>
<source>Invalid -tor address: &apos;%s&apos;</source>
<translation>Invalid -tor address: &apos;%s&apos;</translation>
</message>
@@ -2379,6 +2420,11 @@ If the file does not exist, create it with owner-readable-only file permissions.
</message>
<message>
<location line="+1"/>
+ <source>Only accept block chain matching built-in checkpoints (default: 1)</source>
+ <translation>Only accept block chain matching built-in checkpoints (default: 1)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Only connect to nodes in network &lt;net&gt; (IPv4, IPv6 or Tor)</source>
<translation>Only connect to nodes in network &lt;net&gt; (IPv4, IPv6 or Tor)</translation>
</message>
@@ -2423,7 +2469,7 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Send trace/debug info to debugger</translation>
</message>
<message>
- <location line="+6"/>
+ <location line="+5"/>
<source>Set maximum block size in bytes (default: 250000)</source>
<translation>Set maximum block size in bytes (default: 250000)</translation>
</message>
@@ -2469,8 +2515,8 @@ If the file does not exist, create it with owner-readable-only file permissions.
</message>
<message>
<location line="+2"/>
- <source>Warning: Disk space is low!</source>
- <translation>Warning: Disk space is low!</translation>
+ <source>Warning</source>
+ <translation>Warning</translation>
</message>
<message>
<location line="+1"/>
@@ -2483,27 +2529,27 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>wallet.dat corrupt, salvage failed</translation>
</message>
<message>
- <location line="-43"/>
+ <location line="-42"/>
<source>Password for JSON-RPC connections</source>
<translation>Password for JSON-RPC connections</translation>
</message>
<message>
- <location line="-51"/>
+ <location line="-53"/>
<source>Allow JSON-RPC connections from specified IP address</source>
<translation>Allow JSON-RPC connections from specified IP address</translation>
</message>
<message>
- <location line="+60"/>
+ <location line="+62"/>
<source>Send commands to node running on &lt;ip&gt; (default: 127.0.0.1)</source>
<translation>Send commands to node running on &lt;ip&gt; (default: 127.0.0.1)</translation>
</message>
<message>
- <location line="-101"/>
+ <location line="-103"/>
<source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
<translation>Execute command when the best block changes (%s in cmd is replaced by block hash)</translation>
</message>
<message>
- <location line="+123"/>
+ <location line="+124"/>
<source>Upgrade wallet to latest format</source>
<translation>Upgrade wallet to latest format</translation>
</message>
@@ -2513,12 +2559,12 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Set key pool size to &lt;n&gt; (default: 100)</translation>
</message>
<message>
- <location line="-13"/>
+ <location line="-12"/>
<source>Rescan the block chain for missing wallet transactions</source>
<translation>Rescan the block chain for missing wallet transactions</translation>
</message>
<message>
- <location line="-24"/>
+ <location line="-26"/>
<source>How many blocks to check at startup (default: 2500, 0 = all)</source>
<translation>How many blocks to check at startup (default: 2500, 0 = all)</translation>
</message>
@@ -2528,12 +2574,7 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>How thorough the block verification is (0-6, default: 1)</translation>
</message>
<message>
- <location line="+2"/>
- <source>Imports blocks from external blk000?.dat file</source>
- <translation>Imports blocks from external blk000?.dat file</translation>
- </message>
- <message>
- <location line="+51"/>
+ <location line="+54"/>
<source>Use OpenSSL (https) for JSON-RPC connections</source>
<translation>Use OpenSSL (https) for JSON-RPC connections</translation>
</message>
@@ -2548,42 +2589,37 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Server private key (default: server.pem)</translation>
</message>
<message>
- <location line="-130"/>
+ <location line="-131"/>
<source>Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</source>
<translation>Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</translation>
</message>
<message>
- <location line="+141"/>
+ <location line="+142"/>
<source>This help message</source>
<translation>This help message</translation>
</message>
<message>
- <location line="-73"/>
- <source>Bitcoin</source>
- <translation>Bitcoin</translation>
- </message>
- <message>
- <location line="+76"/>
+ <location line="+3"/>
<source>Unable to bind to %s on this computer (bind returned error %d, %s)</source>
<translation>Unable to bind to %s on this computer (bind returned error %d, %s)</translation>
</message>
<message>
- <location line="-68"/>
+ <location line="-70"/>
<source>Connect through socks proxy</source>
<translation>Connect through socks proxy</translation>
</message>
<message>
- <location line="-12"/>
+ <location line="-11"/>
<source>Allow DNS lookups for -addnode, -seednode and -connect</source>
<translation>Allow DNS lookups for -addnode, -seednode and -connect</translation>
</message>
<message>
- <location line="+42"/>
+ <location line="+43"/>
<source>Loading addresses...</source>
<translation>Loading addresses...</translation>
</message>
<message>
- <location line="-25"/>
+ <location line="-27"/>
<source>Error loading blkindex.dat</source>
<translation>Error loading blkindex.dat</translation>
</message>
@@ -2598,17 +2634,17 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Error loading wallet.dat: Wallet requires newer version of Bitcoin</translation>
</message>
<message>
- <location line="+72"/>
+ <location line="+74"/>
<source>Wallet needed to be rewritten: restart Bitcoin to complete</source>
<translation>Wallet needed to be rewritten: restart Bitcoin to complete</translation>
</message>
<message>
- <location line="-74"/>
+ <location line="-76"/>
<source>Error loading wallet.dat</source>
<translation>Error loading wallet.dat</translation>
</message>
<message>
- <location line="+18"/>
+ <location line="+20"/>
<source>Invalid -proxy address: &apos;%s&apos;</source>
<translation>Invalid -proxy address: &apos;%s&apos;</translation>
</message>
@@ -2623,7 +2659,7 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Unknown -socks proxy version requested: %i</translation>
</message>
<message>
- <location line="-73"/>
+ <location line="-75"/>
<source>Cannot resolve -bind address: &apos;%s&apos;</source>
<translation>Cannot resolve -bind address: &apos;%s&apos;</translation>
</message>
@@ -2633,22 +2669,17 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Cannot resolve -externalip address: &apos;%s&apos;</translation>
</message>
<message>
- <location line="+29"/>
+ <location line="+31"/>
<source>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos;</source>
<translation>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos;</translation>
</message>
<message>
- <location line="-14"/>
+ <location line="-15"/>
<source>Error: could not start node</source>
<translation>Error: could not start node</translation>
</message>
<message>
- <location line="+40"/>
- <source>Sending...</source>
- <translation>Sending...</translation>
- </message>
- <message>
- <location line="-25"/>
+ <location line="+16"/>
<source>Invalid amount</source>
<translation>Invalid amount</translation>
</message>
@@ -2663,7 +2694,7 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Loading block index...</translation>
</message>
<message>
- <location line="-44"/>
+ <location line="-45"/>
<source>Add a node to connect to and attempt to keep the connection open</source>
<translation>Add a node to connect to and attempt to keep the connection open</translation>
</message>
@@ -2683,12 +2714,12 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Fee per KB to add to transactions you send</translation>
</message>
<message>
- <location line="+18"/>
+ <location line="+19"/>
<source>Loading wallet...</source>
<translation>Loading wallet...</translation>
</message>
<message>
- <location line="-38"/>
+ <location line="-40"/>
<source>Cannot downgrade wallet</source>
<translation>Cannot downgrade wallet</translation>
</message>
@@ -2703,27 +2734,27 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Cannot write default address</translation>
</message>
<message>
- <location line="+46"/>
+ <location line="+49"/>
<source>Rescanning...</source>
<translation>Rescanning...</translation>
</message>
<message>
- <location line="-40"/>
+ <location line="-43"/>
<source>Done loading</source>
<translation>Done loading</translation>
</message>
<message>
- <location line="+63"/>
+ <location line="+65"/>
<source>To use the %s option</source>
<translation>To use the %s option</translation>
</message>
<message>
- <location line="-58"/>
+ <location line="-60"/>
<source>Error</source>
<translation>Error</translation>
</message>
<message>
- <location line="-29"/>
+ <location line="-28"/>
<source>You must set rpcpassword=&lt;password&gt; in the configuration file:
%s
If the file does not exist, create it with owner-readable-only file permissions.</source>
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index 03dcb0b538..6b98ab1929 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -177,6 +177,33 @@ void OptionsDialog::setSaveButtonState(bool fState)
ui->okButton->setEnabled(fState);
}
+void OptionsDialog::on_resetButton_clicked()
+{
+ if(model)
+ {
+ // confirmation dialog
+ QMessageBox::StandardButton btnRetVal = QMessageBox::question(this, tr("Confirm options reset"),
+ tr("Some settings may require a client restart to take effect.") + "<br><br>" + tr("Do you want to proceed?"),
+ QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
+
+ if(btnRetVal == QMessageBox::Cancel)
+ return;
+
+ disableApplyButton();
+
+ /* disable restart warning messages display */
+ fRestartWarningDisplayed_Lang = fRestartWarningDisplayed_Proxy = true;
+
+ /* reset all options and save the default values (QSettings) */
+ model->Reset();
+ mapper->toFirst();
+ mapper->submit();
+
+ /* re-enable restart warning messages display */
+ fRestartWarningDisplayed_Lang = fRestartWarningDisplayed_Proxy = false;
+ }
+}
+
void OptionsDialog::on_okButton_clicked()
{
mapper->submit();
diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h
index 18469f509d..d64ed0b57f 100644
--- a/src/qt/optionsdialog.h
+++ b/src/qt/optionsdialog.h
@@ -36,6 +36,7 @@ private slots:
void disableSaveButtons();
/* set apply button and OK button state (enabled / disabled) */
void setSaveButtonState(bool fState);
+ void on_resetButton_clicked();
void on_okButton_clicked();
void on_cancelButton_clicked();
void on_applyButton_clicked();
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp
index 5dac5a6c45..2457e38742 100644
--- a/src/qt/optionsmodel.cpp
+++ b/src/qt/optionsmodel.cpp
@@ -60,6 +60,24 @@ void OptionsModel::Init()
SoftSetArg("-lang", language.toStdString());
}
+void OptionsModel::Reset()
+{
+ QSettings settings;
+
+ // Remove all entries in this QSettings object
+ settings.clear();
+
+ // default setting for OptionsModel::StartAtStartup - disabled
+ if (GUIUtil::GetStartOnSystemStartup())
+ GUIUtil::SetStartOnSystemStartup(false);
+
+ // Re-Init to get default values
+ Init();
+
+ // Ensure Upgrade() is not running again by setting the bImportFinished flag
+ settings.setValue("bImportFinished", true);
+}
+
bool OptionsModel::Upgrade()
{
QSettings settings;
diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h
index 4f893bb44e..d25d898d9c 100644
--- a/src/qt/optionsmodel.h
+++ b/src/qt/optionsmodel.h
@@ -33,6 +33,7 @@ public:
};
void Init();
+ void Reset();
/* Migrate settings from wallet.dat after app initialization */
bool Upgrade(); /* returns true if settings upgraded */
diff --git a/src/qt/qtipcserver.cpp b/src/qt/qtipcserver.cpp
index b26c37581c..2777fab852 100644
--- a/src/qt/qtipcserver.cpp
+++ b/src/qt/qtipcserver.cpp
@@ -26,6 +26,9 @@ using namespace boost;
using namespace boost::interprocess;
using namespace boost::posix_time;
+// holds Bitcoin-Qt message queue name (initialized in bitcoin.cpp)
+std::string strBitcoinURIQueueName;
+
#if defined MAC_OSX || defined __FreeBSD__
// URI handling not implemented on OSX yet
@@ -46,7 +49,7 @@ static bool ipcScanCmd(int argc, char *argv[], bool fRelay)
{
const char *strURI = argv[i];
try {
- boost::interprocess::message_queue mq(boost::interprocess::open_only, BITCOINURI_QUEUE_NAME);
+ boost::interprocess::message_queue mq(boost::interprocess::open_only, strBitcoinURIQueueName.c_str());
if (mq.try_send(strURI, strlen(strURI), 0))
fSent = true;
else if (fRelay)
@@ -76,7 +79,7 @@ static void ipcThread(void* pArg)
{
// Make this thread recognisable as the GUI-IPC thread
RenameThread("bitcoin-gui-ipc");
-
+
try
{
ipcThread2(pArg);
@@ -112,7 +115,7 @@ static void ipcThread2(void* pArg)
}
// Remove message queue
- message_queue::remove(BITCOINURI_QUEUE_NAME);
+ message_queue::remove(strBitcoinURIQueueName.c_str());
// Cleanup allocated memory
delete mq;
}
@@ -125,7 +128,7 @@ void ipcInit(int argc, char *argv[])
unsigned int nPriority = 0;
try {
- mq = new message_queue(open_or_create, BITCOINURI_QUEUE_NAME, 2, MAX_URI_LENGTH);
+ mq = new message_queue(open_or_create, strBitcoinURIQueueName.c_str(), 2, MAX_URI_LENGTH);
// Make sure we don't lose any bitcoin: URIs
for (int i = 0; i < 2; i++)
@@ -140,10 +143,10 @@ void ipcInit(int argc, char *argv[])
}
// Make sure only one bitcoin instance is listening
- message_queue::remove(BITCOINURI_QUEUE_NAME);
+ message_queue::remove(strBitcoinURIQueueName.c_str());
delete mq;
- mq = new message_queue(open_or_create, BITCOINURI_QUEUE_NAME, 2, MAX_URI_LENGTH);
+ mq = new message_queue(open_or_create, strBitcoinURIQueueName.c_str(), 2, MAX_URI_LENGTH);
}
catch (interprocess_exception &ex) {
printf("ipcInit() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what());
diff --git a/src/qt/qtipcserver.h b/src/qt/qtipcserver.h
index cccf200b2d..f775f272c2 100644
--- a/src/qt/qtipcserver.h
+++ b/src/qt/qtipcserver.h
@@ -1,8 +1,14 @@
#ifndef QTIPCSERVER_H
#define QTIPCSERVER_H
-// Define Bitcoin-Qt message queue name
-#define BITCOINURI_QUEUE_NAME "BitcoinURI"
+#include <string>
+
+// Define Bitcoin-Qt message queue name for mainnet
+#define BITCOINURI_QUEUE_NAME_MAINNET "BitcoinURI"
+// Define Bitcoin-Qt message queue name for testnet
+#define BITCOINURI_QUEUE_NAME_TESTNET "BitcoinURI-testnet"
+
+extern std::string strBitcoinURIQueueName;
void ipcScanRelay(int argc, char *argv[]);
void ipcInit(int argc, char *argv[]);
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 3dc32d0e47..7cf2d41962 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -269,8 +269,6 @@ void RPCConsole::setClientModel(ClientModel *model)
setNumConnections(model->getNumConnections());
ui->isTestNet->setChecked(model->isTestNet());
-
- setNumBlocks(model->getNumBlocks(), model->getNumBlocksOfPeers());
}
}
@@ -342,13 +340,10 @@ void RPCConsole::setNumConnections(int count)
void RPCConsole::setNumBlocks(int count, int countOfPeers)
{
ui->numberOfBlocks->setText(QString::number(count));
- ui->totalBlocks->setText(QString::number(countOfPeers));
+ // If there is no current countOfPeers available display N/A instead of 0, which can't ever be true
+ ui->totalBlocks->setText(countOfPeers == 0 ? tr("N/A") : QString::number(countOfPeers));
if(clientModel)
- {
- // If there is no current number available display N/A instead of 0, which can't ever be true
- ui->totalBlocks->setText(clientModel->getNumBlocksOfPeers() == 0 ? tr("N/A") : QString::number(clientModel->getNumBlocksOfPeers()));
ui->lastBlockTime->setText(clientModel->getLastBlockDate().toString());
- }
}
void RPCConsole::on_lineEdit_returnPressed()
diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp
index b3fc69ef0f..371b5ba535 100644
--- a/src/qt/signverifymessagedialog.cpp
+++ b/src/qt/signverifymessagedialog.cpp
@@ -55,13 +55,13 @@ void SignVerifyMessageDialog::setModel(WalletModel *model)
this->model = model;
}
-void SignVerifyMessageDialog::setAddress_SM(QString address)
+void SignVerifyMessageDialog::setAddress_SM(const QString &address)
{
ui->addressIn_SM->setText(address);
ui->messageIn_SM->setFocus();
}
-void SignVerifyMessageDialog::setAddress_VM(QString address)
+void SignVerifyMessageDialog::setAddress_VM(const QString &address)
{
ui->addressIn_VM->setText(address);
ui->messageIn_VM->setFocus();
diff --git a/src/qt/signverifymessagedialog.h b/src/qt/signverifymessagedialog.h
index 5569c8bf33..2c2677cc0c 100644
--- a/src/qt/signverifymessagedialog.h
+++ b/src/qt/signverifymessagedialog.h
@@ -20,8 +20,8 @@ public:
~SignVerifyMessageDialog();
void setModel(WalletModel *model);
- void setAddress_SM(QString address);
- void setAddress_VM(QString address);
+ void setAddress_SM(const QString &address);
+ void setAddress_VM(const QString &address);
void showTab_SM(bool fShow);
void showTab_VM(bool fShow);
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index 0591f35392..778e0acbd2 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -103,7 +103,7 @@ Value getwork(const Array& params, bool fHelp)
typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
static mapNewBlock_t mapNewBlock; // FIXME: thread safety
- static vector<CBlock*> vNewBlock;
+ static vector<CBlockTemplate*> vNewBlockTemplate;
static CReserveKey reservekey(pwalletMain);
if (params.size() == 0)
@@ -112,7 +112,7 @@ Value getwork(const Array& params, bool fHelp)
static unsigned int nTransactionsUpdatedLast;
static CBlockIndex* pindexPrev;
static int64 nStart;
- static CBlock* pblock;
+ static CBlockTemplate* pblocktemplate;
if (pindexPrev != pindexBest ||
(nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60))
{
@@ -120,9 +120,9 @@ Value getwork(const Array& params, bool fHelp)
{
// Deallocate old blocks since they're obsolete now
mapNewBlock.clear();
- BOOST_FOREACH(CBlock* pblock, vNewBlock)
- delete pblock;
- vNewBlock.clear();
+ BOOST_FOREACH(CBlockTemplate* pblocktemplate, vNewBlockTemplate)
+ delete pblocktemplate;
+ vNewBlockTemplate.clear();
}
// Clear pindexPrev so future getworks make a new block, despite any failures from here on
@@ -134,14 +134,15 @@ Value getwork(const Array& params, bool fHelp)
nStart = GetTime();
// Create new block
- pblock = CreateNewBlock(reservekey);
- if (!pblock)
+ pblocktemplate = CreateNewBlock(reservekey);
+ if (!pblocktemplate)
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
- vNewBlock.push_back(pblock);
+ vNewBlockTemplate.push_back(pblocktemplate);
// Need to update only after we know CreateNewBlock succeeded
pindexPrev = pindexPrevNew;
}
+ CBlock* pblock = &pblocktemplate->block; // pointer for convenience
// Update nTime
pblock->UpdateTime(pindexPrev);
@@ -248,7 +249,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
static unsigned int nTransactionsUpdatedLast;
static CBlockIndex* pindexPrev;
static int64 nStart;
- static CBlock* pblock;
+ static CBlockTemplate* pblocktemplate;
if (pindexPrev != pindexBest ||
(nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 5))
{
@@ -261,18 +262,19 @@ Value getblocktemplate(const Array& params, bool fHelp)
nStart = GetTime();
// Create new block
- if(pblock)
+ if(pblocktemplate)
{
- delete pblock;
- pblock = NULL;
+ delete pblocktemplate;
+ pblocktemplate = NULL;
}
- pblock = CreateNewBlock(reservekey);
- if (!pblock)
+ pblocktemplate = CreateNewBlock(reservekey);
+ if (!pblocktemplate)
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
// Need to update only after we know CreateNewBlock succeeded
pindexPrev = pindexPrevNew;
}
+ CBlock* pblock = &pblocktemplate->block; // pointer for convenience
// Update nTime
pblock->UpdateTime(pindexPrev);
@@ -281,7 +283,6 @@ Value getblocktemplate(const Array& params, bool fHelp)
Array transactions;
map<uint256, int64_t> setTxIndex;
int i = 0;
- CCoinsViewCache &view = *pcoinsTip;
BOOST_FOREACH (CTransaction& tx, pblock->vtx)
{
uint256 txHash = tx.GetHash();
@@ -306,13 +307,9 @@ Value getblocktemplate(const Array& params, bool fHelp)
}
entry.push_back(Pair("depends", deps));
- int64_t nSigOps = tx.GetLegacySigOpCount();
- if (tx.HaveInputs(view))
- {
- entry.push_back(Pair("fee", (int64_t)(tx.GetValueIn(view) - tx.GetValueOut())));
- nSigOps += tx.GetP2SHSigOpCount(view);
- }
- entry.push_back(Pair("sigops", nSigOps));
+ int index_in_template = &tx - pblock->vtx.data();
+ entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template]));
+ entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template]));
transactions.push_back(entry);
}
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index 4558a76a28..bc2a05a6b3 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -49,19 +49,20 @@ struct {
BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
{
CReserveKey reservekey(pwalletMain);
- CBlock *pblock;
+ CBlockTemplate *pblocktemplate;
CTransaction tx;
CScript script;
uint256 hash;
// Simple block creation, nothing special yet:
- BOOST_CHECK(pblock = CreateNewBlock(reservekey));
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey));
// We can't make transactions until we have inputs
// Therefore, load 100 blocks :)
std::vector<CTransaction*>txFirst;
for (unsigned int i = 0; i < sizeof(blockinfo)/sizeof(*blockinfo); ++i)
{
+ CBlock *pblock = &pblocktemplate->block; // pointer for convenience
pblock->nVersion = 1;
pblock->nTime = pindexBest->GetMedianTimePast()+1;
pblock->vtx[0].vin[0].scriptSig = CScript();
@@ -75,10 +76,10 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
assert(ProcessBlock(NULL, pblock));
pblock->hashPrevBlock = pblock->GetHash();
}
- delete pblock;
+ delete pblocktemplate;
// Just to make sure we can still make simple blocks
- BOOST_CHECK(pblock = CreateNewBlock(reservekey));
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey));
// block sigops > limit: 1000 CHECKMULTISIG + 1
tx.vin.resize(1);
@@ -95,8 +96,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
mempool.addUnchecked(hash, tx);
tx.vin[0].prevout.hash = hash;
}
- BOOST_CHECK(pblock = CreateNewBlock(reservekey));
- delete pblock;
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey));
+ delete pblocktemplate;
mempool.clear();
// block size > limit
@@ -115,15 +116,15 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
mempool.addUnchecked(hash, tx);
tx.vin[0].prevout.hash = hash;
}
- BOOST_CHECK(pblock = CreateNewBlock(reservekey));
- delete pblock;
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey));
+ delete pblocktemplate;
mempool.clear();
// orphan in mempool
hash = tx.GetHash();
mempool.addUnchecked(hash, tx);
- BOOST_CHECK(pblock = CreateNewBlock(reservekey));
- delete pblock;
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey));
+ delete pblocktemplate;
mempool.clear();
// child with higher priority than parent
@@ -140,8 +141,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].nValue = 5900000000LL;
hash = tx.GetHash();
mempool.addUnchecked(hash, tx);
- BOOST_CHECK(pblock = CreateNewBlock(reservekey));
- delete pblock;
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey));
+ delete pblocktemplate;
mempool.clear();
// coinbase in mempool
@@ -151,8 +152,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].nValue = 0;
hash = tx.GetHash();
mempool.addUnchecked(hash, tx);
- BOOST_CHECK(pblock = CreateNewBlock(reservekey));
- delete pblock;
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey));
+ delete pblocktemplate;
mempool.clear();
// invalid (pre-p2sh) txn in mempool
@@ -169,8 +170,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].nValue -= 1000000;
hash = tx.GetHash();
mempool.addUnchecked(hash,tx);
- BOOST_CHECK(pblock = CreateNewBlock(reservekey));
- delete pblock;
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey));
+ delete pblocktemplate;
mempool.clear();
// double spend txn pair in mempool
@@ -183,18 +184,18 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.vout[0].scriptPubKey = CScript() << OP_2;
hash = tx.GetHash();
mempool.addUnchecked(hash, tx);
- BOOST_CHECK(pblock = CreateNewBlock(reservekey));
- delete pblock;
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey));
+ delete pblocktemplate;
mempool.clear();
// subsidy changing
int nHeight = pindexBest->nHeight;
pindexBest->nHeight = 209999;
- BOOST_CHECK(pblock = CreateNewBlock(reservekey));
- delete pblock;
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey));
+ delete pblocktemplate;
pindexBest->nHeight = 210000;
- BOOST_CHECK(pblock = CreateNewBlock(reservekey));
- delete pblock;
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey));
+ delete pblocktemplate;
pindexBest->nHeight = nHeight;
}
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index c47d25bbe9..f56969cba6 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -104,11 +104,11 @@ BOOST_AUTO_TEST_CASE(util_HexStr)
BOOST_AUTO_TEST_CASE(util_DateTimeStrFormat)
{
/*These are platform-dependant and thus removed to avoid useless test failures
- BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%dT%H:%M:%S", 0), "1970-01-01T00:00:00");
- BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%dT%H:%M:%S", 0x7FFFFFFF), "2038-01-19T03:14:07");
+ BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 0), "1970-01-01 00:00:00");
+ BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 0x7FFFFFFF), "2038-01-19 03:14:07");
// Formats used within Bitcoin
- BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%dT%H:%M:%S", 1317425777), "2011-09-30T23:36:17");
- BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%dT%H:%M", 1317425777), "2011-09-30T23:36");
+ BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 1317425777), "2011-09-30 23:36:17");
+ BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M", 1317425777), "2011-09-30 23:36");
*/
}
diff --git a/src/util.cpp b/src/util.cpp
index 806f3ebcf6..d8f05cb9fd 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -74,7 +74,7 @@ bool fTestNet = false;
bool fNoListen = false;
bool fLogTimestamps = false;
CMedianFilter<int64> vTimeOffsets(200,0);
-bool fReopenDebugLog = false;
+volatile bool fReopenDebugLog = false;
// Init OpenSSL library multithreading support
static CCriticalSection** ppmutexOpenSSL;
@@ -195,62 +195,76 @@ uint256 GetRandHash()
+//
+// OutputDebugStringF (aka printf -- there is a #define that we really
+// should get rid of one day) has been broken a couple of times now
+// by well-meaning people adding mutexes in the most straightforward way.
+// It breaks because it may be called by global destructors during shutdown.
+// Since the order of destruction of static/global objects is undefined,
+// defining a mutex as a global object doesn't work (the mutex gets
+// destroyed, and then some later destructor calls OutputDebugStringF,
+// maybe indirectly, and you get a core dump at shutdown trying to lock
+// the mutex).
+
+static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT;
+// We use boost::call_once() to make sure these are initialized in
+// in a thread-safe manner the first time it is called:
+static FILE* fileout = NULL;
+static boost::mutex* mutexDebugLog = NULL;
+
+static void DebugPrintInit()
+{
+ assert(fileout == NULL);
+ assert(mutexDebugLog == NULL);
+
+ boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
+ fileout = fopen(pathDebug.string().c_str(), "a");
+ if (fileout) setbuf(fileout, NULL); // unbuffered
+
+ mutexDebugLog = new boost::mutex();
+}
-inline int OutputDebugStringF(const char* pszFormat, ...)
+int OutputDebugStringF(const char* pszFormat, ...)
{
- int ret = 0;
+ int ret = 0; // Returns total number of characters written
if (fPrintToConsole)
{
// print to console
va_list arg_ptr;
va_start(arg_ptr, pszFormat);
- ret = vprintf(pszFormat, arg_ptr);
+ ret += vprintf(pszFormat, arg_ptr);
va_end(arg_ptr);
}
else if (!fPrintToDebugger)
{
- // print to debug.log
- static FILE* fileout = NULL;
+ static bool fStartedNewLine = true;
+ boost::call_once(&DebugPrintInit, debugPrintInitFlag);
- if (!fileout)
- {
+ if (fileout == NULL)
+ return ret;
+
+ boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
+
+ // reopen the log file, if requested
+ if (fReopenDebugLog) {
+ fReopenDebugLog = false;
boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
- fileout = fopen(pathDebug.string().c_str(), "a");
- if (fileout) setbuf(fileout, NULL); // unbuffered
+ if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL)
+ setbuf(fileout, NULL); // unbuffered
}
- if (fileout)
- {
- static bool fStartedNewLine = true;
-
- // This routine may be called by global destructors during shutdown.
- // Since the order of destruction of static/global objects is undefined,
- // allocate mutexDebugLog on the heap the first time this routine
- // is called to avoid crashes during shutdown.
- static boost::mutex* mutexDebugLog = NULL;
- if (mutexDebugLog == NULL) mutexDebugLog = new boost::mutex();
- boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
-
- // reopen the log file, if requested
- if (fReopenDebugLog) {
- fReopenDebugLog = false;
- boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
- if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL)
- setbuf(fileout, NULL); // unbuffered
- }
- // Debug print useful for profiling
- if (fLogTimestamps && fStartedNewLine)
- fprintf(fileout, "%s ", DateTimeStrFormat("%Y-%m-%dT%H:%M:%S", GetTime()).c_str());
- if (pszFormat[strlen(pszFormat) - 1] == '\n')
- fStartedNewLine = true;
- else
- fStartedNewLine = false;
+ // Debug print useful for profiling
+ if (fLogTimestamps && fStartedNewLine)
+ ret += fprintf(fileout, "%s ", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str());
+ if (pszFormat[strlen(pszFormat) - 1] == '\n')
+ fStartedNewLine = true;
+ else
+ fStartedNewLine = false;
- va_list arg_ptr;
- va_start(arg_ptr, pszFormat);
- ret = vfprintf(fileout, pszFormat, arg_ptr);
- va_end(arg_ptr);
- }
+ va_list arg_ptr;
+ va_start(arg_ptr, pszFormat);
+ ret += vfprintf(fileout, pszFormat, arg_ptr);
+ va_end(arg_ptr);
}
#ifdef WIN32
@@ -273,6 +287,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
{
OutputDebugStringA(buffer.substr(line_start, line_end - line_start).c_str());
line_start = line_end + 1;
+ ret += line_end-line_start;
}
buffer.erase(0, line_start);
}
diff --git a/src/util.h b/src/util.h
index 8bea0dd2b3..97911d7493 100644
--- a/src/util.h
+++ b/src/util.h
@@ -138,7 +138,7 @@ extern std::string strMiscWarning;
extern bool fTestNet;
extern bool fNoListen;
extern bool fLogTimestamps;
-extern bool fReopenDebugLog;
+extern volatile bool fReopenDebugLog;
void RandAddSeed();
void RandAddSeedPerfmon();
diff --git a/src/walletdb.cpp b/src/walletdb.cpp
index 4419cbb5f7..2282bed18a 100644
--- a/src/walletdb.cpp
+++ b/src/walletdb.cpp
@@ -238,7 +238,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
//printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str());
//printf(" %12"PRI64d" %s %s %s\n",
// wtx.vout[0].nValue,
- // DateTimeStrFormat("%Y-%m-%dT%H:%M:%S", wtx.GetBlockTime()).c_str(),
+ // DateTimeStrFormat("%Y-%m-%d %H:%M:%S", wtx.GetBlockTime()).c_str(),
// wtx.hashBlock.ToString().substr(0,20).c_str(),
// wtx.mapValue["message"].c_str());
}