Gavin Andresen's JSON-RPC HTTP authentication,

faster initial block download
-- version 0.3.3
This commit is contained in:
Satoshi Nakamoto 2010-07-26 17:40:05 +00:00 committed by Gavin Andresen
parent fe98cf8dc5
commit 40cd036941
12 changed files with 93 additions and 25 deletions

36
db.cpp
View file

@ -130,7 +130,14 @@ void CDB::Close()
vTxn.front()->abort(); vTxn.front()->abort();
vTxn.clear(); vTxn.clear();
pdb = NULL; 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) CRITICAL_BLOCK(cs_db)
--mapFileUseCount[strFile]; --mapFileUseCount[strFile];
@ -357,11 +364,12 @@ CBlockIndex* InsertBlockIndex(uint256 hash)
bool CTxDB::LoadBlockIndex() bool CTxDB::LoadBlockIndex()
{ {
// Get cursor // Get database cursor
Dbc* pcursor = GetCursor(); Dbc* pcursor = GetCursor();
if (!pcursor) if (!pcursor)
return false; return false;
// Load mapBlockIndex
unsigned int fFlags = DB_SET_RANGE; unsigned int fFlags = DB_SET_RANGE;
loop loop
{ {
@ -398,7 +406,7 @@ bool CTxDB::LoadBlockIndex()
pindexNew->nBits = diskindex.nBits; pindexNew->nBits = diskindex.nBits;
pindexNew->nNonce = diskindex.nNonce; pindexNew->nNonce = diskindex.nNonce;
// Watch for genesis block and best block // Watch for genesis block
if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock) if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock)
pindexGenesisBlock = pindexNew; pindexGenesisBlock = pindexNew;
} }
@ -409,17 +417,33 @@ bool CTxDB::LoadBlockIndex()
} }
pcursor->close(); 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 (!ReadHashBestChain(hashBestChain))
{ {
if (pindexGenesisBlock == NULL) if (pindexGenesisBlock == NULL)
return true; return true;
return error("CTxDB::LoadBlockIndex() : hashBestChain not found"); return error("CTxDB::LoadBlockIndex() : hashBestChain not loaded");
} }
if (!mapBlockIndex.count(hashBestChain)) 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]; pindexBest = mapBlockIndex[hashBestChain];
nBestHeight = pindexBest->nHeight; nBestHeight = pindexBest->nHeight;
bnBestChainWork = pindexBest->bnChainWork;
printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight); printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight);
return true; return true;

4
db.h
View file

@ -16,7 +16,7 @@ extern map<string, string> mapAddressBook;
extern CCriticalSection cs_mapAddressBook; extern CCriticalSection cs_mapAddressBook;
extern vector<unsigned char> vchDefaultKey; extern vector<unsigned char> vchDefaultKey;
extern bool fClient; extern bool fClient;
extern int nBestHeight;
extern unsigned int nWalletDBUpdated; extern unsigned int nWalletDBUpdated;
@ -210,7 +210,7 @@ public:
if (!pdb) if (!pdb)
return false; return false;
DbTxn* ptxn = NULL; 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) if (!ptxn || ret != 0)
return false; return false;
vTxn.push_back(ptxn); vTxn.push_back(ptxn);

View file

@ -24,6 +24,7 @@ map<uint256, CBlockIndex*> mapBlockIndex;
const uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"); const uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
CBlockIndex* pindexGenesisBlock = NULL; CBlockIndex* pindexGenesisBlock = NULL;
int nBestHeight = -1; int nBestHeight = -1;
CBigNum bnBestChainWork = 0;
uint256 hashBestChain = 0; uint256 hashBestChain = 0;
CBlockIndex* pindexBest = NULL; CBlockIndex* pindexBest = NULL;
int64 nTimeBestReceived = 0; int64 nTimeBestReceived = 0;
@ -848,6 +849,23 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast)
return bnNew.GetCompact(); 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->pprev = (*miPrev).second;
pindexNew->nHeight = pindexNew->pprev->nHeight + 1; pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
} }
pindexNew->bnChainWork = (pindexNew->pprev ? pindexNew->pprev->bnChainWork : 0) + pindexNew->GetBlockWork();
CTxDB txdb; CTxDB txdb;
txdb.TxnBegin(); txdb.TxnBegin();
txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew)); txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew));
// New best // New best
if (pindexNew->nHeight > nBestHeight) if (pindexNew->bnChainWork > bnBestChainWork)
{ {
if (pindexGenesisBlock == NULL && hash == hashGenesisBlock) if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
{ {
@ -1253,6 +1272,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
hashBestChain = hash; hashBestChain = hash;
pindexBest = pindexNew; pindexBest = pindexNew;
nBestHeight = pindexBest->nHeight; nBestHeight = pindexBest->nHeight;
bnBestChainWork = pindexNew->bnChainWork;
nTimeBestReceived = GetTime(); nTimeBestReceived = GetTime();
nTransactionsUpdated++; nTransactionsUpdated++;
printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight); printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight);
@ -1900,6 +1920,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
} }
AddTimeData(pfrom->addr.ip, nTime); AddTimeData(pfrom->addr.ip, nTime);
AddStartingHeight(pfrom->nStartingHeight);
// Change version // Change version
if (pfrom->nVersion >= 209) if (pfrom->nVersion >= 209)
@ -2845,6 +2866,10 @@ int64 GetBalance()
} }
int GetRandInt(int nMax)
{
return GetRand(nMax);
}
bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet) bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet)
{ {
@ -2858,9 +2883,14 @@ bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet)
CRITICAL_BLOCK(cs_mapWallet) CRITICAL_BLOCK(cs_mapWallet)
{ {
vector<CWalletTx*> vCoins;
vCoins.reserve(mapWallet.size());
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) 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)
{ {
CWalletTx* pcoin = &(*it).second;
if (!pcoin->IsFinal() || pcoin->fSpent) if (!pcoin->IsFinal() || pcoin->fSpent)
continue; continue;
int64 n = pcoin->GetCredit(); int64 n = pcoin->GetCredit();

13
main.h
View file

@ -32,6 +32,7 @@ extern map<uint256, CBlockIndex*> mapBlockIndex;
extern const uint256 hashGenesisBlock; extern const uint256 hashGenesisBlock;
extern CBlockIndex* pindexGenesisBlock; extern CBlockIndex* pindexGenesisBlock;
extern int nBestHeight; extern int nBestHeight;
extern CBigNum bnBestChainWork;
extern uint256 hashBestChain; extern uint256 hashBestChain;
extern CBlockIndex* pindexBest; extern CBlockIndex* pindexBest;
extern unsigned int nTransactionsUpdated; extern unsigned int nTransactionsUpdated;
@ -78,6 +79,7 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx
void GenerateBitcoins(bool fGenerate); void GenerateBitcoins(bool fGenerate);
void ThreadBitcoinMiner(void* parg); void ThreadBitcoinMiner(void* parg);
void BitcoinMiner(); void BitcoinMiner();
bool IsInitialBlockDownload();
@ -986,11 +988,14 @@ public:
// Flush stdio buffers and commit to disk before returning // Flush stdio buffers and commit to disk before returning
fflush(fileout); fflush(fileout);
if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
{
#ifdef __WXMSW__ #ifdef __WXMSW__
_commit(_fileno(fileout)); _commit(_fileno(fileout));
#else #else
fsync(fileno(fileout)); fsync(fileno(fileout));
#endif #endif
}
return true; return true;
} }
@ -1072,6 +1077,7 @@ public:
unsigned int nFile; unsigned int nFile;
unsigned int nBlockPos; unsigned int nBlockPos;
int nHeight; int nHeight;
CBigNum bnChainWork;
// block header // block header
int nVersion; int nVersion;
@ -1089,6 +1095,7 @@ public:
nFile = 0; nFile = 0;
nBlockPos = 0; nBlockPos = 0;
nHeight = 0; nHeight = 0;
bnChainWork = 0;
nVersion = 0; nVersion = 0;
hashMerkleRoot = 0; hashMerkleRoot = 0;
@ -1105,6 +1112,7 @@ public:
nFile = nFileIn; nFile = nFileIn;
nBlockPos = nBlockPosIn; nBlockPos = nBlockPosIn;
nHeight = 0; nHeight = 0;
bnChainWork = 0;
nVersion = block.nVersion; nVersion = block.nVersion;
hashMerkleRoot = block.hashMerkleRoot; hashMerkleRoot = block.hashMerkleRoot;
@ -1118,6 +1126,11 @@ public:
return *phashBlock; return *phashBlock;
} }
CBigNum GetBlockWork() const
{
return (CBigNum(1)<<256) / (CBigNum().SetCompact(nBits)+1);
}
bool IsInMainChain() const bool IsInMainChain() const
{ {
return (pnext || this == pindexBest); return (pnext || this == pindexBest);

View file

@ -39,7 +39,7 @@ void PrintConsole(const char* format, ...)
#if defined(__WXMSW__) && wxUSE_GUI #if defined(__WXMSW__) && wxUSE_GUI
MyMessageBox(buffer, "Bitcoin", wxOK | wxICON_EXCLAMATION); MyMessageBox(buffer, "Bitcoin", wxOK | wxICON_EXCLAMATION);
#else #else
fprintf(stdout, buffer); fprintf(stdout, "%s", buffer);
#endif #endif
} }

View file

@ -19,8 +19,8 @@ class CScript;
class CDataStream; class CDataStream;
class CAutoFile; class CAutoFile;
static const int VERSION = 302; static const int VERSION = 303;
static const char* pszSubVer = ".2"; static const char* pszSubVer = "";

View file

@ -7,7 +7,7 @@ RequestExecutionLevel highest
# General Symbol Definitions # General Symbol Definitions
!define REGKEY "SOFTWARE\$(^Name)" !define REGKEY "SOFTWARE\$(^Name)"
!define VERSION 0.3.2 !define VERSION 0.3.3
!define COMPANY "Bitcoin project" !define COMPANY "Bitcoin project"
!define URL http://www.bitcoin.org/ !define URL http://www.bitcoin.org/
@ -42,12 +42,12 @@ Var StartMenuGroup
!insertmacro MUI_LANGUAGE English !insertmacro MUI_LANGUAGE English
# Installer attributes # Installer attributes
OutFile bitcoin-0.3.2-win32-setup.exe OutFile bitcoin-0.3.3-win32-setup.exe
InstallDir $PROGRAMFILES\Bitcoin InstallDir $PROGRAMFILES\Bitcoin
CRCCheck on CRCCheck on
XPStyle on XPStyle on
ShowInstDetails show ShowInstDetails show
VIProductVersion 0.3.2.0 VIProductVersion 0.3.3.0
VIAddVersionKey ProductName Bitcoin VIAddVersionKey ProductName Bitcoin
VIAddVersionKey ProductVersion "${VERSION}" VIAddVersionKey ProductVersion "${VERSION}"
VIAddVersionKey CompanyName "${COMPANY}" VIAddVersionKey CompanyName "${COMPANY}"

1
ui.cpp
View file

@ -1614,6 +1614,7 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event)
CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) 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 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 // Change (c) into UTF-8 or ANSI copyright symbol
wxString str = m_staticTextMain->GetLabel(); wxString str = m_staticTextMain->GetLabel();

View file

@ -227,7 +227,7 @@ class CAboutDialogBase : public wxDialog
public: public:
wxStaticText* m_staticTextVersion; 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(); ~CAboutDialogBase();
}; };

View file

@ -2866,7 +2866,7 @@
<property name="minimum_size"></property> <property name="minimum_size"></property>
<property name="name">CAboutDialogBase</property> <property name="name">CAboutDialogBase</property>
<property name="pos"></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="style">wxDEFAULT_DIALOG_STYLE</property>
<property name="subclass"></property> <property name="subclass"></property>
<property name="title">About Bitcoin</property> <property name="title">About Bitcoin</property>

View file

@ -732,7 +732,7 @@ void AddTimeData(unsigned int ip, int64 nTime)
sort(vTimeOffsets.begin(), vTimeOffsets.end()); sort(vTimeOffsets.begin(), vTimeOffsets.end());
int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2]; int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2];
nTimeOffset = nMedian; nTimeOffset = nMedian;
if ((nMedian > 0 ? nMedian : -nMedian) > 36 * 60 * 60) if ((nMedian > 0 ? nMedian : -nMedian) > 70 * 60)
{ {
// Only let other nodes change our clock so far before we // Only let other nodes change our clock so far before we
// go to the NTP servers // go to the NTP servers