Skip to content

Commit 573cdd1

Browse files
authored
Merge pull request #737 from evoskuil/master
Complete validation off-strand, making backlog counter atomic.
2 parents 0160386 + edf6cbf commit 573cdd1

File tree

4 files changed

+23
-32
lines changed

4 files changed

+23
-32
lines changed

include/bitcoin/node/chasers/chaser_check.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,13 @@ class BCN_API chaser_check
6161

6262
virtual void do_bump(height_t height) NOEXCEPT;
6363
virtual void do_checked(height_t height) NOEXCEPT;
64+
virtual void do_advanced(height_t height) NOEXCEPT;
6465
virtual void do_headers(height_t branch_point) NOEXCEPT;
6566
virtual void do_regressed(height_t branch_point) NOEXCEPT;
6667
virtual void do_handle_purged(const code& ec) NOEXCEPT;
6768
virtual void do_get_hashes(const map_handler& handler) NOEXCEPT;
6869
virtual void do_put_hashes(const map_ptr& map,
6970
const network::result_handler& handler) NOEXCEPT;
70-
virtual void do_confirmable(height_t height) NOEXCEPT;
7171

7272
private:
7373
typedef std::deque<map_ptr> maps;
@@ -89,7 +89,7 @@ class BCN_API chaser_check
8989
// These are protected by strand.
9090
size_t inventory_{};
9191
size_t requested_{};
92-
size_t confirmed_{};
92+
size_t advanced_{};
9393
job::ptr job_{};
9494
maps maps_{};
9595
};

include/bitcoin/node/chasers/chaser_validate.hpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#ifndef LIBBITCOIN_NODE_CHASERS_CHASER_VALIDATE_HPP
2020
#define LIBBITCOIN_NODE_CHASERS_CHASER_VALIDATE_HPP
2121

22+
#include <atomic>
2223
#include <bitcoin/database.hpp>
2324
#include <bitcoin/network.hpp>
2425
#include <bitcoin/node/chasers/chaser.hpp>
@@ -59,8 +60,6 @@ class BCN_API chaser_validate
5960
const system::chain::context& ctx) NOEXCEPT;
6061
virtual code populate(bool bypass, const system::chain::block& block,
6162
const system::chain::context& ctx) NOEXCEPT;
62-
virtual void tracked_complete_block(const code& ec,
63-
const database::header_link& link, size_t height, bool bypassed) NOEXCEPT;
6463
virtual void complete_block(const code& ec,
6564
const database::header_link& link, size_t height, bool bypassed) NOEXCEPT;
6665

@@ -74,11 +73,11 @@ class BCN_API chaser_validate
7473
return backlog_ < maximum_backlog_;
7574
}
7675

77-
// These are protected by strand.
78-
size_t backlog_{};
76+
// This is protected by strand.
7977
network::threadpool threadpool_;
8078

8179
// These are thread safe.
80+
std::atomic<size_t> backlog_{};
8281
network::asio::strand independent_strand_;
8382
const uint32_t subsidy_interval_;
8483
const uint64_t initial_subsidy_;

src/chasers/chaser_check.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,11 @@ bool chaser_check::handle_event(const code&, chase event_,
129129
POST(do_headers, std::get<height_t>(value));
130130
break;
131131
}
132-
case chase::confirmable:
132+
////case chase::confirmable:
133+
case chase::valid:
133134
{
134135
BC_ASSERT(std::holds_alternative<height_t>(value));
135-
POST(do_confirmable, std::get<height_t>(value));
136+
POST(do_advanced, std::get<height_t>(value));
136137
break;
137138
}
138139
case chase::stop:
@@ -205,15 +206,15 @@ void chaser_check::do_regressed(height_t branch_point) NOEXCEPT
205206
// track downloaded in order (to move download window)
206207
// ----------------------------------------------------------------------------
207208

208-
void chaser_check::do_confirmable(height_t height) NOEXCEPT
209+
void chaser_check::do_advanced(height_t height) NOEXCEPT
209210
{
210211
BC_ASSERT(stranded());
211212

212213
// Confirmations are ordered and notification order is guaranteed.
213-
confirmed_ = height;
214+
advanced_ = height;
214215

215216
// The full set of requested hashes has been confirmed.
216-
if (confirmed_ == requested_)
217+
if (advanced_ == requested_)
217218
do_headers(height);
218219
}
219220

@@ -345,8 +346,7 @@ size_t chaser_check::set_unassociated() NOEXCEPT
345346
return {};
346347

347348
// Defer new work issuance until gaps filled and confirmation caught up.
348-
if (position() < requested_ ||
349-
confirmed_ < requested_)
349+
if (position() < requested_ || advanced_ < requested_)
350350
return {};
351351

352352
// Inventory size gets set only once.

src/chasers/chaser_validate.cpp

+11-19
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
#include <bitcoin/node/chasers/chaser_validate.hpp>
2020

21+
#include <atomic>
2122
#include <bitcoin/system.hpp>
2223
#include <bitcoin/node/chasers/chaser.hpp>
2324
#include <bitcoin/node/define.hpp>
@@ -171,6 +172,7 @@ void chaser_validate::do_bump(height_t) NOEXCEPT
171172
return;
172173
}
173174

175+
// block_unknown allowed here (debug reset).
174176
const auto bypass =
175177
(ec == database::error::block_valid) ||
176178
(ec == database::error::block_confirmable) ||
@@ -182,7 +184,7 @@ void chaser_validate::do_bump(height_t) NOEXCEPT
182184
}
183185
else
184186
{
185-
++backlog_;
187+
backlog_.fetch_add(one, std::memory_order_relaxed);
186188
PARALLEL(validate_block, link, bypass);
187189
}
188190

@@ -225,8 +227,10 @@ void chaser_validate::validate_block(const header_link& link,
225227
ec = error::validate5;
226228
}
227229

230+
backlog_.fetch_sub(one, std::memory_order_relaxed);
231+
228232
// Return to strand to handle result.
229-
POST(tracked_complete_block, ec, link, ctx.height, bypass);
233+
complete_block(ec, link, ctx.height, bypass);
230234
}
231235

232236
code chaser_validate::populate(bool bypass, const chain::block& block,
@@ -267,30 +271,19 @@ code chaser_validate::validate(bool bypass, const chain::block& block,
267271
if ((ec = block.connect(ctx)))
268272
return ec;
269273

270-
if (!query.set_prevouts(link, block))
271-
return error::validate8;
274+
if ((ec = query.set_prevouts(link, block)))
275+
return ec;
272276

273277
if (!query.set_block_valid(link, block.fees()))
274-
return error::validate9;
278+
return error::validate6;
275279

276280
return ec;
277281
}
278282

279-
// The size of the job is not relevant to the backlog cost.
280-
void chaser_validate::tracked_complete_block(const code& ec,
281-
const header_link& link, size_t height, bool bypassed) NOEXCEPT
282-
{
283-
BC_ASSERT(stranded());
284-
285-
--backlog_;
286-
complete_block(ec, link, height, bypassed);
287-
}
288-
283+
// Completes off strand.
289284
void chaser_validate::complete_block(const code& ec, const header_link& link,
290285
size_t height, bool bypassed) NOEXCEPT
291286
{
292-
BC_ASSERT(stranded());
293-
294287
if (ec)
295288
{
296289
if (node::error::error_category::contains(ec))
@@ -307,7 +300,6 @@ void chaser_validate::complete_block(const code& ec, const header_link& link,
307300
// Stop the network in case of an unexpected invalidity (debugging).
308301
// This is considered a bug, not an invalid block arrival (for now).
309302
////fault(ec);
310-
311303
return;
312304
}
313305

@@ -320,7 +312,7 @@ void chaser_validate::complete_block(const code& ec, const header_link& link,
320312
}
321313

322314
// Prevent stall by posting internal event, avoid hitting external handlers.
323-
if (is_zero(backlog_))
315+
if (is_zero(backlog_.load(std::memory_order_relaxed)))
324316
handle_event(ec, chase::bump, height_t{});
325317
}
326318

0 commit comments

Comments
 (0)