preps for future client-only mode,
jgarzik's initial download speedup git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@195 1a98c847-1fd6-4fd8-948a-caf3550aa51b
This commit is contained in:
parent
bdde31d787
commit
f03304a9c7
6 changed files with 165 additions and 29 deletions
2
db.cpp
2
db.cpp
|
@ -132,6 +132,8 @@ void CDB::Close()
|
|||
|
||||
// Flush database activity from memory pool to disk log
|
||||
unsigned int nMinutes = 0;
|
||||
if (fReadOnly)
|
||||
nMinutes = 1;
|
||||
if (strFile == "addr.dat")
|
||||
nMinutes = 2;
|
||||
if (strFile == "blkindex.dat" && IsInitialBlockDownload() && nBestHeight % 500 != 0)
|
||||
|
|
2
db.h
2
db.h
|
@ -265,7 +265,7 @@ public:
|
|||
class CTxDB : public CDB
|
||||
{
|
||||
public:
|
||||
CTxDB(const char* pszMode="r+") : CDB(!fClient ? "blkindex.dat" : NULL, pszMode) { }
|
||||
CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { }
|
||||
private:
|
||||
CTxDB(const CTxDB&);
|
||||
void operator=(const CTxDB&);
|
||||
|
|
76
irc.cpp
76
irc.cpp
|
@ -173,6 +173,68 @@ bool Wait(int nSeconds)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool RecvCodeLine(SOCKET hSocket, const char* psz1, string& strRet)
|
||||
{
|
||||
strRet.clear();
|
||||
loop
|
||||
{
|
||||
string strLine;
|
||||
if (!RecvLineIRC(hSocket, strLine))
|
||||
return false;
|
||||
|
||||
vector<string> vWords;
|
||||
ParseString(strLine, ' ', vWords);
|
||||
if (vWords.size() < 2)
|
||||
continue;
|
||||
|
||||
if (vWords[1] == psz1)
|
||||
{
|
||||
printf("IRC %s\n", strLine.c_str());
|
||||
strRet = strLine;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GetIPFromIRC(SOCKET hSocket, string strMyName, unsigned int& ipRet)
|
||||
{
|
||||
Send(hSocket, strprintf("USERHOST %s\r", strMyName.c_str()).c_str());
|
||||
|
||||
string strLine;
|
||||
if (!RecvCodeLine(hSocket, "302", strLine))
|
||||
return false;
|
||||
|
||||
vector<string> vWords;
|
||||
ParseString(strLine, ' ', vWords);
|
||||
if (vWords.size() < 4)
|
||||
return false;
|
||||
|
||||
string str = vWords[3];
|
||||
if (str.rfind("@") == string::npos)
|
||||
return false;
|
||||
string strHost = str.substr(str.rfind("@")+1);
|
||||
|
||||
unsigned int a=0, b=0, c=0, d=0;
|
||||
if (sscanf(strHost.c_str(), "%u.%u.%u.%u", &a, &b, &c, &d) == 4 &&
|
||||
inet_addr(strHost.c_str()) != INADDR_NONE)
|
||||
{
|
||||
printf("GetIPFromIRC() userhost is IP %s\n", strHost.c_str());
|
||||
ipRet = CAddress(strHost).ip;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("GetIPFromIRC() got userhost %s\n", strHost.c_str());
|
||||
if (fUseProxy)
|
||||
return false;
|
||||
struct hostent* phostent = gethostbyname(strHost.c_str());
|
||||
if (!phostent || !phostent->h_addr_list || !phostent->h_addr_list[0])
|
||||
return false;
|
||||
ipRet = *(u_long*)phostent->h_addr_list[0];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ThreadIRCSeed(void* parg)
|
||||
|
@ -265,6 +327,20 @@ void ThreadIRCSeed2(void* parg)
|
|||
}
|
||||
Sleep(500);
|
||||
|
||||
// Get my external IP from IRC server
|
||||
CAddress addrFromIRC;
|
||||
if (GetIPFromIRC(hSocket, strMyName, addrFromIRC.ip))
|
||||
{
|
||||
// Just using it as a backup for now
|
||||
printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToStringIP().c_str());
|
||||
if (addrFromIRC.IsRoutable() && !fUseProxy && !addrLocalHost.IsRoutable())
|
||||
{
|
||||
addrLocalHost.ip = addrFromIRC.ip;
|
||||
strMyName = EncodeAddress(addrLocalHost);
|
||||
Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
Send(hSocket, fTestNet ? "JOIN #bitcoinTEST\r" : "JOIN #bitcoin\r");
|
||||
Send(hSocket, fTestNet ? "WHO #bitcoinTEST\r" : "WHO #bitcoin\r");
|
||||
|
||||
|
|
75
main.cpp
75
main.cpp
|
@ -870,6 +870,11 @@ void ResendWalletTransactions()
|
|||
|
||||
bool CBlock::ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions)
|
||||
{
|
||||
if (!fReadTransactions)
|
||||
{
|
||||
*this = pindex->GetBlockHeader();
|
||||
return true;
|
||||
}
|
||||
if (!ReadFromDisk(pindex->nFile, pindex->nBlockPos, fReadTransactions))
|
||||
return false;
|
||||
if (GetHash() != pindex->GetBlockHash())
|
||||
|
@ -1425,7 +1430,10 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
|
|||
pindexNew->bnChainWork = (pindexNew->pprev ? pindexNew->pprev->bnChainWork : 0) + pindexNew->GetBlockWork();
|
||||
|
||||
CTxDB txdb;
|
||||
txdb.TxnBegin();
|
||||
txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew));
|
||||
if (!txdb.TxnCommit())
|
||||
return false;
|
||||
|
||||
// New best
|
||||
if (pindexNew->bnChainWork > bnBestChainWork)
|
||||
|
@ -1529,9 +1537,9 @@ bool CBlock::AcceptBlock()
|
|||
// Write block to history file
|
||||
if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK)))
|
||||
return error("AcceptBlock() : out of disk space");
|
||||
unsigned int nFile;
|
||||
unsigned int nBlockPos;
|
||||
if (!WriteToDisk(!fClient, nFile, nBlockPos))
|
||||
unsigned int nFile = -1;
|
||||
unsigned int nBlockPos = 0;
|
||||
if (!WriteToDisk(nFile, nBlockPos))
|
||||
return error("AcceptBlock() : WriteToDisk failed");
|
||||
if (!AddToBlockIndex(nFile, nBlockPos))
|
||||
return error("AcceptBlock() : AddToBlockIndex failed");
|
||||
|
@ -1777,7 +1785,7 @@ bool LoadBlockIndex(bool fAllowNew)
|
|||
// Start new block file
|
||||
unsigned int nFile;
|
||||
unsigned int nBlockPos;
|
||||
if (!block.WriteToDisk(!fClient, nFile, nBlockPos))
|
||||
if (!block.WriteToDisk(nFile, nBlockPos))
|
||||
return error("LoadBlockIndex() : writing genesis block to disk failed");
|
||||
if (!block.AddToBlockIndex(nFile, nBlockPos))
|
||||
return error("LoadBlockIndex() : genesis block not accepted");
|
||||
|
@ -2181,11 +2189,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||
}
|
||||
|
||||
pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
|
||||
if (pfrom->fClient)
|
||||
{
|
||||
pfrom->vSend.nType |= SER_BLOCKHEADERONLY;
|
||||
pfrom->vRecv.nType |= SER_BLOCKHEADERONLY;
|
||||
}
|
||||
|
||||
AddTimeData(pfrom->addr.ip, nTime);
|
||||
|
||||
|
@ -2359,9 +2362,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash);
|
||||
if (mi != mapBlockIndex.end())
|
||||
{
|
||||
//// could optimize this to send header straight from blockindex for client
|
||||
CBlock block;
|
||||
block.ReadFromDisk((*mi).second, !pfrom->fClient);
|
||||
block.ReadFromDisk((*mi).second);
|
||||
pfrom->PushMessage("block", block);
|
||||
|
||||
// Trigger them to send a getblocks request for the next batch of inventory
|
||||
|
@ -2405,7 +2407,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||
uint256 hashStop;
|
||||
vRecv >> locator >> hashStop;
|
||||
|
||||
// Find the first block the caller has in the main chain
|
||||
// Find the last block the caller has in the main chain
|
||||
CBlockIndex* pindex = locator.GetBlockIndex();
|
||||
|
||||
// Send the rest of the chain
|
||||
|
@ -2433,6 +2435,42 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||
}
|
||||
|
||||
|
||||
else if (strCommand == "getheaders")
|
||||
{
|
||||
CBlockLocator locator;
|
||||
uint256 hashStop;
|
||||
vRecv >> locator >> hashStop;
|
||||
|
||||
CBlockIndex* pindex = NULL;
|
||||
if (locator.IsNull())
|
||||
{
|
||||
// If locator is null, return the hashStop block
|
||||
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashStop);
|
||||
if (mi == mapBlockIndex.end())
|
||||
return true;
|
||||
pindex = (*mi).second;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find the last block the caller has in the main chain
|
||||
pindex = locator.GetBlockIndex();
|
||||
if (pindex)
|
||||
pindex = pindex->pnext;
|
||||
}
|
||||
|
||||
vector<CBlock> vHeaders;
|
||||
int nLimit = 2000 + locator.GetDistanceBack();
|
||||
printf("getheaders %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit);
|
||||
for (; pindex; pindex = pindex->pnext)
|
||||
{
|
||||
vHeaders.push_back(pindex->GetBlockHeader());
|
||||
if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
|
||||
break;
|
||||
}
|
||||
pfrom->PushMessage("headers", vHeaders);
|
||||
}
|
||||
|
||||
|
||||
else if (strCommand == "tx")
|
||||
{
|
||||
vector<uint256> vWorkQueue;
|
||||
|
@ -2488,17 +2526,16 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
|||
|
||||
else if (strCommand == "block")
|
||||
{
|
||||
auto_ptr<CBlock> pblock(new CBlock);
|
||||
vRecv >> *pblock;
|
||||
CBlock block;
|
||||
vRecv >> block;
|
||||
|
||||
//// debug print
|
||||
printf("received block %s\n", pblock->GetHash().ToString().substr(0,20).c_str());
|
||||
// pblock->print();
|
||||
printf("received block %s\n", block.GetHash().ToString().substr(0,20).c_str());
|
||||
// block.print();
|
||||
|
||||
CInv inv(MSG_BLOCK, pblock->GetHash());
|
||||
CInv inv(MSG_BLOCK, block.GetHash());
|
||||
pfrom->AddInventoryKnown(inv);
|
||||
|
||||
if (ProcessBlock(pfrom, pblock.get()))
|
||||
if (ProcessBlock(pfrom, &block))
|
||||
mapAlreadyAskedFor.erase(inv);
|
||||
}
|
||||
|
||||
|
|
37
main.h
37
main.h
|
@ -865,11 +865,6 @@ public:
|
|||
return nChangeCached;
|
||||
}
|
||||
|
||||
bool IsFromMe() const
|
||||
{
|
||||
return (GetDebit() > 0);
|
||||
}
|
||||
|
||||
void GetAccountAmounts(string strAccount, const set<CScript>& setPubKey,
|
||||
int64& nGenerated, int64& nReceived, int64& nSent, int64& nFee) const
|
||||
{
|
||||
|
@ -901,6 +896,11 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
bool IsFromMe() const
|
||||
{
|
||||
return (GetDebit() > 0);
|
||||
}
|
||||
|
||||
bool IsConfirmed() const
|
||||
{
|
||||
// Quick answer in most cases
|
||||
|
@ -1158,14 +1158,12 @@ public:
|
|||
}
|
||||
|
||||
|
||||
bool WriteToDisk(bool fWriteTransactions, unsigned int& nFileRet, unsigned int& nBlockPosRet)
|
||||
bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
|
||||
{
|
||||
// Open history file to append
|
||||
CAutoFile fileout = AppendBlockFile(nFileRet);
|
||||
if (!fileout)
|
||||
return error("CBlock::WriteToDisk() : AppendBlockFile failed");
|
||||
if (!fWriteTransactions)
|
||||
fileout.nType |= SER_BLOCKHEADERONLY;
|
||||
|
||||
// Write index header
|
||||
unsigned int nSize = fileout.GetSerializeSize(*this);
|
||||
|
@ -1310,6 +1308,19 @@ public:
|
|||
nNonce = block.nNonce;
|
||||
}
|
||||
|
||||
CBlock GetBlockHeader() const
|
||||
{
|
||||
CBlock block;
|
||||
block.nVersion = nVersion;
|
||||
if (pprev)
|
||||
block.hashPrevBlock = pprev->GetBlockHash();
|
||||
block.hashMerkleRoot = hashMerkleRoot;
|
||||
block.nTime = nTime;
|
||||
block.nBits = nBits;
|
||||
block.nNonce = nNonce;
|
||||
return block;
|
||||
}
|
||||
|
||||
uint256 GetBlockHash() const
|
||||
{
|
||||
return *phashBlock;
|
||||
|
@ -1511,6 +1522,16 @@ public:
|
|||
READWRITE(vHave);
|
||||
)
|
||||
|
||||
void SetNull()
|
||||
{
|
||||
vHave.clear();
|
||||
}
|
||||
|
||||
bool IsNull()
|
||||
{
|
||||
return vHave.empty();
|
||||
}
|
||||
|
||||
void Set(const CBlockIndex* pindex)
|
||||
{
|
||||
vHave.clear();
|
||||
|
|
|
@ -25,7 +25,7 @@ class CDataStream;
|
|||
class CAutoFile;
|
||||
static const unsigned int MAX_SIZE = 0x02000000;
|
||||
|
||||
static const int VERSION = 31702;
|
||||
static const int VERSION = 31703;
|
||||
static const char* pszSubVer = "";
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue