-
Notifications
You must be signed in to change notification settings - Fork 15
Description
We want to build a STProver that has few properties:
- Be Tree-agnostic, as long as the tree implementation has a checkMembership() and computeRoot() functionality
- Be able to process multiple batches of connected ST batches
This means that we want to encode the applying of a set of ST-batches, while being able to mark any batch on whether it should progress the state root or not. The output of this Prover will be a to stateRoot - Batches and their contents have to be assertable easily.
- (not sure if that is needed - might be for merging) There should be a single assertable hash with a list of all applied STs, that can be asserted either in the blockProof/settlement/etc
Since we can make the assumptions that we have some fixed order in which we process ST-batches, we can safely encode the batches themself in a hashlist.
The new ST Prover can be imagined as two paths running independently and only at the end merging together and proving their equality.
The first path is the emitting part, where there is a set of circuits that run in a fixed order, which emit state transitions incrementally. In our case this would be Runtimes via the State abstraction and the Protocol + Block Producing circuits via their hooks.
Each part of the execution emits a independent set of STs (called a Batch)
Setting the indicator to
The set of all Batches will continously aggregated into a hash list based commitment as { stsHash, applied } where stsHash is itself a hash list commitment of all STs in that batch.
The second path is the state modification part of the circuits, in our case the STProver. It will take a set of Batches and a beginning state
The algorithm by which it does this is fairly straight forward.
Define the state of the algorithm as a struct of: { currentBatch: { stsHash: Field, stagedRoot: Field }, batchListHash: Field, finalizedRoot: Field }
First, the set of batches { sts: ST[], applied: Bool }[] will be flattened trivially into { st: ST, type: "continue" | "closeAndApply" | "closeAndThrowAway" }[]
Then, for each of those entries:
- Apply the current ST onto the staged root and append the ST to the stsHash
- If
type == "closeAndApply":- Add the currentBatch to the batchListHash
- set finalizedRoot to stagedRoot
- Reset currentBatch
- If
type == "closeAndThrowAway":- Add the currentBatch to the batchListHash
- Reset current batch
Notice that for closeAndThrowAway, we don't update the finalizedRoot, but instead throw away the result. This ensures that all preconditions of the STs are still checked, but no updated are applied.
Merging the two pipeline paths:
We have two paths in our proving pipeline: One that emits the STs, and one that takes STs and applies them to the tree.
Those are now very much independent, but we have to make sure that both path worked with the same STs.
It makes sense to choose a very long interval in which the two paths run independently, because it improves the proving efficiency. When choosing to merge, two things have to be enforced:
- Assert that the
batchListHashof both paths match - The new output is set to the ST-path's finalizedRoot output
When this happens at any point in the proof chain, we assert the validity, completeness and correctness of the STs and the equality of both paths.
Example:
In our example, we start at stateroot
A the emitted batch list looks like this:
The corresponding steps in the ST Prover would look like
As we can see, the third batch, is based off
Metadata
Metadata
Assignees
Labels
Type
Projects
Status