cartesi / rollups-node

Reference implementation of the Cartesi Rollups Node
Apache License 2.0
20 stars 63 forks source link

Create the new Validator component #359

Closed torives closed 5 months ago

torives commented 6 months ago

📚 Context

The server-manager, developed by the Machine Unit, is a central component in the node design, as it's responsible for handling critical tasks such as interfacing with the Cartesi Machine. For a long time, there were talks of transferring server-manager's ownership to the Node Unit, and this shared vision finally came to be due to the output unification effort.

Since server-manager is a huge C++ project, to better adapt it to the architecture envisioned for the 2.0 release, it will be rewritten as two separate components: Machine Runner (#258) and Validator. Machine Runner will be the new interface with the Cartesi Machine and the Validator will handle epochs, claims, and proofs.

✔️ Solution

Create a new sub-package of node called validator with three sequential tasks: finalize epochs, generate proofs, and create claims.

  1. Finalize epochs Epochs will be simplified:
    • Epoch length will now be determined in terms of blocks instead of seconds, thus changing the node's CARTESI_EPOCH_DURATION parameter. The new default value will be 7200 blocks, equivalent to a day in a chain that generates new blocks after 12s.
    • If there were no inputs within this block interval, the epoch will be finished but no claim will be generated as there's nothing to prove.
  2. Generate proofs After an epoch is finished, it must generate the output proofs and update the outputs Merkle tree in the database accordingly.
  3. Create claims After the proofs are generated, it will create the epoch's claim, although it won't be responsible for sending it: that will still be the authority-claimer's job. Since it reads claims from Redis, it will be necessary to write the claims to Redis. And since we will eventually remove both Redis and the authority-claimer the goal is to create a second, temporary component with the single goal of watching the database for new claims and sending them to Redis. Then, when the time comes to remove the authority-claimer we will only need to delete this smaller component instead of altering the validator's code.

📈 Subtasks

torives commented 6 months ago

After an initial discussion with the @cartesi/node-unit, we reached a consensus around the following database schema: Rollups Node 2 0 - Database2 This might still change though, so it might be a good idea to check the original and more up-to-date diagram here.

torives commented 6 months ago

Here is also a draft of a to-be-implemented API for the Validator to interact with the node's database:

type ValidatorRepository interface {
    // GetMostRecentBlock returns the number of the last finalized block
    // processed by InputReader
    GetMostRecentBlock(ctx context.Context) (uint64, error)
    // GetCurrentEpoch returns the current epoch
    GetCurrentEpoch(ctx context.Context) (*Epoch, error)
    // GetMachineStateHash returns the hash of the state of the Cartesi Machine after processing
    // the input at `inputIndex`
    GetMachineStateHash(ctx context.Context, inputIndex uint64) (hexutil.Bytes, error)
    // GetAllOutputsFromProcessedInputs returns all outputs produced by inputs
    // sent between `startBlock` and `endBlock` (inclusive).
    // If one or more inputs are still unprocessed,
    // it waits for its status to change until it times out
    GetAllOutputsFromProcessedInputs(
        ctx context.Context,
        startBlock uint64,
        endBlock uint64,
        timeout time.Duration,
    ) ([]Output, error)
    // InitConfigTransaction performs a database transaction
    // containing two operations:
    //
    // 1. Inserts a new Epoch, starting at `inputBoxDeploymentBlock` and
    // ending at `inputBoxDeploymentBlock` + `epochDuration`
    //
    // 2. Updates the current epoch to the newly created Epoch
    //
    // This should only be called once to set up the first Epoch in the database.
    // All subsequent calls will do nothing or, if the parameters do not match
    // the values already stored, it will return an `InvalidNodeState` error
    SetupFirstEpochTransaction(
        ctx context.Context,
        inputBoxDeploymentBlock uint64,
        epochDuration uint64,
    ) error
    // FinishEmptyEpochTransaction performs a database transaction
    // containing two operations:
    //
    //  1. Inserts a new Epoch starting at `nextEpochStartBlock` and ending at
    //  `nextEpochStartBlock` + `epochDuration`
    //
    //  2. Updates the current epoch to the newly inserted one
    FinishEmptyEpochTransaction(ctx context.Context, nextEpochStartBlock uint64) error
    // FinishEpochTransaction performs a database transaction
    // containing three operations:
    //
    //  1. Inserts a new Epoch
    //
    //  2. Updates the current epoch to the newly inserted one
    //
    //  3. Inserts a new claim in a single transaction
    FinishEpochTransaction(ctx context.Context, nextEpochStartBlock uint64, claim *Claim) error
}
torives commented 5 months ago

The Validator tasks will now be tracked by #375