L0 State Channel - snapshots

Idea

tbc

Implementation

Step structure

The input for the state channel is a stream of blocks. It is computed by an initial pipeline to create a final edge of blocks.

The input for the Cell is an L0Edge with checkpoint blocks.

case class L0Edge(blocks: Set[L1Block]) extends Ω

The output of the Cell is a Snapshot class holding all the blocks provided in the L0Edge.

case class Snapshot(blocks: Set[L1Block]) extends Ω

Pipeline

This is for now the most complex part of an L0 implementation. The idea behind this pipeline is converting an initial stream of blocks into the final edge that can be consumed by the Cell. Stream of blocks is unordered, so the pipeline must aggregate blocks within height ranges and push the Edge when the snapshot condition is met.

Snapshot condition is a formula allowing the pipeline to emit an edge for the next snapshot: tip - tipDelay >= lastEmittedHeight + heightInterval, where tip is a minimum height of all parents used to create blocks, tipDelay is the initial delay before creating the very first snapshot, lastEmittedHeight is a height of the previous snapshot and heightInterval is the range of snapshot.

The initial pipeline can be reduced to the following pseudocode which works as a more complex scan operator:

  case Some((Left(tip), tail)) if tip - tipDelay >= lastEmittedHeight + heightInterval =>
    // get cached blocks and output L0Edge with these blocks

  case Some((Left(tip), tail)) =>
    // increment minimum tip height

  case Some((Right(block), tail)) =>
    // add block to cache under its height 

Inner Algebra and Coalgebra

Algebra reacts on SnapshotEnd(blocks) class and folds all the blocks to the single Snapshot class. It also reacts on L0Error class to produce a CellError class.

Coalgebra takes CreateSnapshot(edge) where the edge is a Set of blocks prepared in the initial pipeline and produces SnapshotEnd class.

StackF Algebra and Coalgebra

When the inner algebra produces a Snapshot or L0Error, it must end the computation, so here is the conversion to Done(result) class. For every other case it executes the inner hylomorphism over and over again.