aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp45
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 {