| 1106 | } |
| 1107 | |
| 1108 | void static ProcessGetBlockData(CNode* pfrom, const CChainParams& chainparams, const CInv& inv, CConnman* connman) |
| 1109 | { |
| 1110 | bool send = false; |
| 1111 | std::shared_ptr<const CBlock> a_recent_block; |
| 1112 | std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block; |
| 1113 | bool fWitnessesPresentInARecentCompactBlock; |
| 1114 | const Consensus::Params& consensusParams = chainparams.GetConsensus(); |
| 1115 | { |
| 1116 | LOCK(cs_most_recent_block); |
| 1117 | a_recent_block = most_recent_block; |
| 1118 | a_recent_compact_block = most_recent_compact_block; |
| 1119 | fWitnessesPresentInARecentCompactBlock = fWitnessesPresentInMostRecentCompactBlock; |
| 1120 | } |
| 1121 | |
| 1122 | bool need_activate_chain = false; |
| 1123 | { |
| 1124 | LOCK(cs_main); |
| 1125 | const CBlockIndex* pindex = LookupBlockIndex(inv.hash); |
| 1126 | if (pindex) { |
| 1127 | if (pindex->nChainTx && !pindex->IsValid(BLOCK_VALID_SCRIPTS) && |
| 1128 | pindex->IsValid(BLOCK_VALID_TREE)) { |
| 1129 | // If we have the block and all of its parents, but have not yet validated it, |
| 1130 | // we might be in the middle of connecting it (ie in the unlock of cs_main |
| 1131 | // before ActivateBestChain but after AcceptBlock). |
| 1132 | // In this case, we need to run ActivateBestChain prior to checking the relay |
| 1133 | // conditions below. |
| 1134 | need_activate_chain = true; |
| 1135 | } |
| 1136 | } |
| 1137 | } // release cs_main before calling ActivateBestChain |
| 1138 | if (need_activate_chain) { |
| 1139 | CValidationState state; |
| 1140 | if (!ActivateBestChain(state, Params(), a_recent_block)) { |
| 1141 | LogPrint(BCLog::NET, "failed to activate chain (%s)\n", FormatStateMessage(state)); |
| 1142 | } |
| 1143 | } |
| 1144 | |
| 1145 | LOCK(cs_main); |
| 1146 | const CBlockIndex* pindex = LookupBlockIndex(inv.hash); |
| 1147 | if (pindex) { |
| 1148 | send = BlockRequestAllowed(pindex, consensusParams); |
| 1149 | if (!send) { |
| 1150 | LogPrint(BCLog::NET, "%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId()); |
| 1151 | } |
| 1152 | } |
| 1153 | const CNetMsgMaker msgMaker(pfrom->GetSendVersion()); |
| 1154 | // disconnect node in case we have reached the outbound limit for serving historical blocks |
| 1155 | // never disconnect whitelisted nodes |
| 1156 | if (send && connman->OutboundTargetReached(true) && ( ((pindexBestHeader != nullptr) && (pindexBestHeader->GetBlockTime() - pindex->GetBlockTime() > HISTORICAL_BLOCK_AGE)) || inv.type == MSG_FILTERED_BLOCK) && !pfrom->fWhitelisted) |
| 1157 | { |
| 1158 | LogPrint(BCLog::NET, "historical block serving limit reached, disconnect peer=%d\n", pfrom->GetId()); |
| 1159 | |
| 1160 | //disconnect node |
| 1161 | pfrom->fDisconnect = true; |
| 1162 | send = false; |
| 1163 | } |
| 1164 | // Avoid leaking prune-height by never sending blocks below the NODE_NETWORK_LIMITED threshold |
| 1165 | if (send && !pfrom->fWhitelisted && ( |
no test coverage detected