aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authors_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>2010-12-05 09:29:30 +0000
committers_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>2010-12-05 09:29:30 +0000
commitf03304a9c79a6cc6096ed501ad38702fd012e7f7 (patch)
treeb336b15afca6035f7c09021e12179078ae6900c4
parentbdde31d787c4fe2da8e9fb168abbd22af2c27442 (diff)
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
-rw-r--r--db.cpp2
-rw-r--r--db.h2
-rw-r--r--irc.cpp76
-rw-r--r--main.cpp75
-rw-r--r--main.h37
-rw-r--r--serialize.h2
6 files changed, 165 insertions, 29 deletions
diff --git a/db.cpp b/db.cpp
index 40998fb740..fb4e48c596 100644
--- a/db.cpp
+++ b/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)
diff --git a/db.h b/db.h
index e3ffc40c65..72fe0d9fac 100644
--- a/db.h
+++ b/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&);
diff --git a/irc.cpp b/irc.cpp
index 55b23f2dec..1734d76fa1 100644
--- a/irc.cpp
+++ b/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");
diff --git a/main.cpp b/main.cpp
index f4131395fc..be29ceb971 100644
--- a/main.cpp
+++ b/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);
}
diff --git a/main.h b/main.h
index 2c24eba2d5..cca233896e 100644
--- a/main.h
+++ b/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();
diff --git a/serialize.h b/serialize.h
index 5088e37007..7f47d0fcbb 100644
--- a/serialize.h
+++ b/serialize.h
@@ -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 = "";