@@ -61,6 +61,14 @@ static std::vector<std::pair<uint256, CTransactionRef>> vExtraTxnForCompact GUAR
6161
6262static const uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL ; // SHA256("main address relay")[0:8]
6363
64+ // / Age after which a stale block will no longer be served if requested as
65+ // / protection against fingerprinting. Set to one month, denominated in seconds.
66+ static const int STALE_RELAY_AGE_LIMIT = 30 * 24 * 60 * 60 ;
67+
68+ // / Age after which a block is considered historical for purposes of rate
69+ // / limiting block relay. Set to one week, denominated in seconds.
70+ static const int HISTORICAL_BLOCK_AGE = 7 * 24 * 60 * 60 ;
71+
6472// Internal stuff
6573namespace {
6674 /* * Number of nodes with fSyncStarted. */
@@ -706,6 +714,17 @@ void Misbehaving(NodeId pnode, int howmuch)
706714// blockchain -> download logic notification
707715//
708716
717+ // To prevent fingerprinting attacks, only send blocks/headers outside of the
718+ // active chain if they are no more than a month older (both in time, and in
719+ // best equivalent proof of work) than the best header chain we know about.
720+ static bool StaleBlockRequestAllowed (const CBlockIndex* pindex, const Consensus::Params& consensusParams)
721+ {
722+ AssertLockHeld (cs_main);
723+ return (pindexBestHeader != nullptr ) &&
724+ (pindexBestHeader->GetBlockTime () - pindex->GetBlockTime () < STALE_RELAY_AGE_LIMIT) &&
725+ (GetBlockProofEquivalentTime (*pindexBestHeader, *pindex, *pindexBestHeader, consensusParams) < STALE_RELAY_AGE_LIMIT);
726+ }
727+
709728PeerLogicValidation::PeerLogicValidation (CConnman* connmanIn) : connman(connmanIn) {
710729 // Initialize global variables that cannot be constructed at startup.
711730 recentRejects.reset (new CRollingBloomFilter (120000 , 0.000001 ));
@@ -983,22 +1002,16 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
9831002 if (chainActive.Contains (mi->second )) {
9841003 send = true ;
9851004 } else {
986- static const int nOneMonth = 30 * 24 * 60 * 60 ;
987- // To prevent fingerprinting attacks, only send blocks outside of the active
988- // chain if they are valid, and no more than a month older (both in time, and in
989- // best equivalent proof of work) than the best header chain we know about.
990- send = mi->second ->IsValid (BLOCK_VALID_SCRIPTS) && (pindexBestHeader != nullptr ) &&
991- (pindexBestHeader->GetBlockTime () - mi->second ->GetBlockTime () < nOneMonth) &&
992- (GetBlockProofEquivalentTime (*pindexBestHeader, *mi->second , *pindexBestHeader, consensusParams) < nOneMonth);
1005+ send = mi->second ->IsValid (BLOCK_VALID_SCRIPTS) &&
1006+ StaleBlockRequestAllowed (mi->second , consensusParams);
9931007 if (!send) {
9941008 LogPrintf (" %s: ignoring request from peer=%i for old block that isn't in the main chain\n " , __func__, pfrom->GetId ());
9951009 }
9961010 }
9971011 }
9981012 // disconnect node in case we have reached the outbound limit for serving historical blocks
9991013 // never disconnect whitelisted nodes
1000- static const int nOneWeek = 7 * 24 * 60 * 60 ; // assume > 1 week = historical
1001- if (send && connman->OutboundTargetReached (true ) && ( ((pindexBestHeader != nullptr ) && (pindexBestHeader->GetBlockTime () - mi->second ->GetBlockTime () > nOneWeek)) || inv.type == MSG_FILTERED_BLOCK) && !pfrom->fWhitelisted )
1014+ if (send && connman->OutboundTargetReached (true ) && ( ((pindexBestHeader != nullptr ) && (pindexBestHeader->GetBlockTime () - mi->second ->GetBlockTime () > HISTORICAL_BLOCK_AGE)) || inv.type == MSG_FILTERED_BLOCK) && !pfrom->fWhitelisted )
10021015 {
10031016 LogPrint (BCLog::NET, " historical block serving limit reached, disconnect peer=%d\n " , pfrom->GetId ());
10041017
@@ -1723,6 +1736,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
17231736 if (mi == mapBlockIndex.end ())
17241737 return true ;
17251738 pindex = (*mi).second ;
1739+
1740+ if (!chainActive.Contains (pindex) &&
1741+ !StaleBlockRequestAllowed (pindex, chainparams.GetConsensus ())) {
1742+ LogPrintf (" %s: ignoring request from peer=%i for old block header that isn't in the main chain\n " , __func__, pfrom->GetId ());
1743+ return true ;
1744+ }
17261745 }
17271746 else
17281747 {
0 commit comments