| 88 | } |
| 89 | |
| 90 | void BlockSender::sendBlock(CNode& node, |
| 91 | const CBlockIndex& blockIndex, int invType, int activeChainHeight) |
| 92 | { |
| 93 | |
| 94 | // Send block from disk |
| 95 | CBlock block; |
| 96 | if (!readBlockFromDisk(block, &blockIndex) || block.IsNull()) |
| 97 | throw std::runtime_error("cannot read block from disk"); |
| 98 | |
| 99 | // We only support MSG_XTHINBLOCK, if peer wants MSG_THINBLOCK, |
| 100 | // fallback to full one. |
| 101 | if (invType == MSG_BLOCK || (invType == MSG_THINBLOCK |
| 102 | && !NodeStatePtr(node.id)->supportsCompactBlocks)) |
| 103 | { |
| 104 | // Fun fact: |
| 105 | // Responding to a BUIP010 MSG_THINBLOCK is actually a BIP152 violation. |
| 106 | // MSG_CMPCT_BLOCK uses the same enum value as MSG_THINBLOCK. |
| 107 | // |
| 108 | // BIP152 states: |
| 109 | // "Nodes MUST NOT send a request for a MSG_CMPCT_BLOCK object to a |
| 110 | // peer before having received a sendcmpct message from that peer." |
| 111 | |
| 112 | node.PushMessage("block", block); |
| 113 | return; |
| 114 | } |
| 115 | |
| 116 | if (invType == MSG_XTHINBLOCK) { |
| 117 | CBloomFilter filter; |
| 118 | { |
| 119 | LOCK(node.cs_xfilter); |
| 120 | filter = *node.xthinFilter; |
| 121 | } |
| 122 | |
| 123 | try { |
| 124 | bool sent = false; |
| 125 | if (withinDepthLimits(MAX_CMPCTBLOCK_DEPTH, blockIndex.nHeight, activeChainHeight)) { |
| 126 | XThinBlock thinb(block, filter); |
| 127 | if (thinIsSmaller(block, thinb)) { |
| 128 | node.PushMessage("xthinblock", thinb); |
| 129 | sent = true; |
| 130 | } |
| 131 | } |
| 132 | if (!sent) |
| 133 | node.PushMessage("block", block); |
| 134 | } |
| 135 | catch (const xthin_collision_error& e) { |
| 136 | LogPrintf("tx collision in thin block %s\n", |
| 137 | block.GetHash().ToString()); |
| 138 | |
| 139 | // fall back to full block |
| 140 | node.PushMessage("block", block); |
| 141 | } |
| 142 | return; |
| 143 | } |
| 144 | |
| 145 | if (invType == MSG_CMPCT_BLOCK && NodeStatePtr(node.id)->supportsCompactBlocks) { |
| 146 | if (withinDepthLimits(MAX_CMPCTBLOCK_DEPTH, blockIndex.nHeight, activeChainHeight)) { |
| 147 | CompactBlock cmpct(block, *choosePrefiller(node)); |
no test coverage detected