@@ -30,9 +30,6 @@ using namespace system::chain;
3030using namespace database ;
3131using namespace std ::placeholders;
3232
33- // Shared pointers required for lifetime in handler parameters.
34- BC_PUSH_WARNING (NO_VALUE_OR_CONST_REF_SHARED_PTR )
35- BC_PUSH_WARNING (SMART_PTR_NOT_NEEDED )
3633BC_PUSH_WARNING (NO_THROW_IN_NOEXCEPT )
3734
3835// Capture handlers.
@@ -63,68 +60,6 @@ void chaser_validate::do_fire(missed miss, size_t count) NOEXCEPT
6360 }
6461}
6562
66- bool chaser_validate::do_ecdsa (const hash_digest& digest,
67- const ec_compressed& point, const ec_signature& sign,
68- const header_link& link, const atomic_counter_ptr& sequence) NOEXCEPT
69- {
70- ++counters_.ecdsa_ ;
71- const auto id = (*sequence)++;
72- if (is_limited<uint16_t >(id)) return false ;
73- const auto group = narrow_cast<uint16_t >(id);
74- const auto set = archive ().set_signature (digest, point, sign, group, link);
75- if (!set) fault (error::batch5);
76- return set;
77- }
78-
79- bool chaser_validate::do_schnorr (const hash_digest& digest,
80- const ec_xonly& point, const ec_signature& sign,
81- const header_link& link) NOEXCEPT
82- {
83- ++counters_.schnorr_ ;
84- const auto set = archive ().set_signature (digest, point, sign, link);
85- if (!set) fault (error::batch6);
86- return set;
87- }
88-
89- bool chaser_validate::do_multisig (const hash_digest& digest,
90- const std::span<const system::ec_compressed>& points,
91- const std::span<const system::ec_signature>& signs,
92- const header_link& link, const atomic_counter_ptr& sequence) NOEXCEPT
93- {
94- counters_.multisig_ += points.size ();
95- const auto id = (*sequence)++;
96- if (is_limited<uint16_t >(id)) return false ;
97- const auto group = narrow_cast<uint16_t >(id);
98- const auto set = archive ().set_signatures (digest, points, signs, group, link);
99- if (!set) fault (error::batch7);
100- return set;
101- }
102-
103- bool chaser_validate::do_threshold (const hash_digest& digest,
104- const ec_xonly& point, const ec_signature& sign,
105- const schnorr_link_ptr& fk_ptr, const header_link& link) NOEXCEPT
106- {
107- auto set = archive ().set_signature ((*fk_ptr)++, digest, point, sign, link);
108- if (!set) fault (error::batch8);
109- return set;
110- }
111-
112- chaser_validate::cursor chaser_validate::open_threshold (size_t rows,
113- const header_link& link) NOEXCEPT
114- {
115- auto first = archive ().allocate_signatures (rows);
116- const auto fk = emplace_shared<schnorr_link>(first);
117- if (fk->is_terminal ())
118- return {};
119-
120- counters_.threshold_ += rows;
121- return
122- {
123- .put = BIND_THIS (do_threshold, _1, _2, _3, fk, link),
124- .rows = rows
125- };
126- }
127-
12863// Capture helpers.
12964// ----------------------------------------------------------------------------
13065// private
@@ -134,19 +69,87 @@ signatures chaser_validate::get_capture(const header_link& link) NOEXCEPT
13469 if (!batch_enabled_ || link.is_terminal () || is_current_header (link))
13570 return { false };
13671
137- const auto sequence = to_shared<atomic_counter>();
72+ // The capture populates this thread's accumulators (commit_capture consumes).
13873 return signatures
13974 {
14075 .enabled = true ,
14176 .log = BIND_THIS (do_log, _1),
142- .fire = BIND_THIS (do_fire, _1, _2),
143- .ecdsa = BIND_THIS (do_ecdsa, _1, _2, _3, link, sequence),
144- .schnorr = BIND_THIS (do_schnorr, _1, _2, _3, link),
145- .multisig = BIND_THIS (do_multisig, _1, _2, _3, link, sequence),
146- .threshold = BIND_THIS (open_threshold, _1, link)
77+ .fire = BIND_THIS (do_fire, _1, _2)
14778 };
14879}
14980
81+ // Commit this thread's captured signatures as the block's batch rows. All
82+ // batch table state is written inside the commit epoch (turnstile). When
83+ // diverted by a drain, or upon store decline, the rows are verified in
84+ // place, equivalent to the inline evaluation their capture fabricated
85+ // (batched is cleared so the block completes by the non-batched path).
86+ code chaser_validate::commit_capture (bool & batched,
87+ const header_link& link) NOEXCEPT
88+ {
89+ code ec{};
90+ auto committed = false ;
91+ auto & ecdsa = signatures::ecdsa_rows ();
92+ auto & schnorr = signatures::schnorr_rows ();
93+
94+ if (enter_capture ())
95+ {
96+ auto & query = archive ();
97+ committed =
98+ query.set_signatures (ecdsa, link) &&
99+ query.set_signatures (schnorr, link) &&
100+ query.set_prevalid (link);
101+ exit_capture ();
102+
103+ // Store decline (e.g. disk full), recoverable once faulted.
104+ if (!committed)
105+ fault (error::batch5);
106+ }
107+
108+ const auto thresholds = schnorr.thresholds ();
109+ const auto singles = schnorr.rows ().size () - thresholds;
110+
111+ if (committed)
112+ {
113+ counters_.ecdsa_ += ecdsa.singles ();
114+ counters_.multisig_ += ecdsa.multisig_keys ();
115+ counters_.schnorr_ += singles;
116+ counters_.threshold_ += thresholds;
117+ }
118+ else
119+ {
120+ counters_.missed_ecdsa_ += ecdsa.singles ();
121+ counters_.missed_multisig_ += ecdsa.multisig_keys ();
122+ counters_.missed_schnorr_ += singles;
123+ counters_.missed_threshold_ += thresholds;
124+
125+ // Block validity remains fully determined.
126+ batched = false ;
127+ if (!ecdsa.verify () || !schnorr.verify ())
128+ ec = system::error::invalid_signature;
129+ }
130+
131+ ecdsa.clear ();
132+ schnorr.clear ();
133+ return ec;
134+ }
135+
136+ // Discard this thread's captured signatures (script failure preempted commit).
137+ void chaser_validate::clear_capture () NOEXCEPT
138+ {
139+ signatures::ecdsa_rows ().clear ();
140+ signatures::schnorr_rows ().clear ();
141+ }
142+
143+ // Release all threads' accumulator capacity (batching subsided). Safe on the
144+ // strand with an empty backlog: accumulators are populated only within
145+ // validate_block, and the strand is the sole poster of validations.
146+ void chaser_validate::do_purge_capture () NOEXCEPT
147+ {
148+ BC_ASSERT (stranded ());
149+ if (is_zero (validate_backlog_.load ()))
150+ signatures::purge ();
151+ }
152+
150153std::string chaser_validate::log_ratio (const std::string& name,
151154 size_t numerator, size_t denominator) const NOEXCEPT
152155{
@@ -167,11 +170,9 @@ void chaser_validate::log_captures() const NOEXCEPT
167170 LOGN (log_ratio (" Capture schnorr.." , counters_.schnorr_ ,
168171 counters_.schnorr_ + counters_.missed_schnorr_ ));
169172 LOGN (log_ratio (" Capture threshold" , counters_.threshold_ ,
170- counters_.threshold_ + zero ));
173+ counters_.threshold_ + counters_. missed_threshold_ ));
171174}
172175
173- BC_POP_WARNING ()
174- BC_POP_WARNING ()
175176BC_POP_WARNING ()
176177
177178} // namespace node
0 commit comments