@@ -56,8 +56,13 @@ int64_t CTransaction::nMinRelayTxFee = 10000;
56
56
57
57
static CMedianFilter<int > cPeerBlockCounts (8 , 0 ); // Amount of blocks that other nodes claim to have
58
58
59
- map<uint256, CBlock*> mapOrphanBlocks;
60
- multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
59
+ struct COrphanBlock {
60
+ uint256 hashBlock;
61
+ uint256 hashPrev;
62
+ vector<unsigned char > vchBlock;
63
+ };
64
+ map<uint256, COrphanBlock*> mapOrphanBlocks;
65
+ multimap<uint256, COrphanBlock*> mapOrphanBlocksByPrev;
61
66
62
67
map<uint256, CTransaction> mapOrphanTransactions;
63
68
map<uint256, set<uint256> > mapOrphanTransactionsByPrev;
@@ -985,12 +990,19 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex)
985
990
return true ;
986
991
}
987
992
988
- uint256 static GetOrphanRoot (const CBlockHeader* pblock )
993
+ uint256 static GetOrphanRoot (const uint256& hash )
989
994
{
995
+ map<uint256, COrphanBlock*>::iterator it = mapOrphanBlocks.find (hash);
996
+ if (it == mapOrphanBlocks.end ())
997
+ return hash;
998
+
990
999
// Work back to the first block in the orphan chain
991
- while (mapOrphanBlocks.count (pblock->hashPrevBlock ))
992
- pblock = mapOrphanBlocks[pblock->hashPrevBlock ];
993
- return pblock->GetHash ();
1000
+ do {
1001
+ map<uint256, COrphanBlock*>::iterator it2 = mapOrphanBlocks.find (it->second ->hashPrev );
1002
+ if (it2 == mapOrphanBlocks.end ())
1003
+ return it->first ;
1004
+ it = it2;
1005
+ } while (true );
994
1006
}
995
1007
996
1008
int64_t GetBlockValue (int nHeight, int64_t nFees)
@@ -2277,12 +2289,19 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
2277
2289
2278
2290
// Accept orphans as long as there is a node to request its parents from
2279
2291
if (pfrom) {
2280
- CBlock* pblock2 = new CBlock (*pblock);
2292
+ COrphanBlock* pblock2 = new COrphanBlock ();
2293
+ {
2294
+ CDataStream ss (SER_DISK, CLIENT_VERSION);
2295
+ ss << *pblock;
2296
+ pblock2->vchBlock = std::vector<unsigned char >(ss.begin (), ss.end ());
2297
+ }
2298
+ pblock2->hashBlock = hash;
2299
+ pblock2->hashPrev = pblock->hashPrevBlock ;
2281
2300
mapOrphanBlocks.insert (make_pair (hash, pblock2));
2282
- mapOrphanBlocksByPrev.insert (make_pair (pblock2->hashPrevBlock , pblock2));
2301
+ mapOrphanBlocksByPrev.insert (make_pair (pblock2->hashPrev , pblock2));
2283
2302
2284
2303
// Ask this guy to fill in what we're missing
2285
- PushGetBlocks (pfrom, chainActive.Tip (), GetOrphanRoot (pblock2 ));
2304
+ PushGetBlocks (pfrom, chainActive.Tip (), GetOrphanRoot (hash ));
2286
2305
}
2287
2306
return true ;
2288
2307
}
@@ -2297,17 +2316,22 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
2297
2316
for (unsigned int i = 0 ; i < vWorkQueue.size (); i++)
2298
2317
{
2299
2318
uint256 hashPrev = vWorkQueue[i];
2300
- for (multimap<uint256, CBlock *>::iterator mi = mapOrphanBlocksByPrev.lower_bound (hashPrev);
2319
+ for (multimap<uint256, COrphanBlock *>::iterator mi = mapOrphanBlocksByPrev.lower_bound (hashPrev);
2301
2320
mi != mapOrphanBlocksByPrev.upper_bound (hashPrev);
2302
2321
++mi)
2303
2322
{
2304
- CBlock* pblockOrphan = (*mi).second ;
2323
+ CBlock block;
2324
+ {
2325
+ CDataStream ss (mi->second ->vchBlock , SER_DISK, CLIENT_VERSION);
2326
+ ss >> block;
2327
+ }
2328
+ block.BuildMerkleTree ();
2305
2329
// Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan resolution (that is, feeding people an invalid block based on LegitBlockX in order to get anyone relaying LegitBlockX banned)
2306
2330
CValidationState stateDummy;
2307
- if (AcceptBlock (*pblockOrphan , stateDummy))
2308
- vWorkQueue.push_back (pblockOrphan-> GetHash () );
2309
- mapOrphanBlocks.erase (pblockOrphan-> GetHash () );
2310
- delete pblockOrphan ;
2331
+ if (AcceptBlock (block , stateDummy))
2332
+ vWorkQueue.push_back (mi-> second -> hashBlock );
2333
+ mapOrphanBlocks.erase (mi-> second -> hashBlock );
2334
+ delete mi-> second ;
2311
2335
}
2312
2336
mapOrphanBlocksByPrev.erase (hashPrev);
2313
2337
}
@@ -3331,7 +3355,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
3331
3355
if (!fImporting && !fReindex )
3332
3356
pfrom->AskFor (inv);
3333
3357
} else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count (inv.hash )) {
3334
- PushGetBlocks (pfrom, chainActive.Tip (), GetOrphanRoot (mapOrphanBlocks[ inv.hash ] ));
3358
+ PushGetBlocks (pfrom, chainActive.Tip (), GetOrphanRoot (inv.hash ));
3335
3359
} else if (nInv == nLastBlock) {
3336
3360
// In case we are on a very long side-chain, it is possible that we already have
3337
3361
// the last block in an inv bundle sent in response to getblocks. Try to detect
@@ -4119,7 +4143,7 @@ class CMainCleanup
4119
4143
mapBlockIndex.clear ();
4120
4144
4121
4145
// orphan blocks
4122
- std::map<uint256, CBlock *>::iterator it2 = mapOrphanBlocks.begin ();
4146
+ std::map<uint256, COrphanBlock *>::iterator it2 = mapOrphanBlocks.begin ();
4123
4147
for (; it2 != mapOrphanBlocks.end (); it2++)
4124
4148
delete (*it2).second ;
4125
4149
mapOrphanBlocks.clear ();
0 commit comments