Skip to content

Optimise state storage with long-term freezer database #499

@michaelsproul

Description

@michaelsproul

Description

As raised in #484 we need to do something about the duplication of state in the database. This RFC proposes to solve the problem by storing state efficiently before the last finalized checkpoint, in tables similar to those used in #484 (sequential DB keys, multiple values per key).

Design Details

This is more of a quick idea dump before I start prototyping:

  • Separate "hot" and "cold" databases. Provide an abstraction that makes the distinction transparent to the user (maybe with an optional flag to say "hot only" or "cold only"). We can implement the Store trait for the abstraction wrapper, so that the hot-cold DB can be swapped in and out with the existing DB implementation.
  • The wrapper over the hot and cold databases needs to keep track of the finalized checkpoint at which the database splits, so that it knows which database to check for a given state root/block root/slot.
  • We don't want to "stop the world" each time we want to move things from the hot database to the cold. I think we can avoid this by running the migration in its own thread, using an algorithm something like:
    1. Copy all of the state from hot to cold, taking only temporary per-entry read/write locks on the database (allows the main thread to interleave reads)
    2. Atomically update the finalized checkpoint in the database wrapper, so that it starts to direct queries for the recently copied states to the cold database.
    3. Delete the copied entries one by one from the hot database using short-lived write locks.
      AFAICT this should prevent the main thread from observing a partial migration (which would be difficult to handle).

TODO

A few issues require a bit more thought:

  • What if a finalized checkpoint is reverted, by 1/3 of validators getting slashed? If we have the wrong chain in our DB and we've deleted the other chain then we're a bit screwed. A pragmatic solution might be to lag protocol finalization by a little bit... i.e. only migrate the database once a checkpoint has other finalized checkpoints after it (but that would seem to defeat the point!)
  • Exactly how do we find all the short-lived forks that can be garbage-collected once the main chain is finalized? We likely want to hook into the fork choice code, but I haven't thought about this in-depth or formulated an exact plan yet.

Metadata

Metadata

Labels

RFCRequest for commentenhancementNew feature or requestmajor-taskA significant amount of work or conceptual task.work-started

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions