/// <exception cref="IOException"/> private void ProcessInv(InventoryMessage inv) { // This should be called in the network loop thread for this peer // The peer told us about some blocks or transactions they have. For now we only care about blocks. // Note that as we don't actually want to store the entire block chain or even the headers of the block // chain, we may end up requesting blocks we already requested before. This shouldn't (in theory) happen // enough to be a problem. var topBlock = _blockChain.UnconnectedBlock; var topHash = topBlock != null ? topBlock.Hash : null; var items = inv.Items; if (items.Count == 1 && items[0].Type == InventoryItem.ItemType.Block && topHash != null && items[0].Hash.Equals(topHash)) { // An inv with a single hash containing our most recent unconnected block is a special inv, // it's kind of like a tickle from the peer telling us that it's time to download more blocks to catch up to // the block chain. We could just ignore this and treat it as a regular inv but then we'd download the head // block over and over again after each batch of 500 blocks, which is wasteful. BlockChainDownload(topHash); return; } var getdata = new GetDataMessage(_params); var dirty = false; foreach (var item in items) { if (item.Type != InventoryItem.ItemType.Block) { continue; } getdata.AddItem(item); dirty = true; } // No blocks to download. This probably contained transactions instead, but right now we can't prove they are // valid so we don't bother downloading transactions that aren't in blocks yet. if (!dirty) { return; } // This will cause us to receive a bunch of block messages. _conn.WriteMessage(getdata); }
/// <exception cref="IOException"/> private void ProcessInv(InventoryMessage inv) { // This should be called in the network loop thread for this peer // The peer told us about some blocks or transactions they have. For now we only care about blocks. // Note that as we don't actually want to store the entire block chain or even the headers of the block // chain, we may end up requesting blocks we already requested before. This shouldn't (in theory) happen // enough to be a problem. var topBlock = _blockChain.UnconnectedBlock; var topHash = topBlock != null ? topBlock.Hash : null; var items = inv.Items; if (items.Count == 1 && items[0].Type == InventoryItem.ItemType.Block && topHash != null && items[0].Hash.Equals(topHash)) { // An inv with a single hash containing our most recent unconnected block is a special inv, // it's kind of like a tickle from the peer telling us that it's time to download more blocks to catch up to // the block chain. We could just ignore this and treat it as a regular inv but then we'd download the head // block over and over again after each batch of 500 blocks, which is wasteful. BlockChainDownload(topHash); return; } var getdata = new GetDataMessage(_params); var dirty = false; foreach (var item in items) { if (item.Type != InventoryItem.ItemType.Block) continue; getdata.AddItem(item); dirty = true; } // No blocks to download. This probably contained transactions instead, but right now we can't prove they are // valid so we don't bother downloading transactions that aren't in blocks yet. if (!dirty) return; // This will cause us to receive a bunch of block messages. _conn.WriteMessage(getdata); }