Test Details Overview

Keep the representative weight cache flat (#5227)

* Benchmark the representative weight cache

Measures what the cache costs its callers with 64, 1k, 10k and 100k
cached representatives: the weight of one representative with and
without a cached weight, the weights of a ballot's hundred voters
written into a span or returned as a map, setting a weight again, a
copy of the whole cache, and a mix of one tally and one lookup per vote
with an update every hundred votes. Every benchmark reports time, heap
allocations and bytes per operation.

The cache under test stands alone, bound to a dev node's store view and
filled through `put`, which touches the cache only, so the numbers are
those of the table and its lock.

* Keep the representative weight cache flat

The cache kept the weight of every representative at or above the cache
minimum in a std::unordered_map, a node per representative. A copy of
the whole cache, which the rep tiers take on every refresh and the
representatives and representative_count RPCs on every call, allocated
a node per representative while it held the cache's lock, so a ledger
write changing a weight waited for the whole copy. A batch read
returned as a map, as an election reads the weights of its voters,
allocated a node per voter.

The cache is now a boost::unordered_flat_map, so a copy is one
allocation and one pass over a contiguous table, an order of magnitude
faster at every size measured, and a lookup reads one table instead of
a bucket and a node. Before the bootstrap height the ledger's snapshot
copies the bootstrap weights into the same type, and the weight check
of the node's entry point sums either kind of map. The header now also
says what the committed and unused weights hold and what the
consistency check asserts.

* Test the weight snapshot and consistency check and regroup the weight tests

The whole-cache snapshot had no test of what it holds: it now has one
pinning that it carries exactly the representatives at or above the
cache minimum with their weights, and that a snapshot already taken
stays as it was while the cache moves on. The consistency check had
only ever been seen to pass; two death tests show it stopping the node
when committed and unused weight do not add up to the supply and when
the committed weight leaves no room for the burned balance. The weight
cache test also checks that a cache counts as empty until it is loaded.

The older ledger tests of weights join the weights group under its
naming scheme, each with a description: rollback_representation
becomes weights_rollback and now checks the result of its last
rollback, representation becomes weights_legacy_blocks,
change_representative_move_representation becomes
weights_change_without_balance and checks that the change moves
nothing, bootstrap_weights becomes weights_bootstrap, and
zero_rep_weight becomes weights_zero_representative on a bare ledger
instead of a whole node. Every test the change moves or edits gets
step comments saying what each block or rollback does to the weights.

__________

Type: commit

Hash: 58d368cb95676ee5e0729197c701ecce23f664c9

Created: today

__________

gr0v1ty/nano-node:58d368cb95676ee5e0729197c701ecce23f664c9

Test Results

Test Case Status Duration Median Deviation Log Graph