| 32 | } |
| 33 | |
| 34 | bool BlockSender::canSend(const CChain& activeChain, const CBlockIndex& block, |
| 35 | CBlockIndex *pindexBestHeader) |
| 36 | { |
| 37 | // Pruned nodes may have deleted the block, so check whether |
| 38 | // it's available before trying to send. |
| 39 | if (!(block.nStatus & BLOCK_HAVE_DATA)) |
| 40 | return false; |
| 41 | |
| 42 | if (activeChain.Contains(&block)) |
| 43 | return true; |
| 44 | |
| 45 | static const int nOneMonth = 30 * 24 * 60 * 60; |
| 46 | // To prevent fingerprinting attacks, only send blocks outside of the active |
| 47 | // chain if they are valid, and no more than a month older (both in time, and in |
| 48 | // best equivalent proof of work) than the best header chain we know about. |
| 49 | bool send = block.IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) && |
| 50 | (pindexBestHeader->GetBlockTime() - block.GetBlockTime() < nOneMonth) && |
| 51 | (GetBlockProofEquivalentTime(*pindexBestHeader, block, *pindexBestHeader, Params().GetConsensus()) < nOneMonth); |
| 52 | if (!send) |
| 53 | LogPrintf("ignoring request for old block that isn't in the main chain\n"); |
| 54 | |
| 55 | return send; |
| 56 | } |
| 57 | |
| 58 | void BlockSender::send(const CChain& activeChain, CNode& node, |
| 59 | CBlockIndex& blockIndex, const CInv& inv) |