Skip to content

Commit 6ec41df

Browse files
authored
Merge pull request #981 from evoskuil/master
Fix protocol_block_out stall after batch completion.
2 parents 1a9847d + d15c058 commit 6ec41df

File tree

4 files changed

+28
-18
lines changed

4 files changed

+28
-18
lines changed

include/bitcoin/node/events.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ enum events : uint8_t
5757
snapshot_secs, // snapshot timespan in seconds.
5858
prune_msecs, // prune timespan in milliseconds.
5959
reload_msecs, // store reload timespan in milliseconds.
60-
block_msecs, // getblock timespan in milliseconds.
60+
block_usecs, // getblock timespan in microseconds.
6161
ancestry_msecs, // getancestry timespan in milliseconds.
6262
filter_msecs, // getfilter timespan in milliseconds.
6363
filterhashes_msecs, // getfilterhashes timespan in milliseconds.

include/bitcoin/node/protocols/protocol_block_out_106.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,11 @@ class BCN_API protocol_block_out_106
6969
const network::messages::peer::get_blocks& locator) const NOEXCEPT;
7070

7171
private:
72-
// These are thread safe.
72+
// This is thread safe.
7373
const bool node_witness_;
74+
75+
// This is protected by strand.
76+
bool busy_{};
7477
};
7578

7679
} // namespace node

src/protocols/protocol_block_out_106.cpp

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,19 @@ bool protocol_block_out_106::handle_receive_get_data(const code& ec,
147147
if (stopped(ec))
148148
return false;
149149

150-
// Send and desubscribe.
150+
if (!message->any_block())
151+
return true;
152+
153+
if (busy_)
154+
{
155+
LOGR("Overlapping block requests [" << opposite() << "].");
156+
stop(network::error::protocol_violation);
157+
return false;
158+
}
159+
160+
busy_ = true;
151161
send_block(error::success, zero, message);
152-
return false;
162+
return true;
153163
}
154164

155165
// Outbound (block).
@@ -162,19 +172,18 @@ void protocol_block_out_106::send_block(const code& ec, size_t index,
162172
if (stopped(ec))
163173
return;
164174

165-
// Skip over non-block inventory.
166-
for (; index < message->items.size(); ++index)
167-
if (message->items.at(index).is_block_type())
168-
break;
175+
// Skip over non-block requests.
176+
const auto& items = message->items;
177+
for (; index < items.size() && !items.at(index).is_block_type(); ++index);
169178

170-
if (index >= message->items.size())
179+
// No more block requests.
180+
if (index == items.size())
171181
{
172-
// Complete, resubscribe to block requests.
173-
SUBSCRIBE_CHANNEL(get_data, handle_receive_get_data, _1, _2);
182+
busy_ = false;
174183
return;
175184
}
176185

177-
const auto& item = message->items.at(index);
186+
const auto& item = items.at(index);
178187
const auto witness = item.is_witness_type();
179188
if (!node_witness_ && witness)
180189
{
@@ -183,23 +192,20 @@ void protocol_block_out_106::send_block(const code& ec, size_t index,
183192
return;
184193
}
185194

186-
// Block could be always queried with witness and therefore safely cached.
187-
// If can then be serialized according to channel configuration, however
188-
// that is currently fixed to witness as available in the object.
189195
const auto& query = archive();
190196
const auto start = logger::now();
191197
const auto ptr = query.get_block(query.to_header(item.hash), witness);
192198
if (!ptr)
193199
{
194-
LOGR("Requested block " << encode_hash(item.hash)
195-
<< " from [" << opposite() << "] not found.");
200+
LOGR("Requested block " << encode_hash(item.hash) << " from ["
201+
<< opposite() << "] not found.");
196202

197203
// This block could not have been advertised to the peer.
198204
stop(system::error::not_found);
199205
return;
200206
}
201207

202-
span<milliseconds>(events::block_msecs, start);
208+
span<microseconds>(events::block_usecs, start);
203209
SEND(block{ ptr }, send_block, _1, add1(index), message);
204210
}
205211

src/protocols/protocol_transaction_out_106.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ void protocol_transaction_out_106::send_transaction(const code& ec,
152152
if (message->items.at(index).is_transaction_type())
153153
break;
154154

155+
// BUGBUG: registration race.
155156
if (index >= message->items.size())
156157
{
157158
// Complete, resubscribe to transaction requests.

0 commit comments

Comments
 (0)