mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-26 10:03:52 +01:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
40cd036941 | ||
|
|
fe98cf8dc5 | ||
|
|
e96cd730d1 | ||
|
|
4110f33cde |
2
bugs.txt
2
bugs.txt
@@ -1,2 +0,0 @@
|
||||
Known bugs:
|
||||
- Window flickers when blocks are added (problem with repainting?)
|
||||
@@ -1,7 +0,0 @@
|
||||
Changes after 0.1.5:
|
||||
--------------------
|
||||
+ Options dialog layout changed - added the UI options panel
|
||||
+ Minimize to tray feature
|
||||
+ Startup on system boot feature
|
||||
+ Ask before closing
|
||||
+ NSIS installer
|
||||
36
db.cpp
36
db.cpp
@@ -130,7 +130,14 @@ void CDB::Close()
|
||||
vTxn.front()->abort();
|
||||
vTxn.clear();
|
||||
pdb = NULL;
|
||||
dbenv.txn_checkpoint(0, 0, 0);
|
||||
|
||||
// Flush database activity from memory pool to disk log
|
||||
unsigned int nMinutes = 0;
|
||||
if (strFile == "addr.dat")
|
||||
nMinutes = 2;
|
||||
if (strFile == "blkindex.dat" && IsInitialBlockDownload() && nBestHeight % 500 != 0)
|
||||
nMinutes = 1;
|
||||
dbenv.txn_checkpoint(0, nMinutes, 0);
|
||||
|
||||
CRITICAL_BLOCK(cs_db)
|
||||
--mapFileUseCount[strFile];
|
||||
@@ -357,11 +364,12 @@ CBlockIndex* InsertBlockIndex(uint256 hash)
|
||||
|
||||
bool CTxDB::LoadBlockIndex()
|
||||
{
|
||||
// Get cursor
|
||||
// Get database cursor
|
||||
Dbc* pcursor = GetCursor();
|
||||
if (!pcursor)
|
||||
return false;
|
||||
|
||||
// Load mapBlockIndex
|
||||
unsigned int fFlags = DB_SET_RANGE;
|
||||
loop
|
||||
{
|
||||
@@ -398,7 +406,7 @@ bool CTxDB::LoadBlockIndex()
|
||||
pindexNew->nBits = diskindex.nBits;
|
||||
pindexNew->nNonce = diskindex.nNonce;
|
||||
|
||||
// Watch for genesis block and best block
|
||||
// Watch for genesis block
|
||||
if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock)
|
||||
pindexGenesisBlock = pindexNew;
|
||||
}
|
||||
@@ -409,17 +417,33 @@ bool CTxDB::LoadBlockIndex()
|
||||
}
|
||||
pcursor->close();
|
||||
|
||||
// Calculate bnChainWork
|
||||
vector<pair<int, CBlockIndex*> > vSortedByHeight;
|
||||
vSortedByHeight.reserve(mapBlockIndex.size());
|
||||
foreach(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
|
||||
{
|
||||
CBlockIndex* pindex = item.second;
|
||||
vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex));
|
||||
}
|
||||
sort(vSortedByHeight.begin(), vSortedByHeight.end());
|
||||
foreach(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
|
||||
{
|
||||
CBlockIndex* pindex = item.second;
|
||||
pindex->bnChainWork = (pindex->pprev ? pindex->pprev->bnChainWork : 0) + pindex->GetBlockWork();
|
||||
}
|
||||
|
||||
// Load hashBestChain pointer to end of best chain
|
||||
if (!ReadHashBestChain(hashBestChain))
|
||||
{
|
||||
if (pindexGenesisBlock == NULL)
|
||||
return true;
|
||||
return error("CTxDB::LoadBlockIndex() : hashBestChain not found");
|
||||
return error("CTxDB::LoadBlockIndex() : hashBestChain not loaded");
|
||||
}
|
||||
|
||||
if (!mapBlockIndex.count(hashBestChain))
|
||||
return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found");
|
||||
return error("CTxDB::LoadBlockIndex() : hashBestChain not found in the block index");
|
||||
pindexBest = mapBlockIndex[hashBestChain];
|
||||
nBestHeight = pindexBest->nHeight;
|
||||
bnBestChainWork = pindexBest->bnChainWork;
|
||||
printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight);
|
||||
|
||||
return true;
|
||||
|
||||
4
db.h
4
db.h
@@ -16,7 +16,7 @@ extern map<string, string> mapAddressBook;
|
||||
extern CCriticalSection cs_mapAddressBook;
|
||||
extern vector<unsigned char> vchDefaultKey;
|
||||
extern bool fClient;
|
||||
|
||||
extern int nBestHeight;
|
||||
|
||||
|
||||
extern unsigned int nWalletDBUpdated;
|
||||
@@ -210,7 +210,7 @@ public:
|
||||
if (!pdb)
|
||||
return false;
|
||||
DbTxn* ptxn = NULL;
|
||||
int ret = dbenv.txn_begin(GetTxn(), &ptxn, 0);
|
||||
int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC);
|
||||
if (!ptxn || ret != 0)
|
||||
return false;
|
||||
vTxn.push_back(ptxn);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <wx/clipbrd.h>
|
||||
#include <wx/taskbar.h>
|
||||
#endif
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
@@ -64,6 +65,9 @@
|
||||
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
|
||||
#include <boost/date_time/gregorian/gregorian_types.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/program_options/detail/config_file.hpp>
|
||||
#include <boost/program_options/parsers.hpp>
|
||||
|
||||
#ifdef __WXMSW__
|
||||
#include <windows.h>
|
||||
|
||||
81
init.cpp
81
init.cpp
@@ -240,33 +240,34 @@ IMPLEMENT_APP(CMyApp)
|
||||
|
||||
bool CMyApp::Initialize(int& argc, wxChar** argv)
|
||||
{
|
||||
if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') &&
|
||||
wxString(argv[1]) != "start")
|
||||
for (int i = 1; i < argc; i++)
|
||||
if (!IsSwitchChar(argv[i][0]))
|
||||
fCommandLine = true;
|
||||
|
||||
if (!fCommandLine)
|
||||
{
|
||||
fCommandLine = true;
|
||||
}
|
||||
else if (!fGUI)
|
||||
{
|
||||
fDaemon = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// wxApp::Initialize will remove environment-specific parameters,
|
||||
// so it's too early to call ParseParameters yet
|
||||
for (int i = 1; i < argc; i++)
|
||||
if (!fGUI)
|
||||
{
|
||||
wxString str = argv[i];
|
||||
#ifdef __WXMSW__
|
||||
if (str.size() >= 1 && str[0] == '/')
|
||||
str[0] = '-';
|
||||
char pszLower[MAX_PATH];
|
||||
strlcpy(pszLower, str.c_str(), sizeof(pszLower));
|
||||
strlwr(pszLower);
|
||||
str = pszLower;
|
||||
#endif
|
||||
// haven't decided which argument to use for this yet
|
||||
if (str == "-daemon" || str == "-d" || str == "start")
|
||||
fDaemon = true;
|
||||
fDaemon = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// wxApp::Initialize will remove environment-specific parameters,
|
||||
// so it's too early to call ParseParameters yet
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
wxString str = argv[i];
|
||||
#ifdef __WXMSW__
|
||||
if (str.size() >= 1 && str[0] == '/')
|
||||
str[0] = '-';
|
||||
char pszLower[MAX_PATH];
|
||||
strlcpy(pszLower, str.c_str(), sizeof(pszLower));
|
||||
strlwr(pszLower);
|
||||
str = pszLower;
|
||||
#endif
|
||||
if (str == "-daemon")
|
||||
fDaemon = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,22 +376,23 @@ bool CMyApp::OnInit2()
|
||||
//
|
||||
// Parameters
|
||||
//
|
||||
if (fCommandLine)
|
||||
{
|
||||
int ret = CommandLineRPC(argc, argv);
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
ParseParameters(argc, argv);
|
||||
|
||||
if (mapArgs.count("-datadir"))
|
||||
strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir));
|
||||
|
||||
ReadConfigFile(mapArgs, mapMultiArgs); // Must be done after processing datadir
|
||||
|
||||
if (mapArgs.count("-?") || mapArgs.count("--help"))
|
||||
{
|
||||
wxString strUsage = string() +
|
||||
_("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" +
|
||||
" bitcoin [options] \t" + "\n" +
|
||||
" bitcoin [command] \t" + _("Send command to bitcoin running with -server or -daemon\n") +
|
||||
" bitcoin [command] -? \t" + _("Get help for a command\n") +
|
||||
" bitcoin help \t" + _("List commands\n") +
|
||||
" bitcoin [options] \t " + "\n" +
|
||||
" bitcoin [options] <command> [params]\t " + _("Send command to -server or bitcoind\n") +
|
||||
" bitcoin [options] <command> -? \t\t " + _("Get help for a command\n") +
|
||||
" bitcoin help \t\t\t " + _("List commands\n") +
|
||||
_("Options:\n") +
|
||||
" -conf=<file> \t " + _("Specify configuration file (default: bitcoin.conf)\n") +
|
||||
" -gen \t " + _("Generate coins\n") +
|
||||
" -gen=0 \t " + _("Don't generate coins\n") +
|
||||
" -min \t " + _("Start minimized\n") +
|
||||
@@ -413,15 +415,18 @@ bool CMyApp::OnInit2()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mapArgs.count("-datadir"))
|
||||
strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir));
|
||||
|
||||
if (mapArgs.count("-debug"))
|
||||
fDebug = true;
|
||||
|
||||
if (mapArgs.count("-printtodebugger"))
|
||||
fPrintToDebugger = true;
|
||||
|
||||
if (fCommandLine)
|
||||
{
|
||||
int ret = CommandLineRPC(argc, argv);
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
Binary file not shown.
@@ -216,7 +216,7 @@ msgstr "&Neue Empfangs-Adresse"
|
||||
#: ../../../ui.cpp:1124
|
||||
#: ../../../ui.cpp:2352
|
||||
msgid ""
|
||||
"It's good policy to use a new address for each payment you receive.\n"
|
||||
"You should use a new address for each payment you receive.\n"
|
||||
"\n"
|
||||
"Label"
|
||||
msgstr ""
|
||||
|
||||
Binary file not shown.
@@ -242,7 +242,7 @@ msgstr "Nueva direccion de recepcion"
|
||||
#: ../../../ui.cpp:1129
|
||||
#: ../../../ui.cpp:2369
|
||||
msgid ""
|
||||
"It's good policy to use a new address for each payment you receive.\n"
|
||||
"You should use a new address for each payment you receive.\n"
|
||||
"\n"
|
||||
"Label"
|
||||
msgstr ""
|
||||
|
||||
Binary file not shown.
@@ -242,7 +242,7 @@ msgstr "Nouvelle adresse de reception"
|
||||
#: ../../../ui.cpp:1129
|
||||
#: ../../../ui.cpp:2369
|
||||
msgid ""
|
||||
"It's good policy to use a new address for each payment you receive.\n"
|
||||
"You should use a new address for each payment you receive.\n"
|
||||
"\n"
|
||||
"Label"
|
||||
msgstr ""
|
||||
|
||||
Binary file not shown.
@@ -216,7 +216,7 @@ msgstr "Nuovo indirizzo ricevente"
|
||||
#: ../../../ui.cpp:1124
|
||||
#: ../../../ui.cpp:2352
|
||||
msgid ""
|
||||
"It's good policy to use a new address for each payment you receive.\n"
|
||||
"You should use a new address for each payment you receive.\n"
|
||||
"\n"
|
||||
"Label"
|
||||
msgstr ""
|
||||
|
||||
Binary file not shown.
@@ -216,7 +216,7 @@ msgstr "Nieuw Ontvangings Adres"
|
||||
#: ../../../ui.cpp:1124
|
||||
#: ../../../ui.cpp:2352
|
||||
msgid ""
|
||||
"It's good policy to use a new address for each payment you receive.\n"
|
||||
"You should use a new address for each payment you receive.\n"
|
||||
"\n"
|
||||
"Label"
|
||||
msgstr ""
|
||||
|
||||
Binary file not shown.
@@ -216,7 +216,7 @@ msgstr "Novo Endereço de Recepção"
|
||||
#: ../../../ui.cpp:1124
|
||||
#: ../../../ui.cpp:2352
|
||||
msgid ""
|
||||
"It's good policy to use a new address for each payment you receive.\n"
|
||||
"You should use a new address for each payment you receive.\n"
|
||||
"\n"
|
||||
"Label"
|
||||
msgstr ""
|
||||
|
||||
57
main.cpp
57
main.cpp
@@ -24,6 +24,7 @@ map<uint256, CBlockIndex*> mapBlockIndex;
|
||||
const uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
|
||||
CBlockIndex* pindexGenesisBlock = NULL;
|
||||
int nBestHeight = -1;
|
||||
CBigNum bnBestChainWork = 0;
|
||||
uint256 hashBestChain = 0;
|
||||
CBlockIndex* pindexBest = NULL;
|
||||
int64 nTimeBestReceived = 0;
|
||||
@@ -848,6 +849,23 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast)
|
||||
return bnNew.GetCompact();
|
||||
}
|
||||
|
||||
vector<int> vStartingHeight;
|
||||
void AddStartingHeight(int nStartingHeight)
|
||||
{
|
||||
if (nStartingHeight != -1)
|
||||
{
|
||||
vStartingHeight.push_back(nStartingHeight);
|
||||
sort(vStartingHeight.begin(), vStartingHeight.end());
|
||||
}
|
||||
}
|
||||
|
||||
bool IsInitialBlockDownload()
|
||||
{
|
||||
int nMedian = 69000;
|
||||
if (vStartingHeight.size() >= 5)
|
||||
nMedian = vStartingHeight[vStartingHeight.size()/2];
|
||||
return nBestHeight < nMedian-1000;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1208,13 +1226,14 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
|
||||
pindexNew->pprev = (*miPrev).second;
|
||||
pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
|
||||
}
|
||||
pindexNew->bnChainWork = (pindexNew->pprev ? pindexNew->pprev->bnChainWork : 0) + pindexNew->GetBlockWork();
|
||||
|
||||
CTxDB txdb;
|
||||
txdb.TxnBegin();
|
||||
txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew));
|
||||
|
||||
// New best
|
||||
if (pindexNew->nHeight > nBestHeight)
|
||||
if (pindexNew->bnChainWork > bnBestChainWork)
|
||||
{
|
||||
if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
|
||||
{
|
||||
@@ -1253,6 +1272,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
|
||||
hashBestChain = hash;
|
||||
pindexBest = pindexNew;
|
||||
nBestHeight = pindexBest->nHeight;
|
||||
bnBestChainWork = pindexNew->bnChainWork;
|
||||
nTimeBestReceived = GetTime();
|
||||
nTransactionsUpdated++;
|
||||
printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight);
|
||||
@@ -1341,6 +1361,14 @@ bool CBlock::AcceptBlock()
|
||||
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 (pindexPrev->nHeight+1 == 11111 && hash != uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
|
||||
return error("AcceptBlock() : rejected by checkpoint lockin at 11111");
|
||||
if (pindexPrev->nHeight+1 == 33333 && hash != uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
|
||||
return error("AcceptBlock() : rejected by checkpoint lockin at 33333");
|
||||
if (pindexPrev->nHeight+1 == 68555 && hash != uint256("0x00000000001e1b4903550a0b96e9a9405c8a95f387162e4944e8d9fbe501cd6a"))
|
||||
return error("AcceptBlock() : rejected by checkpoint lockin at 68555");
|
||||
|
||||
// Write block to history file
|
||||
if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK)))
|
||||
return error("AcceptBlock() : out of disk space");
|
||||
@@ -1892,6 +1920,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
}
|
||||
|
||||
AddTimeData(pfrom->addr.ip, nTime);
|
||||
AddStartingHeight(pfrom->nStartingHeight);
|
||||
|
||||
// Change version
|
||||
if (pfrom->nVersion >= 209)
|
||||
@@ -1933,6 +1962,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
vRecv >> vAddr;
|
||||
if (pfrom->nVersion < 200) // don't want addresses from 0.1.5
|
||||
return true;
|
||||
if (pfrom->nVersion < 209 && mapAddresses.size() > 1000) // don't want addr from 0.2.0 unless seeding
|
||||
return true;
|
||||
if (vAddr.size() > 1000)
|
||||
return error("message addr size() = %d", vAddr.size());
|
||||
|
||||
@@ -1941,6 +1972,9 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
{
|
||||
if (fShutdown)
|
||||
return true;
|
||||
// ignore IPv6 for now, since it isn't implemented anyway
|
||||
if (!addr.IsIPv4())
|
||||
continue;
|
||||
addr.nTime = GetAdjustedTime() - 2 * 60 * 60;
|
||||
if (pfrom->fGetAddr || vAddr.size() > 10)
|
||||
addr.nTime -= 5 * 24 * 60 * 60;
|
||||
@@ -1952,15 +1986,15 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
// Use deterministic randomness to send to
|
||||
// the same places for an hour at a time
|
||||
// the same places for 12 hours at a time
|
||||
static uint256 hashSalt;
|
||||
if (hashSalt == 0)
|
||||
RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
|
||||
uint256 hashRand = addr.ip ^ (GetTime()/3600) ^ hashSalt;
|
||||
uint256 hashRand = addr.ip ^ ((GetTime()+addr.ip)/(12*60*60)) ^ hashSalt;
|
||||
multimap<uint256, CNode*> mapMix;
|
||||
foreach(CNode* pnode, vNodes)
|
||||
mapMix.insert(make_pair(hashRand = Hash(BEGIN(hashRand), END(hashRand)), pnode));
|
||||
int nRelayNodes = 10; // reduce this to 5 when the network is large
|
||||
int nRelayNodes = 4;
|
||||
for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
|
||||
((*mi).second)->PushAddress(addr);
|
||||
}
|
||||
@@ -2832,6 +2866,10 @@ int64 GetBalance()
|
||||
}
|
||||
|
||||
|
||||
int GetRandInt(int nMax)
|
||||
{
|
||||
return GetRand(nMax);
|
||||
}
|
||||
|
||||
bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet)
|
||||
{
|
||||
@@ -2845,9 +2883,14 @@ bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet)
|
||||
|
||||
CRITICAL_BLOCK(cs_mapWallet)
|
||||
{
|
||||
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
{
|
||||
CWalletTx* pcoin = &(*it).second;
|
||||
vector<CWalletTx*> vCoins;
|
||||
vCoins.reserve(mapWallet.size());
|
||||
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
vCoins.push_back(&(*it).second);
|
||||
random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
|
||||
|
||||
foreach(CWalletTx* pcoin, vCoins)
|
||||
{
|
||||
if (!pcoin->IsFinal() || pcoin->fSpent)
|
||||
continue;
|
||||
int64 n = pcoin->GetCredit();
|
||||
|
||||
17
main.h
17
main.h
@@ -32,6 +32,7 @@ extern map<uint256, CBlockIndex*> mapBlockIndex;
|
||||
extern const uint256 hashGenesisBlock;
|
||||
extern CBlockIndex* pindexGenesisBlock;
|
||||
extern int nBestHeight;
|
||||
extern CBigNum bnBestChainWork;
|
||||
extern uint256 hashBestChain;
|
||||
extern CBlockIndex* pindexBest;
|
||||
extern unsigned int nTransactionsUpdated;
|
||||
@@ -78,6 +79,7 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx
|
||||
void GenerateBitcoins(bool fGenerate);
|
||||
void ThreadBitcoinMiner(void* parg);
|
||||
void BitcoinMiner();
|
||||
bool IsInitialBlockDownload();
|
||||
|
||||
|
||||
|
||||
@@ -986,11 +988,14 @@ public:
|
||||
|
||||
// Flush stdio buffers and commit to disk before returning
|
||||
fflush(fileout);
|
||||
if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
_commit(_fileno(fileout));
|
||||
_commit(_fileno(fileout));
|
||||
#else
|
||||
fsync(fileno(fileout));
|
||||
fsync(fileno(fileout));
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1072,6 +1077,7 @@ public:
|
||||
unsigned int nFile;
|
||||
unsigned int nBlockPos;
|
||||
int nHeight;
|
||||
CBigNum bnChainWork;
|
||||
|
||||
// block header
|
||||
int nVersion;
|
||||
@@ -1089,6 +1095,7 @@ public:
|
||||
nFile = 0;
|
||||
nBlockPos = 0;
|
||||
nHeight = 0;
|
||||
bnChainWork = 0;
|
||||
|
||||
nVersion = 0;
|
||||
hashMerkleRoot = 0;
|
||||
@@ -1105,6 +1112,7 @@ public:
|
||||
nFile = nFileIn;
|
||||
nBlockPos = nBlockPosIn;
|
||||
nHeight = 0;
|
||||
bnChainWork = 0;
|
||||
|
||||
nVersion = block.nVersion;
|
||||
hashMerkleRoot = block.hashMerkleRoot;
|
||||
@@ -1118,6 +1126,11 @@ public:
|
||||
return *phashBlock;
|
||||
}
|
||||
|
||||
CBigNum GetBlockWork() const
|
||||
{
|
||||
return (CBigNum(1)<<256) / (CBigNum().SetCompact(nBits)+1);
|
||||
}
|
||||
|
||||
bool IsInMainChain() const
|
||||
{
|
||||
return (pnext || this == pindexBest);
|
||||
|
||||
@@ -22,7 +22,7 @@ WXLIBS= \
|
||||
-l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd
|
||||
|
||||
LIBS= \
|
||||
-l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \
|
||||
-l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d -l libboost_program_options-mgw34-mt-d \
|
||||
-l db_cxx \
|
||||
-l eay32 \
|
||||
-l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi
|
||||
|
||||
@@ -19,6 +19,7 @@ LIBS= -dead_strip \
|
||||
$(DEPSDIR)/lib/libdb_cxx-4.8.a \
|
||||
$(DEPSDIR)/lib/libboost_system.a \
|
||||
$(DEPSDIR)/lib/libboost_filesystem.a \
|
||||
$(DEPSDIR)/lib/libboost_program_options.a \
|
||||
$(DEPSDIR)/lib/libcrypto.a
|
||||
|
||||
WXDEFS=$(shell $(DEPSDIR)/bin/wx-config --cxxflags) -DNOPCH -DMSG_NOSIGNAL=0
|
||||
|
||||
@@ -21,7 +21,7 @@ WXLIBS= \
|
||||
|
||||
LIBS= \
|
||||
-Wl,-Bstatic \
|
||||
-l boost_system -l boost_filesystem \
|
||||
-l boost_system -l boost_filesystem -l boost_program_options \
|
||||
-l db_cxx \
|
||||
-l crypto \
|
||||
-Wl,-Bdynamic \
|
||||
|
||||
@@ -19,7 +19,7 @@ LIBPATHS= \
|
||||
/LIBPATH:"/wxwidgets/lib/vc_lib"
|
||||
|
||||
LIBS= \
|
||||
libboost_system-vc80-mt-gd.lib libboost_filesystem-vc80-mt-gd.lib \
|
||||
libboost_system-vc80-mt-gd.lib libboost_filesystem-vc80-mt-gd.lib libboost_program_options-vc80-mt-gd.lib \
|
||||
libdb47sd.lib \
|
||||
libeay32.lib \
|
||||
wxmsw29ud_html.lib wxmsw29ud_core.lib wxmsw29ud_adv.lib wxbase29ud.lib wxtiffd.lib wxjpegd.lib wxpngd.lib wxzlibd.lib \
|
||||
|
||||
239
rpc.cpp
239
rpc.cpp
@@ -23,6 +23,28 @@ extern map<string, rpcfn_type> mapCallTable;
|
||||
|
||||
|
||||
|
||||
void PrintConsole(const char* format, ...)
|
||||
{
|
||||
char buffer[50000];
|
||||
int limit = sizeof(buffer);
|
||||
va_list arg_ptr;
|
||||
va_start(arg_ptr, format);
|
||||
int ret = _vsnprintf(buffer, limit, format, arg_ptr);
|
||||
va_end(arg_ptr);
|
||||
if (ret < 0 || ret >= limit)
|
||||
{
|
||||
ret = limit - 1;
|
||||
buffer[limit-1] = 0;
|
||||
}
|
||||
#if defined(__WXMSW__) && wxUSE_GUI
|
||||
MyMessageBox(buffer, "Bitcoin", wxOK | wxICON_EXCLAMATION);
|
||||
#else
|
||||
fprintf(stdout, "%s", buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -32,7 +54,6 @@ extern map<string, rpcfn_type> mapCallTable;
|
||||
///
|
||||
|
||||
|
||||
|
||||
Value help(const Array& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
@@ -41,12 +62,20 @@ Value help(const Array& params, bool fHelp)
|
||||
"List commands.");
|
||||
|
||||
string strRet;
|
||||
set<rpcfn_type> setDone;
|
||||
for (map<string, rpcfn_type>::iterator mi = mapCallTable.begin(); mi != mapCallTable.end(); ++mi)
|
||||
{
|
||||
string strMethod = (*mi).first;
|
||||
// We already filter duplicates, but these deprecated screw up the sort order
|
||||
if (strMethod == "getamountreceived" ||
|
||||
strMethod == "getallreceived")
|
||||
continue;
|
||||
try
|
||||
{
|
||||
Array params;
|
||||
(*(*mi).second)(params, true);
|
||||
rpcfn_type pfn = (*mi).second;
|
||||
if (setDone.insert(pfn).second)
|
||||
(*pfn)(params, true);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
@@ -603,7 +632,6 @@ pair<string, rpcfn_type> pCallTable[] =
|
||||
make_pair("getlabel", &getlabel),
|
||||
make_pair("getaddressesbylabel", &getaddressesbylabel),
|
||||
make_pair("sendtoaddress", &sendtoaddress),
|
||||
make_pair("listtransactions", &listtransactions),
|
||||
make_pair("getamountreceived", &getreceivedbyaddress), // deprecated, renamed to getreceivedbyaddress
|
||||
make_pair("getallreceived", &listreceivedbyaddress), // deprecated, renamed to listreceivedbyaddress
|
||||
make_pair("getreceivedbyaddress", &getreceivedbyaddress),
|
||||
@@ -623,23 +651,41 @@ map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)
|
||||
// and to be compatible with other JSON-RPC implementations.
|
||||
//
|
||||
|
||||
string HTTPPost(const string& strMsg)
|
||||
string HTTPPost(const string& strMsg, const map<string,string>& mapRequestHeaders)
|
||||
{
|
||||
return strprintf(
|
||||
"POST / HTTP/1.1\r\n"
|
||||
"User-Agent: json-rpc/1.0\r\n"
|
||||
"Host: 127.0.0.1\r\n"
|
||||
"Content-Type: application/json\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"Accept: application/json\r\n"
|
||||
"\r\n"
|
||||
"%s",
|
||||
strMsg.size(),
|
||||
strMsg.c_str());
|
||||
ostringstream s;
|
||||
s << "POST / HTTP/1.1\r\n"
|
||||
<< "User-Agent: json-rpc/1.0\r\n"
|
||||
<< "Host: 127.0.0.1\r\n"
|
||||
<< "Content-Type: application/json\r\n"
|
||||
<< "Content-Length: " << strMsg.size() << "\r\n"
|
||||
<< "Accept: application/json\r\n";
|
||||
for (map<string,string>::const_iterator it = mapRequestHeaders.begin(); it != mapRequestHeaders.end(); ++it)
|
||||
s << it->first << ": " << it->second << "\r\n";
|
||||
s << "\r\n" << strMsg;
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
string HTTPReply(const string& strMsg, int nStatus=200)
|
||||
{
|
||||
if (nStatus == 401)
|
||||
return "HTTP/1.0 401 Authorization Required\r\n"
|
||||
"Server: HTTPd/1.0\r\n"
|
||||
"Date: Sat, 08 Jul 2006 12:04:08 GMT\r\n"
|
||||
"WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n"
|
||||
"Content-Type: text/html\r\n"
|
||||
"Content-Length: 311\r\n"
|
||||
"\r\n"
|
||||
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
|
||||
"\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\r\n"
|
||||
"<HTML>\r\n"
|
||||
"<HEAD>\r\n"
|
||||
"<TITLE>Error</TITLE>\r\n"
|
||||
"<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-1'>\r\n"
|
||||
"</HEAD>\r\n"
|
||||
"<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
|
||||
"</HTML>\r\n";
|
||||
string strStatus;
|
||||
if (nStatus == 200) strStatus = "OK";
|
||||
if (nStatus == 500) strStatus = "Internal Server Error";
|
||||
@@ -658,7 +704,17 @@ string HTTPReply(const string& strMsg, int nStatus=200)
|
||||
strMsg.c_str());
|
||||
}
|
||||
|
||||
int ReadHTTPHeader(tcp::iostream& stream)
|
||||
int ReadHTTPStatus(tcp::iostream& stream)
|
||||
{
|
||||
string str;
|
||||
getline(stream, str);
|
||||
vector<string> vWords;
|
||||
boost::split(vWords, str, boost::is_any_of(" "));
|
||||
int nStatus = atoi(vWords[1].c_str());
|
||||
return nStatus;
|
||||
}
|
||||
|
||||
int ReadHTTPHeader(tcp::iostream& stream, map<string, string>& mapHeadersRet)
|
||||
{
|
||||
int nLen = 0;
|
||||
loop
|
||||
@@ -667,26 +723,92 @@ int ReadHTTPHeader(tcp::iostream& stream)
|
||||
std::getline(stream, str);
|
||||
if (str.empty() || str == "\r")
|
||||
break;
|
||||
if (str.substr(0,15) == "Content-Length:")
|
||||
nLen = atoi(str.substr(15));
|
||||
string::size_type nColon = str.find(":");
|
||||
if (nColon != string::npos)
|
||||
{
|
||||
string strHeader = str.substr(0, nColon);
|
||||
boost::trim(strHeader);
|
||||
string strValue = str.substr(nColon+1);
|
||||
boost::trim(strValue);
|
||||
mapHeadersRet[strHeader] = strValue;
|
||||
if (strHeader == "Content-Length")
|
||||
nLen = atoi(strValue.c_str());
|
||||
}
|
||||
}
|
||||
return nLen;
|
||||
}
|
||||
|
||||
inline string ReadHTTP(tcp::iostream& stream)
|
||||
int ReadHTTP(tcp::iostream& stream, map<string, string>& mapHeadersRet, string& strMessageRet)
|
||||
{
|
||||
mapHeadersRet.clear();
|
||||
strMessageRet = "";
|
||||
|
||||
// Read status
|
||||
int nStatus = ReadHTTPStatus(stream);
|
||||
|
||||
// Read header
|
||||
int nLen = ReadHTTPHeader(stream);
|
||||
int nLen = ReadHTTPHeader(stream, mapHeadersRet);
|
||||
if (nLen <= 0)
|
||||
return string();
|
||||
return 500;
|
||||
|
||||
// Read message
|
||||
vector<char> vch(nLen);
|
||||
stream.read(&vch[0], nLen);
|
||||
return string(vch.begin(), vch.end());
|
||||
strMessageRet = string(vch.begin(), vch.end());
|
||||
|
||||
return nStatus;
|
||||
}
|
||||
|
||||
string EncodeBase64(string s)
|
||||
{
|
||||
BIO *b64, *bmem;
|
||||
BUF_MEM *bptr;
|
||||
|
||||
b64 = BIO_new(BIO_f_base64());
|
||||
bmem = BIO_new(BIO_s_mem());
|
||||
b64 = BIO_push(b64, bmem);
|
||||
BIO_write(b64, s.c_str(), s.size());
|
||||
BIO_flush(b64);
|
||||
BIO_get_mem_ptr(b64, &bptr);
|
||||
|
||||
string result(bptr->data, bptr->length-1);
|
||||
BIO_free_all(b64);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
string DecodeBase64(string s)
|
||||
{
|
||||
BIO *b64, *bmem;
|
||||
|
||||
char* buffer = static_cast<char*>(calloc(s.size(), sizeof(char)));
|
||||
|
||||
b64 = BIO_new(BIO_f_base64());
|
||||
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
|
||||
bmem = BIO_new_mem_buf(const_cast<char*>(s.c_str()), s.size());
|
||||
bmem = BIO_push(b64, bmem);
|
||||
BIO_read(bmem, buffer, s.size());
|
||||
BIO_free_all(bmem);
|
||||
|
||||
string result(buffer);
|
||||
free(buffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool HTTPAuthorized(map<string, string>& mapHeaders)
|
||||
{
|
||||
string strAuth = mapHeaders["Authorization"];
|
||||
if (strAuth.substr(0,6) != "Basic ")
|
||||
return false;
|
||||
string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64);
|
||||
string strUserPass = DecodeBase64(strUserPass64);
|
||||
string::size_type nColon = strUserPass.find(":");
|
||||
if (nColon == string::npos)
|
||||
return false;
|
||||
string strUser = strUserPass.substr(0, nColon);
|
||||
string strPassword = strUserPass.substr(nColon+1);
|
||||
return (strUser == mapArgs["-rpcuser"] && strPassword == mapArgs["-rpcpassword"]);
|
||||
}
|
||||
|
||||
//
|
||||
// JSON-RPC protocol
|
||||
@@ -742,6 +864,22 @@ void ThreadRPCServer2(void* parg)
|
||||
{
|
||||
printf("ThreadRPCServer started\n");
|
||||
|
||||
if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
|
||||
{
|
||||
string strWhatAmI = "To use bitcoind";
|
||||
if (mapArgs.count("-server"))
|
||||
strWhatAmI = strprintf(_("To use the %s option"), "\"-server\"");
|
||||
else if (mapArgs.count("-daemon"))
|
||||
strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\"");
|
||||
PrintConsole(
|
||||
_("Warning: %s, you must set rpcpassword=<password>\nin the configuration file: %s\n"
|
||||
"If the file does not exist, create it with owner-readable-only file permissions.\n"),
|
||||
strWhatAmI.c_str(),
|
||||
GetConfigFile().c_str());
|
||||
CreateThread(Shutdown, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Bind to loopback 127.0.0.1 so the socket can only be accessed locally
|
||||
boost::asio::io_service io_service;
|
||||
tcp::endpoint endpoint(boost::asio::ip::address_v4::loopback(), 8332);
|
||||
@@ -763,8 +901,26 @@ void ThreadRPCServer2(void* parg)
|
||||
continue;
|
||||
|
||||
// Receive request
|
||||
string strRequest = ReadHTTP(stream);
|
||||
printf("ThreadRPCServer request=%s", strRequest.c_str());
|
||||
map<string, string> mapHeaders;
|
||||
string strRequest;
|
||||
ReadHTTP(stream, mapHeaders, strRequest);
|
||||
|
||||
// Check authorization
|
||||
if (mapHeaders.count("Authorization") == 0)
|
||||
{
|
||||
stream << HTTPReply("", 401) << std::flush;
|
||||
continue;
|
||||
}
|
||||
if (!HTTPAuthorized(mapHeaders))
|
||||
{
|
||||
// Deter brute-forcing short passwords
|
||||
if (mapArgs["-rpcpassword"].size() < 15)
|
||||
Sleep(50);
|
||||
|
||||
stream << HTTPReply("", 401) << std::flush;
|
||||
printf("ThreadRPCServer incorrect password attempt\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle multiple invocations per request
|
||||
string::iterator begin = strRequest.begin();
|
||||
@@ -787,6 +943,8 @@ void ThreadRPCServer2(void* parg)
|
||||
const Array& params = find_value(request, "params").get_array();
|
||||
id = find_value(request, "id");
|
||||
|
||||
printf("ThreadRPCServer method=%s\n", strMethod.c_str());
|
||||
|
||||
// Execute
|
||||
map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod);
|
||||
if (mi == mapCallTable.end())
|
||||
@@ -814,18 +972,36 @@ void ThreadRPCServer2(void* parg)
|
||||
|
||||
Value CallRPC(const string& strMethod, const Array& params)
|
||||
{
|
||||
if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
|
||||
throw runtime_error(strprintf(
|
||||
_("You must set rpcpassword=<password> in the configuration file:\n%s\n"
|
||||
"If the file does not exist, create it with owner-readable-only file permissions."),
|
||||
GetConfigFile().c_str()));
|
||||
|
||||
// Connect to localhost
|
||||
tcp::iostream stream("127.0.0.1", "8332");
|
||||
if (stream.fail())
|
||||
throw runtime_error("couldn't connect to server");
|
||||
|
||||
// HTTP basic authentication
|
||||
string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);
|
||||
map<string, string> mapRequestHeaders;
|
||||
mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64;
|
||||
|
||||
// Send request
|
||||
string strRequest = JSONRPCRequest(strMethod, params, 1);
|
||||
stream << HTTPPost(strRequest) << std::flush;
|
||||
string strPost = HTTPPost(strRequest, mapRequestHeaders);
|
||||
stream << strPost << std::flush;
|
||||
|
||||
// Receive reply
|
||||
string strReply = ReadHTTP(stream);
|
||||
if (strReply.empty())
|
||||
map<string, string> mapHeaders;
|
||||
string strReply;
|
||||
int nStatus = ReadHTTP(stream, mapHeaders, strReply);
|
||||
if (nStatus == 401)
|
||||
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
|
||||
else if (nStatus >= 400 && nStatus != 500)
|
||||
throw runtime_error(strprintf("server returned HTTP error %d", nStatus));
|
||||
else if (strReply.empty())
|
||||
throw runtime_error("no response from server");
|
||||
|
||||
// Parse reply
|
||||
@@ -871,7 +1047,14 @@ int CommandLineRPC(int argc, char *argv[])
|
||||
{
|
||||
try
|
||||
{
|
||||
// Check that method exists
|
||||
// Skip switches
|
||||
while (argc > 1 && IsSwitchChar(argv[1][0]))
|
||||
{
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
// Check that the method exists
|
||||
if (argc < 2)
|
||||
throw runtime_error("too few parameters");
|
||||
string strMethod = argv[1];
|
||||
|
||||
@@ -19,7 +19,7 @@ class CScript;
|
||||
class CDataStream;
|
||||
class CAutoFile;
|
||||
|
||||
static const int VERSION = 301;
|
||||
static const int VERSION = 303;
|
||||
static const char* pszSubVer = "";
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ RequestExecutionLevel highest
|
||||
|
||||
# General Symbol Definitions
|
||||
!define REGKEY "SOFTWARE\$(^Name)"
|
||||
!define VERSION 0.3.1
|
||||
!define VERSION 0.3.3
|
||||
!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.1-win32-setup.exe
|
||||
OutFile bitcoin-0.3.3-win32-setup.exe
|
||||
InstallDir $PROGRAMFILES\Bitcoin
|
||||
CRCCheck on
|
||||
XPStyle on
|
||||
ShowInstDetails show
|
||||
VIProductVersion 0.3.1.0
|
||||
VIProductVersion 0.3.3.0
|
||||
VIAddVersionKey ProductName Bitcoin
|
||||
VIAddVersionKey ProductVersion "${VERSION}"
|
||||
VIAddVersionKey CompanyName "${COMPANY}"
|
||||
|
||||
5
ui.cpp
5
ui.cpp
@@ -1132,7 +1132,7 @@ void CMainFrame::OnButtonNew(wxCommandEvent& event)
|
||||
// Ask name
|
||||
CGetTextFromUserDialog dialog(this,
|
||||
_("New Receiving Address"),
|
||||
_("It's good policy to use a new address for each payment you receive.\n\nLabel"),
|
||||
_("You should use a new address for each payment you receive.\n\nLabel"),
|
||||
"");
|
||||
if (!dialog.ShowModal())
|
||||
return;
|
||||
@@ -1614,6 +1614,7 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event)
|
||||
CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent)
|
||||
{
|
||||
m_staticTextVersion->SetLabel(strprintf(_("version %d.%d.%d beta"), VERSION/10000, (VERSION/100)%100, VERSION%100));
|
||||
//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();
|
||||
@@ -2372,7 +2373,7 @@ void CAddressBookDialog::OnButtonNew(wxCommandEvent& event)
|
||||
// Ask name
|
||||
CGetTextFromUserDialog dialog(this,
|
||||
_("New Receiving Address"),
|
||||
_("It's good policy to use a new address for each payment you receive.\n\nLabel"),
|
||||
_("You should use a new address for each payment you receive.\n\nLabel"),
|
||||
"");
|
||||
if (!dialog.ShowModal())
|
||||
return;
|
||||
|
||||
2
uibase.h
2
uibase.h
@@ -227,7 +227,7 @@ class CAboutDialogBase : public wxDialog
|
||||
|
||||
public:
|
||||
wxStaticText* m_staticTextVersion;
|
||||
CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 532,329 ), long style = wxDEFAULT_DIALOG_STYLE );
|
||||
CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 532,333 ), long style = wxDEFAULT_DIALOG_STYLE );
|
||||
~CAboutDialogBase();
|
||||
|
||||
};
|
||||
|
||||
@@ -2866,7 +2866,7 @@
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">CAboutDialogBase</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size">532,329</property>
|
||||
<property name="size">532,333</property>
|
||||
<property name="style">wxDEFAULT_DIALOG_STYLE</property>
|
||||
<property name="subclass"></property>
|
||||
<property name="title">About Bitcoin</property>
|
||||
|
||||
42
util.cpp
42
util.cpp
@@ -416,7 +416,7 @@ void ParseParameters(int argc, char* argv[])
|
||||
{
|
||||
mapArgs.clear();
|
||||
mapMultiArgs.clear();
|
||||
for (int i = 0; i < argc; i++)
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
char psz[10000];
|
||||
strlcpy(psz, argv[i], sizeof(psz));
|
||||
@@ -431,6 +431,8 @@ void ParseParameters(int argc, char* argv[])
|
||||
if (psz[0] == '/')
|
||||
psz[0] = '-';
|
||||
#endif
|
||||
if (psz[0] != '-')
|
||||
break;
|
||||
mapArgs[psz] = pszValue;
|
||||
mapMultiArgs[psz].push_back(pszValue);
|
||||
}
|
||||
@@ -619,6 +621,38 @@ string GetDataDir()
|
||||
return pszDir;
|
||||
}
|
||||
|
||||
string GetConfigFile()
|
||||
{
|
||||
namespace fs = boost::filesystem;
|
||||
fs::path pathConfig(mapArgs.count("-conf") ? mapArgs["-conf"] : string("bitcoin.conf"));
|
||||
if (!pathConfig.is_complete())
|
||||
pathConfig = fs::path(GetDataDir()) / pathConfig;
|
||||
return pathConfig.string();
|
||||
}
|
||||
|
||||
void ReadConfigFile(map<string, string>& mapSettingsRet,
|
||||
map<string, vector<string> >& mapMultiSettingsRet)
|
||||
{
|
||||
namespace fs = boost::filesystem;
|
||||
namespace pod = boost::program_options::detail;
|
||||
|
||||
fs::ifstream streamConfig(GetConfigFile());
|
||||
if (!streamConfig.good())
|
||||
return;
|
||||
|
||||
set<string> setOptions;
|
||||
setOptions.insert("*");
|
||||
|
||||
for (pod::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it)
|
||||
{
|
||||
// Don't overwrite existing settings so command line settings override bitcoin.conf
|
||||
string strKey = string("-") + it->string_key;
|
||||
if (mapSettingsRet.count(strKey) == 0)
|
||||
mapSettingsRet[strKey] = it->value[0];
|
||||
mapMultiSettingsRet[strKey].push_back(it->value[0]);
|
||||
}
|
||||
}
|
||||
|
||||
int GetFilesize(FILE* file)
|
||||
{
|
||||
int nSavePos = ftell(file);
|
||||
@@ -656,9 +690,6 @@ void ShrinkDebugFile()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// "Never go to sea with two chronometers; take one or three."
|
||||
// Our three chronometers are:
|
||||
@@ -701,12 +732,13 @@ void AddTimeData(unsigned int ip, int64 nTime)
|
||||
sort(vTimeOffsets.begin(), vTimeOffsets.end());
|
||||
int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2];
|
||||
nTimeOffset = nMedian;
|
||||
if ((nMedian > 0 ? nMedian : -nMedian) > 5 * 60)
|
||||
if ((nMedian > 0 ? nMedian : -nMedian) > 70 * 60)
|
||||
{
|
||||
// Only let other nodes change our clock so far before we
|
||||
// go to the NTP servers
|
||||
/// todo: Get time from NTP servers, then set a flag
|
||||
/// to make sure it doesn't get changed again
|
||||
nTimeOffset = 0;
|
||||
}
|
||||
foreach(int64 n, vTimeOffsets)
|
||||
printf("%+"PRI64d" ", n);
|
||||
|
||||
11
util.h
11
util.h
@@ -141,6 +141,8 @@ void ParseParameters(int argc, char* argv[]);
|
||||
const char* wxGetTranslation(const char* psz);
|
||||
int GetFilesize(FILE* file);
|
||||
void GetDataDir(char* pszDirRet);
|
||||
string GetConfigFile();
|
||||
void ReadConfigFile(map<string, string>& mapSettingsRet, map<string, vector<string> >& mapMultiSettingsRet);
|
||||
#ifdef __WXMSW__
|
||||
string MyGetSpecialFolderPath(int nFolder, bool fCreate);
|
||||
#endif
|
||||
@@ -348,7 +350,14 @@ void skipspaces(T& it)
|
||||
++it;
|
||||
}
|
||||
|
||||
|
||||
inline bool IsSwitchChar(char c)
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
return c == '-' || c == '/';
|
||||
#else
|
||||
return c == '-';
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user