@@ -276,7 +276,7 @@ code chaser_validate::populate(bool bypass, const chain::block& block,
276276}
277277
278278code chaser_validate::validate (bool bypass, const chain::block& block,
279- const database:: header_link& link, const chain::context& ctx) NOEXCEPT
279+ const header_link& link, const chain::context& ctx) NOEXCEPT
280280{
281281 auto & query = archive ();
282282
@@ -296,160 +296,8 @@ code chaser_validate::validate(bool bypass, const chain::block& block,
296296 if ((ec = block.accept (ctx, subsidy_interval_, initial_subsidy_)))
297297 return ec;
298298
299- if (batch_signatures_)
300- {
301- using namespace chain ;
302- std::atomic<size_t > set{};
303- code capture_ec{};
304-
305- const auto to_events = [](opcode op) NOEXCEPT
306- {
307- switch (op)
308- {
309- // ecdsa single (checksig/verify).
310- case opcode::checksigverify:
311- return events::checksigverify;
312-
313- // ecdsa multiple (checkmultisig/verify).
314- case opcode::checkmultisigverify:
315- return events::checkmultisigverify;
316-
317- // schnorr single (op_checksigadd|op_checksig/verify).
318- case opcode::checksigadd:
319- return events::checksigadd;
320-
321- // schnorr multiple (multisig pattern).
322- case opcode::checksig:
323- return events::checksig;
324-
325- // schnorr multiple (is_threshold).
326- case opcode::numequal:
327- return events::numequal;
328- case opcode::numequalverify:
329- return events::numequalverify;
330- case opcode::numnotequal:
331- return events::numnotequal;
332- case opcode::lessthan:
333- return events::lessthan;
334- case opcode::greaterthan:
335- return events::greaterthan;
336- case opcode::lessthanorequal:
337- return events::lessthanorequal;
338- case opcode::greaterthanorequal:
339- return events::greaterthanorequal;
340- case opcode::within:
341- return events::within;
342-
343- // should be no path to this.
344- default :
345- return events::unknown;
346- }
347- };
348-
349- const signatures capture
350- {
351- // Enable/disable capture.
352- .enabled = batch_signatures_,
353-
354- .log = [&](const script& ) NOEXCEPT
355- {
356- // //LOGA("Sigop @ " << ctx.height << " -> "
357- // // << missed.to_string(chain::flags::all_rules));
358- },
359- .fire = [&](signatures::miss miss, size_t count) NOEXCEPT
360- {
361- switch (miss)
362- {
363- case signatures::miss::ecdsa:
364- missed_ecdsa_ += count;
365- // //fire(events::missed_ecdsa, ctx.height);
366- break ;
367- case signatures::miss::multisig:
368- missed_multisig_ += count;
369- // //fire(events::missed_multisig, ctx.height);
370- break ;
371- case signatures::miss::schnorr:
372- missed_schnorr_ += count;
373- // //fire(events::missed_schnorr, ctx.height);
374- break ;
375- case signatures::miss::overflow:
376- // Misses overflow to single, so not called.
377- // This is instead used to reflect cache failure.
378- missed_threshold_ += count;
379- // //fire(events::missed_overflow, ctx.height);
380- break ;
381-
382- // should be no path to this.
383- default :
384- BC_ASSERT_MSG (false , " unknown signatures::miss" );
385- }
386- },
387- .ecdsa = [&](const hash_digest& digest,
388- const ec_compressed& point,
389- const ec_signature& sign) NOEXCEPT
390- {
391- ++ecdsa_;
392- // //fire(to_events(opcode::checksigverify), ctx.height);
393- return query.set_signature (digest, point, sign, link);
394- },
395- .schnorr = [&](const hash_digest& digest, const ec_xonly& point,
396- const ec_signature& sign) NOEXCEPT
397- {
398- ++schnorr_;
399- // //fire(to_events(opcode::checksigadd), ctx.height);
400- return query.set_signature (digest, point, sign, link);
401- },
402- .multisig = [&](const hash_digest& digest,
403- const ec_compresseds& points,
404- const ec_signatures& signs) NOEXCEPT
405- {
406- BC_ASSERT (points.size () == signs.size ());
407- multisig_ += points.size ();
408- // //fire(to_events(opcode::checkmultisigverify), ctx.height);
409- return query.set_signatures (digest, points, signs, set, link);
410- },
411- .threshold = [&](
412- const signatures::threshold_entries& group) NOEXCEPT
413- {
414- // Sets condition to opcode::checksig for all required.
415- threshold_ += group.entries .size ();
416- // //fire(to_events(group.condition), ctx.height);
417-
418- // Script always processing proceeds as if batch succeeded.
419- if (!query.set_signatures (group, set, link))
420- capture_ec = fault (error::capture_fault);
421- }
422- };
423-
424- // Prioritize validation failure over capture failure.
425- if ((ec = block.connect (ctx, capture)))
426- return ec;
427-
428- // TODO: repost block (link) to work queue in complete_block
429- // TODO: based on error::capture_fault.
430- if (capture_ec)
431- return capture_ec;
432-
433- const auto log_capture = [&](std::string_view name,
434- size_t captured, size_t missed) NOEXCEPT
435- {
436- if (!to_bool (captured) && !to_bool (missed)) return ;
437- const auto ratio = (100 .0f * captured) / (captured + missed);
438- const auto rate = (boost_format (" %.4f" ) % ratio).str ();
439- LOGA (" Efficiency " << name << rate << " % = " << captured
440- << " /(" << captured << " +" << missed << " )" );
441- };
442-
443- log_capture (" ecdsa.... " , ecdsa_, missed_ecdsa_);
444- log_capture (" multisig. " , multisig_, missed_multisig_);
445- log_capture (" schnorr.. " , schnorr_, missed_schnorr_);
446- log_capture (" threshold " , threshold_, missed_threshold_);
447- }
448- else
449- {
450- if ((ec = block.connect (ctx)))
451- return ec;
452- }
299+ if ((ec = block.connect (ctx, get_capture (link))))
300+ return ec;
453301
454302 // Prevouts optimize confirmation.
455303 if (!query.set_prevouts (link, block))
@@ -529,6 +377,114 @@ bool chaser_validate::stranded() const NOEXCEPT
529377 return validation_strand_.running_in_this_thread ();
530378}
531379
380+ // private
381+ // ----------------------------------------------------------------------------
382+
383+ chain::signatures chaser_validate::get_capture (
384+ const header_link& link) NOEXCEPT
385+ {
386+ if (!batch_signatures_)
387+ return {};
388+
389+ // Group identifier for block, incremented for each multisig/threshold.
390+ const auto id = to_shared<std::atomic<size_t >>();
391+
392+ using namespace chain ;
393+ return signatures
394+ {
395+ // Default struct is disabled.
396+ .enabled = true ,
397+
398+ // Enable for a game of whack-a-mole.
399+ .log = [&](const script& /* LOG_ONLY(missed) */ ) NOEXCEPT
400+ {
401+ // //LOGA("Sigop @ " << ctx.height << " -> "
402+ // // << missed.to_string(chain::flags::all_rules));
403+ },
404+
405+ // Update counters for missed capture.
406+ .fire = [&](signatures::miss miss, size_t count) NOEXCEPT
407+ {
408+ switch (miss)
409+ {
410+ case signatures::miss::ecdsa:
411+ missed_ecdsa_ += count;
412+ break ;
413+ case signatures::miss::multisig:
414+ missed_multisig_ += count;
415+ break ;
416+ case signatures::miss::schnorr:
417+ missed_schnorr_ += count;
418+ break ;
419+ default :;
420+ }
421+ },
422+
423+ // opcode::checksig/verify
424+ .ecdsa = [&](const hash_digest& digest, const ec_compressed& point,
425+ const ec_signature& sign) NOEXCEPT
426+ {
427+ ++ecdsa_;
428+ auto & query = archive ();
429+ return query.set_signature (digest, point, sign, link);
430+ },
431+
432+ // opcode::checksigadd | opcode::checksig/verify
433+ .schnorr = [&](const hash_digest& digest, const ec_xonly& point,
434+ const ec_signature& sign) NOEXCEPT
435+ {
436+ ++schnorr_;
437+ auto & query = archive ();
438+ return query.set_signature (digest, point, sign, link);
439+ },
440+
441+ // opcode::checkmultisig/verify
442+ .multisig = [&, id](const hash_digest& digest,
443+ const ec_compresseds& points, const ec_signatures& signs) NOEXCEPT
444+ {
445+ BC_ASSERT (points.size () == signs.size ());
446+ auto & query = archive ();
447+ multisig_ += points.size ();
448+ return query.set_signatures (digest, points, signs, (*id)++, link);
449+ },
450+
451+ // opcode::within
452+ // opcode::numequal/verify
453+ // opcode::numnotequal
454+ // opcode::lessthan
455+ // opcode::greaterthan
456+ // opcode::lessthanorequal
457+ // opcode::greaterthanorequal
458+ // opcode::checksig (m of m)
459+ .threshold = [&, id](const signatures::threshold_group& group) NOEXCEPT
460+ {
461+ threshold_ += group.entries .size ();
462+ auto & query = archive ();
463+ return query.set_signatures (group, (*id)++, link);
464+ }
465+ };
466+ }
467+
468+ void chaser_validate::log_capture (const std::string_view& name,
469+ size_t captured, size_t missed) const NOEXCEPT
470+ {
471+ if (to_bool (captured) || to_bool (missed))
472+ {
473+ const auto rate = (100 .0f * captured) / (captured + missed);
474+ const auto text = (boost_format (" %.4f" ) % rate).str ();
475+ LOGV (" Capture rate " << name << text << " % = " << captured
476+ << " /(" << captured << " +" << missed << " )" );
477+ }
478+ }
479+
480+ void chaser_validate::log_captures () const NOEXCEPT
481+ {
482+ log_capture (" ecdsa.... " , ecdsa_, missed_ecdsa_);
483+ log_capture (" multisig. " , multisig_, missed_multisig_);
484+ log_capture (" schnorr.. " , schnorr_, missed_schnorr_);
485+ log_capture (" threshold " , threshold_, zero);
486+ }
487+
532488BC_POP_WARNING ()
533489
534490} // namespace node
0 commit comments