Test Details Overview

Refuse blocks once the block processor stops and drop the queued ones (#5263)

* Refuse blocks once the block processor stops and drop the queued ones

A blocking add queued its block and waited on the result promise with
no timeout. After stop () nothing processes the queue, and the queued
context kept the promise alive, so the caller waited until the
processor was destroyed. node::stop () stops the block processor before
the wallets, so a wallet receive that reached process_local () in that
window blocked the wallet action thread, wallets::stop () never got its
join back, and the node hung on shutdown. node.rep_self_vote hit it on
CI: its block0 confirms, and the wallet auto-receives it while the test
tears down.

add_impl now checks `stopped` under the lock its pushes take and
refuses the block once it is set, and stop () drops whatever is still
queued after joining the thread. A blocking add's block is either
refused or queued before the drop, so the add always gets a result or a
broken promise and returns nullopt. Both are counted as `stopped`.
Batch adds keep their own path unchanged: nothing waits on them, so a
batch queued after stop () only sits there until the processor is
destroyed, as before.

block_processor.size_per_channel froze the queue by stopping the
processor and adding afterwards, which a stopped processor now refuses.
It runs on a processor that is never started instead.

Against the previous implementation add_after_stop fails at its first
assertion, add () accepting the block, and add_blocking_released_on_stop
times out waiting for the blocked add to return.

* Drop the ledger notifications still queued when they stop

Processed block contexts, with the result promises of blocking adds,
are completed on the ledger notifications thread. A notification still
queued when that thread exited kept its promises pending until the
component was destroyed, the same wait the block processor's queue
caused one step earlier. stop () now drops the queue after joining the
thread, counted as `stopped`. The block processor is the only source of
processed notifications and stops first, so nothing queues one after
the drop.

Against the previous implementation stop_drops_queued fails: the
promise is still pending after stop ().

__________

Type: commit

Hash: 7d8e31cdd7c8483f2cbb1d5cfffa97d6bce188aa

Created: yesterday

__________

gr0v1ty/nano-node:7d8e31cdd7c8483f2cbb1d5cfffa97d6bce188aa

Test Results

Test Case Status Duration Median Deviation Log Graph
5n4pr_conf_10k_bintree PASS 106 s -4.5 s GitHub job logs Show
5n4pr_conf_10k_change PASS 175 s 42.0 s GitHub job logs Show
5n4pr_conf_change_dependant PASS 109 s -6.5 s GitHub job logs -
5n4pr_conf_change_independant PASS 107 s -6.0 s GitHub job logs -
5n4pr_conf_send_dependant PASS 108 s -6.0 s GitHub job logs -
5n4pr_conf_send_independant PASS 110 s -2.0 s GitHub job logs -
5n4pr_rocks_10k_bintree PASS 109 s -3.0 s GitHub job logs -
5n4pr_rocks_10k_change PASS 160 s 2.5 s GitHub job logs -