* Maintain state about the best-seen block and fast-announce a compact block * to compatible peers. */
| 2130 | * to compatible peers. |
| 2131 | */ |
| 2132 | void PeerManagerImpl::NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr<const CBlock>& pblock) |
| 2133 | { |
| 2134 | auto pcmpctblock = std::make_shared<const CBlockHeaderAndShortTxIDs>(*pblock, FastRandomContext().rand64()); |
| 2135 | |
| 2136 | LOCK(cs_main); |
| 2137 | |
| 2138 | if (pindex->nHeight <= m_highest_fast_announce) |
| 2139 | return; |
| 2140 | m_highest_fast_announce = pindex->nHeight; |
| 2141 | |
| 2142 | if (!DeploymentActiveAt(*pindex, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) return; |
| 2143 | |
| 2144 | uint256 hashBlock(pblock->GetHash()); |
| 2145 | const std::shared_future<CSerializedNetMsg> lazy_ser{ |
| 2146 | std::async(std::launch::deferred, [&] { return NetMsg::Make(NetMsgType::CMPCTBLOCK, *pcmpctblock); })}; |
| 2147 | |
| 2148 | { |
| 2149 | auto most_recent_block_txs = std::make_unique<std::map<GenTxid, CTransactionRef>>(); |
| 2150 | for (const auto& tx : pblock->vtx) { |
| 2151 | most_recent_block_txs->emplace(tx->GetHash(), tx); |
| 2152 | most_recent_block_txs->emplace(tx->GetWitnessHash(), tx); |
| 2153 | } |
| 2154 | |
| 2155 | LOCK(m_most_recent_block_mutex); |
| 2156 | m_most_recent_block_hash = hashBlock; |
| 2157 | m_most_recent_block = pblock; |
| 2158 | m_most_recent_compact_block = pcmpctblock; |
| 2159 | m_most_recent_block_txs = std::move(most_recent_block_txs); |
| 2160 | } |
| 2161 | |
| 2162 | m_connman.ForEachNode([this, pindex, &lazy_ser, &hashBlock](CNode* pnode) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { |
| 2163 | AssertLockHeld(::cs_main); |
| 2164 | |
| 2165 | if (pnode->GetCommonVersion() < INVALID_CB_NO_BAN_VERSION || pnode->fDisconnect) |
| 2166 | return; |
| 2167 | ProcessBlockAvailability(pnode->GetId()); |
| 2168 | CNodeState &state = *State(pnode->GetId()); |
| 2169 | // If the peer has, or we announced to them the previous block already, |
| 2170 | // but we don't think they have this one, go ahead and announce it |
| 2171 | if (state.m_requested_hb_cmpctblocks && !PeerHasHeader(&state, pindex) && PeerHasHeader(&state, pindex->pprev)) { |
| 2172 | |
| 2173 | LogDebug(BCLog::NET, "%s sending header-and-ids %s to peer=%d\n", "PeerManager::NewPoWValidBlock", |
| 2174 | hashBlock.ToString(), pnode->GetId()); |
| 2175 | |
| 2176 | const CSerializedNetMsg& ser_cmpctblock{lazy_ser.get()}; |
| 2177 | PushMessage(*pnode, ser_cmpctblock.Copy()); |
| 2178 | state.pindexBestHeaderSent = pindex; |
| 2179 | } |
| 2180 | }); |
| 2181 | } |
| 2182 | |
| 2183 | /** |
| 2184 | * Update our best height and announce any block hashes which weren't previously |
no test coverage detected