diff options
Diffstat (limited to 'src/main.cpp')
-rw-r--r-- | src/main.cpp | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/src/main.cpp b/src/main.cpp index 9ed4656b35..f6fce00e6e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1593,6 +1593,14 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJust // verify that the view's current state corresponds to the previous block assert(pindex->pprev == view.GetBestBlock()); + // Special case for the genesis block, skipping connection of its transactions + // (its coinbase is unspendable) + if (GetHash() == hashGenesisBlock) { + view.SetBestBlock(pindex); + pindexGenesisBlock = pindex; + return true; + } + bool fScriptChecks = pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate(); // Do not allow blocks that contain transactions which 'overwrite' older transactions, @@ -1728,21 +1736,6 @@ bool SetBestChain(CBlockIndex* pindexNew) // Only when all have succeeded, we push it to pcoinsTip. CCoinsViewCache view(*pcoinsTip, true); - // special case for attaching the genesis block - // note that no ConnectBlock is called, so its coinbase output is non-spendable - if (pindexGenesisBlock == NULL && pindexNew->GetBlockHash() == hashGenesisBlock) - { - view.SetBestBlock(pindexNew); - if (!view.Flush()) - return false; - pindexGenesisBlock = pindexNew; - pindexBest = pindexNew; - hashBestChain = pindexNew->GetBlockHash(); - nBestHeight = pindexBest->nHeight; - bnBestChainWork = pindexNew->bnChainWork; - return true; - } - // Find the fork (typically, there is none) CBlockIndex* pfork = view.GetBestBlock(); CBlockIndex* plonger = pindexNew; @@ -3245,6 +3238,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (fDebugNet || (vInv.size() != 1)) printf("received getdata (%"PRIszu" invsz)\n", vInv.size()); + vector<CInv> vNotFound; BOOST_FOREACH(const CInv& inv, vInv) { if (fShutdown) @@ -3268,6 +3262,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (pfrom->pfilter) { CMerkleBlock merkleBlock(block, *pfrom->pfilter); + pfrom->PushMessage("merkleblock", merkleBlock); // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see // This avoids hurting performance by pointlessly requiring a round-trip // Note that there is currently no way for a node to request any single transactions we didnt send here - @@ -3278,7 +3273,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn) if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second))) pfrom->PushMessage("tx", block.vtx[pair.first]); - pfrom->PushMessage("merkleblock", merkleBlock); } // else // no response @@ -3317,12 +3311,27 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) ss.reserve(1000); ss << tx; pfrom->PushMessage("tx", ss); + pushed = true; } } + if (!pushed) { + vNotFound.push_back(inv); + } } - // Track requests for our stuff + // Track requests for our stuff. Inventory(inv.hash); + + if (!vNotFound.empty()) { + // Let the peer know that we didn't find what it asked for, so it doesn't + // have to wait around forever. Currently only SPV clients actually care + // about this message: it's needed when they are recursively walking the + // dependencies of relevant unconfirmed transactions. SPV clients want to + // do that because they want to know about (and store and rebroadcast and + // risk analyze) the dependencies of transactions relevant to them, without + // having to download the entire memory pool. + pfrom->PushMessage("notfound", vNotFound); + } } } @@ -3587,7 +3596,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Nodes must NEVER send a data item > 520 bytes (the max size for a script data object, // and thus, the maximum size any matched object can have) in a filteradd message - if (vData.size() > 520) + if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE) { pfrom->Misbehaving(100); } else { |