mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-11 14:38:29 +01:00
Headers-first synchronization
Many changes: * Do not use 'getblocks', but 'getheaders', and use it to build a headers tree. * Blocks are fetched in parallel from all available outbound peers, using a limited moving window. When one peer stalls the movement of the window, it is disconnected. * No more orphan blocks. At all. We only ever request a block for which we have verified the headers, and store it to disk immediately. This means that a disk-fill attack would require PoW. * Require protocol version 31800 for every peer (released in december 2010). * No more syncnode (we sync from everyone we can, though limited to 1 during initial *headers* sync). * Introduce some extra named constants, comments and asserts.
This commit is contained in:
50
src/net.cpp
50
src/net.cpp
@@ -73,7 +73,6 @@ map<CNetAddr, LocalServiceInfo> mapLocalHost;
|
||||
static bool vfReachable[NET_MAX] = {};
|
||||
static bool vfLimited[NET_MAX] = {};
|
||||
static CNode* pnodeLocalHost = NULL;
|
||||
static CNode* pnodeSync = NULL;
|
||||
uint64_t nLocalHostNonce = 0;
|
||||
static std::vector<ListenSocket> vhListenSocket;
|
||||
CAddrMan addrman;
|
||||
@@ -519,10 +518,6 @@ void CNode::CloseSocketDisconnect()
|
||||
TRY_LOCK(cs_vRecvMsg, lockRecv);
|
||||
if (lockRecv)
|
||||
vRecvMsg.clear();
|
||||
|
||||
// if this was the sync node, we'll need a new one
|
||||
if (this == pnodeSync)
|
||||
pnodeSync = NULL;
|
||||
}
|
||||
|
||||
void CNode::PushVersion()
|
||||
@@ -615,7 +610,6 @@ void CNode::copyStats(CNodeStats &stats)
|
||||
X(nSendBytes);
|
||||
X(nRecvBytes);
|
||||
X(fWhitelisted);
|
||||
stats.fSyncNode = (this == pnodeSync);
|
||||
|
||||
// It is common for nodes with good ping times to suddenly become lagged,
|
||||
// due to a new block arriving or other large transfer.
|
||||
@@ -1487,61 +1481,20 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu
|
||||
}
|
||||
|
||||
|
||||
// for now, use a very simple selection metric: the node from which we received
|
||||
// most recently
|
||||
static int64_t NodeSyncScore(const CNode *pnode) {
|
||||
return pnode->nLastRecv;
|
||||
}
|
||||
|
||||
void static StartSync(const vector<CNode*> &vNodes) {
|
||||
CNode *pnodeNewSync = NULL;
|
||||
int64_t nBestScore = 0;
|
||||
|
||||
int nBestHeight = g_signals.GetHeight().get_value_or(0);
|
||||
|
||||
// Iterate over all nodes
|
||||
BOOST_FOREACH(CNode* pnode, vNodes) {
|
||||
// check preconditions for allowing a sync
|
||||
if (!pnode->fClient && !pnode->fOneShot &&
|
||||
!pnode->fDisconnect && pnode->fSuccessfullyConnected &&
|
||||
(pnode->nStartingHeight > (nBestHeight - 144)) &&
|
||||
(pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) {
|
||||
// if ok, compare node's score with the best so far
|
||||
int64_t nScore = NodeSyncScore(pnode);
|
||||
if (pnodeNewSync == NULL || nScore > nBestScore) {
|
||||
pnodeNewSync = pnode;
|
||||
nBestScore = nScore;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if a new sync candidate was found, start sync!
|
||||
if (pnodeNewSync) {
|
||||
pnodeNewSync->fStartSync = true;
|
||||
pnodeSync = pnodeNewSync;
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadMessageHandler()
|
||||
{
|
||||
SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
|
||||
while (true)
|
||||
{
|
||||
bool fHaveSyncNode = false;
|
||||
|
||||
vector<CNode*> vNodesCopy;
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
vNodesCopy = vNodes;
|
||||
BOOST_FOREACH(CNode* pnode, vNodesCopy) {
|
||||
pnode->AddRef();
|
||||
if (pnode == pnodeSync)
|
||||
fHaveSyncNode = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fHaveSyncNode)
|
||||
StartSync(vNodesCopy);
|
||||
|
||||
// Poll the connected nodes for messages
|
||||
CNode* pnodeTrickle = NULL;
|
||||
if (!vNodesCopy.empty())
|
||||
@@ -2078,10 +2031,7 @@ CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fIn
|
||||
nSendSize = 0;
|
||||
nSendOffset = 0;
|
||||
hashContinue = 0;
|
||||
pindexLastGetBlocksBegin = 0;
|
||||
hashLastGetBlocksEnd = 0;
|
||||
nStartingHeight = -1;
|
||||
fStartSync = false;
|
||||
fGetAddr = false;
|
||||
fRelayTxes = false;
|
||||
setInventoryKnown.max_size(SendBufferSize() / 1000);
|
||||
|
||||
Reference in New Issue
Block a user