Skip to content

v5.3.0

Choose a tag to compare

@github-actions github-actions released this 11 Oct 18:08
· 45 commits to main since this release
b3a8f3f

Nuthatch 5.3.0 proves which blocks a validator proposed (RFC-0063 plan C), whoever received their
fees, so rotki can book a validator's produced blocks and MEV from a nest alone. It also fixes a 5.2.0
defect that stopped rotki reading history from a nest with a start_block. Nothing outside an
[address_history] nest changes, and there is no storage migration.

Proven proposers per validator (Ethereum mainnet)

  • The proof is the chain's own. Block N+1's parent_beacon_block_root (EIP-4788) commits to the
    beacon header that produced block N, whose proposer_index names the proposer. Every row of a span
    is checked before any is filtered by validator, so a tampered row fails the span instead of hiding a
    proposal. Every span hangs from the block the nest's own RPC calls finalized, read by that tag.
  • Coverage: slot 12,777,208 (block 23,551,570) onward. A range starting earlier is refused with
    "proposals are proven from block 23551570". Proofs do not follow start_block or end_block;
    end_block bounds only what is served.
  • Where the proofs come from: catalogue files beside the block partitions on the mirror (published
    for blocks 23,551,570 to 26,159,999), and for the blocks above them, built here from the RPC and a
    beacon node when beacon_url (or NUTHATCH_BEACON_URL) names one. Without one, those blocks stay
    incomplete.
  • API: validators = [...], or POST /api/watch with {"validator": N};
    account/nuthatchValidatorBlocks&validator=N&startblock&endblock&page&offset, complete or refused,
    with supportedFrom and verifiedThrough. Rows carry the block reward (verified from the block's
    receipts, or rewardStatus: unavailable and retried, never zero), the relays' MEV, and the builder's
    payment from the block's traces.
  • nuthatch partitions --proposers --beacon-url URL --beacon-cache DIR builds the catalogue for a
    mirror from its block partitions, verifying every header as a nest does.

Fixes

  • A range before start_block names where history starts (fixes 5.2.0). Every account action
    refused a range starting before start_block, including rotki's usual startblock=0 and a request
    with no start, as "not indexed at block 0", which rotki could not act on. It now says "history starts
    at block N", and rotki asks again from there.
  • A covered answer above the finalized head is served on one hash check instead of waiting for the
    cursor. Measured with the cursor busy backfilling another account: every request timed out at 20 s
    before; 0.08 to 0.53 s after.
  • logs/getLogs fetches a page's receipts and timestamps together, 16 at a time, and answers
    within the request deadline or refuses.
  • A request above what is covered is served inside a long backfill. The cursor serves such
    requests between its windows, and a window could cover 50,000 blocks: on mainnet, tip requests for
    one account while the nest backfilled a busy wallet waited 10.9 to 16.0 s each. Backfill windows now
    start at 128 blocks and are paced to a quarter of the request deadline, and the bridge to the
    finalized block serves waiting requests between its chunks. The same measurement: 0.05 to 2.6 s,
    except a first request right after startup, which can still wait for the first windows.
  • request_deadline defaults to 8 s, down from 20 s, and is one ceiling per request from its
    arrival: the hash check, the queue, a window the cursor is part way through, a trace and a cover all
    count against it. A fully covered range is served if its final read completes within that ceiling;
    otherwise the request is refused. A gap the cursor cannot cover in time at its measured pace is
    refused at once with how far history is covered. The pace is measured per layer (discovery, block
    bodies, produced blocks), the layers' times add up, and owed relay re-asks count as blocks.
  • Recent timestamp lookups search near the chain head first. rotki's usual timestamp just
    behind the tip is bracketed within eight blocks, avoiding a search from genesis that could exhaust
    the four-second search budget. The answer still passes the same neighbour and ancestry checks.
  • An open mirror is read as far as it has published. A [address_history.mirror] without
    to_block follows the mirror's newest partition; coverage it cannot verify is taken back first.

Compatibility and upgrade

Replace the binary and restart. A 5.2.0 store is used as it is. Validator watches start empty.