Skip to main content

LeiosDB

LeiosDB stores Leios endorser blocks (EBs) and their transactions. Its SQLite backend keeps them in two files, called partitions:

  • Volatile partition stores fresh EB announcements, bodies and transaction that the node downloads or forges.
  • Immutable partition stores complete EBs (and their closure transactions) that a certificate on the immutable chain refers to.

The EBs and their closures are copied from the volatile to the immutable partition when they become older than k (the Praos security parameter). See also the ImmutableDB glossary entry.

Database schema​

  • ebs has one row for each pair of slot and EB hash that an announcement named; announcements that name the same pair share the row, and its ebBytesSize is the size claimed by the first one written. Thus one EB hash can occur at several slots.
  • ebTxs is the EB body. It has one row for each transaction of the EB, in order. It stores each EB body only once, however many ebs rows name its hash.
  • ebTxBytes stores the transaction bytes of the EB closure, one row for each ebTxs row, with the same key. The EB owns these bytes: a transaction that belongs to two EBs is stored twice (ie duplicated aka denormalized.)

Volatile partition​

The queries join the tables on the EB hash (ebHashBytes) and the transaction offset (txOffset).

  • When an EB body arrives, rows are inserted in ebTxs. In the same transaction, one ebTxBytes row is allocated for each of them: a zero-filled blob of the declared size, with filled = 0. Then missingTxCount is set to the number of unfilled rows.
  • When transactions arrive, they overwrite their rows in place and set filled = 1. A write is dropped if its row does not exist, is already filled, or has a different size. Also, the missingTxCount of every ebs row whose EB has already arrived and references the arriving transactions is decreased by the number of ebTxBytes rows filled for that EB. Note that a tx will decrement the missingTxCount columns only of EBs that referred to that tx with the correct size.
  • The GC sweep phase deletes the ebTxBytes, ebTxs and ebs rows of an EB by its hash: three range deletes.

Indexes:

IndexOnUsed for
idx_ebs_ebHashBytesebs(ebHashBytes)Looking up an EB by hash
idx_ebs_sweepableebs(ebSlot) WHERE status IN (0, 2)The GC mark scan
idx_ebs_markedForGcebs(ebHashBytes) WHERE status = 3The sweeper picking EBs to evict
idx_ebs_pinnedebs(ebSlot) WHERE status = 1The copier picking EBs to copy

Lifecycle of an EB row​

The status column records where an ebs row is in promotion and garbage collection:

Immutable partition​

The copier copies only complete EBs, and GC never removes EBs from this partition. Thus every ebs row has its full body in ebTxs, and every ebTxs row has its filled ebTxBytes row. For the same reason, the immutable partition does not have missingTxCount, status, or any index other than idx_ebs_ebHashBytes.