@@ -61,6 +61,14 @@ static std::vector<std::pair<uint256, CTransactionRef>> vExtraTxnForCompact GUAR
61
61
62
62
static const uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL ; // SHA256("main address relay")[0:8]
63
63
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
+
64
72
// Internal stuff
65
73
namespace {
66
74
/* * Number of nodes with fSyncStarted. */
@@ -706,6 +714,17 @@ void Misbehaving(NodeId pnode, int howmuch)
706
714
// blockchain -> download logic notification
707
715
//
708
716
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
+
709
728
PeerLogicValidation::PeerLogicValidation (CConnman* connmanIn) : connman(connmanIn) {
710
729
// Initialize global variables that cannot be constructed at startup.
711
730
recentRejects.reset (new CRollingBloomFilter (120000 , 0.000001 ));
@@ -983,22 +1002,16 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
983
1002
if (chainActive.Contains (mi->second )) {
984
1003
send = true ;
985
1004
} 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);
993
1007
if (!send) {
994
1008
LogPrintf (" %s: ignoring request from peer=%i for old block that isn't in the main chain\n " , __func__, pfrom->GetId ());
995
1009
}
996
1010
}
997
1011
}
998
1012
// disconnect node in case we have reached the outbound limit for serving historical blocks
999
1013
// 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 )
1002
1015
{
1003
1016
LogPrint (BCLog::NET, " historical block serving limit reached, disconnect peer=%d\n " , pfrom->GetId ());
1004
1017
@@ -1723,6 +1736,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
1723
1736
if (mi == mapBlockIndex.end ())
1724
1737
return true ;
1725
1738
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
+ }
1726
1745
}
1727
1746
else
1728
1747
{
0 commit comments