Expand description

Filesystem-backed database containing all the information about a chain.

This module handles the persistent storage of the chain on disk.

§Usage

Use the open() function to create a new database or open an existing one. open() returns a DatabaseOpen enum. This enum will contain either a SqliteFullDatabase object, representing an access to the database, or a DatabaseEmpty if the database didn’t exist or is empty. If that is the case, use DatabaseEmpty::initialize in order to populate it and obtain a SqliteFullDatabase.

Use SqliteFullDatabase::insert to insert a new block in the database. The block is assumed to have been successfully verified prior to insertion. An error is returned if this block is already in the database or isn’t a descendant or ancestor of the latest finalized block.

Use SqliteFullDatabase::set_finalized to mark a block already in the database as finalized. Any block that isn’t an ancestor or descendant will be removed. Reverting finalization is not supported.

In order to minimize disk usage, it is not possible to efficiently retrieve the storage items of blocks that are ancestors of the finalized block. When a block is finalized, the storage of its ancestors is lost, and the only way to reconstruct it is to execute all blocks starting from the genesis to the desired one.

§About errors handling

Most of the functions and methods in this module return a Result containing notably an CorruptedError. This kind of errors can happen if the operating system returns an error when accessing the file system, or if the database has been corrupted, for example by the user manually modifying it.

There isn’t much that can be done to properly handle an CorruptedError. The only reasonable solutions are either to stop the program, or to delete the entire database and recreate it.

§Schema

The SQL schema of the database, with explanatory comments, can be found in open.rs.

§About blocking behavior

This implementation uses the SQLite library, which isn’t Rust-asynchronous-compatible. Many functions will, with the help of the operating system, put the current thread to sleep while waiting for an I/O operation to finish. In the context of asynchronous Rust, this is undesirable.

For this reason, you are encouraged to isolate the database in its own threads and never access it directly from an asynchronous context.

Structs§

Enums§

Functions§

  • Opens the database using the given Config.
  • Returns an opaque string representing the version number of the SQLite library this binary is using.