Test Details Overview

Cap blocks random responses and tighten bootstrap request checks (#5239)

* Cap blocks random responses at 100 blocks

A blocks_random request may name up to 128 hashes and the server
answered with every block it found. The response now stops at 100
blocks, a new bootstrap_server::max_random_blocks, and the requester
fetches whatever was left out in a later round, which the topology
strategy already does for any hash a response does not carry. Hashes
the ledger does not hold do not count towards the cap.

* Request only as many random blocks as a peer will return

The topology strategy asked for 128 hashes per blocks_random request,
so against a peer with the response cap it got 100 blocks back and
re-requested the rest after the fetch cooldown. topo_scan.fetch_batch
now defaults to bootstrap_server::max_random_blocks, and its config
description says what larger values cost and when they help.

* Comment the bootstrap server and config declarations

Every setting in bootstrap_config.hpp and every declaration in
bootstrap_server.hpp gets a one-line comment saying what it holds or
does, read from the code that uses it. account_sets.consideration_count
is noted as a config key nothing reads.

* Test every bootstrap server request type at its limits

The suite exercised the rejection path of frontiers and topo index
requests only, asked for more items than the ledger held so no
response ever stopped at its count, and never ran the server disabled
or filled a channel's queue. Each request type now has a test that the
response stops at the requested count and one that a count or target
outside the allowed range is dropped and counted as invalid. Further
tests cover a blocks pull by an unknown account, account info by block
hash and by an unknown hash, frontiers from past the last account, a
disabled server dropping requests, the per-channel queue limit counting
overfill, and a blocks random request with more hashes than the limit
handed to the server directly, since the parser never lets one through.

* Test the blocks random parser and responses the client rejects

The blocks random request parser stops at 128 hashes and reads one
more to find the terminator. Three byte-level tests pin that a longer
list parses as the first 128, that a list cut right after the limit is
rejected, and that a zero hash ends the list wherever it appears.

The client discards a response whose payload type does not match its
query and a response for an unknown id, but nothing covered either
path. Two node tests do: one serves a node's requests from a second
node and hands the client a mismatched payload under a live id before
the real response goes out, the other processes a response for an id
the node never issued. Two verify tests cover a one-block response
that is not an echo of the requested start and the valid pull by
account, which had no test at all.

* Check at compile time that response caps fit the header length field

An asc_pull_ack carries its payload length in the 16-bit header
extensions field, and update_header only debug_asserts that the
payload fits. The three caps are now checked against the largest
serialization they allow, terminator included; the topo index cap
leaves 15 bytes of headroom.

* Reject unknown hash type bytes and oversized frontier pages

The start_type and target_type bytes of a bootstrap request were read
straight off the wire and never checked, so a value outside the enum
fell through the handler switches to an empty or all-zero response.
bootstrap_server::verify now drops such a request as invalid, like a
count outside its range.

On the client side, verify accepted a frontiers response with more
entries than the query asked for, unlike blocks and topo index pages;
it is now invalid as well.

__________

Type: commit

Hash: 58bfe155bda004af0c99d5956dd8bd5ca176829e

Created: yesterday

__________

gr0v1ty/nano-node:58bfe155bda004af0c99d5956dd8bd5ca176829e

Test Results

Test Case Status Duration Median Deviation Log Graph