IConsensus
Inherits: IOutputsMerkleRootValidator, IApplicationChecker, IVersionGetter, MachineValidationErrors
This interface defines functions for submitting and accepting claims about
the state of multiple Cartesi Rollups applications with a single fixed epoch length.
Each application has its own stream of inputs, which is split into epochs. The index
of the epoch of an input is determined by the integer division of the number of the
base-layer block in which the input was added by the epoch length (see
getEpochLength function).
After every epoch, each validator can submit a claim about the post-epoch state of
the application (summarized by a machine Merkle root), while also proving the set of
all outputs ever emitted by the application up until that point (summarized by an
outputs Merkle root, which is written at a known address in the machine memory, and
proved on-chain through a Merkle proof). Naturally, some epochs might be empty (i.e.
they contain no input), in which case the state of the application remains unchanged.
Validators can save on base-layer fees by not submitting claims for empty epochs.
If a claim meets the staging criteria of the consensus model, the claim is staged.
The criteria for a claim to be staged is outside the scope of this interface, but
for example, a claim may be staged if it was...
- submitted by an authority or;
- submitted by the majority of a quorum or;
- submitted and not proven wrong after some period of time or;
- submitted and proven correct through an on-chain tournament.
When a claim is staged, its effects are not instant. Validators must wait for the
claim staging period (see
getClaimStagingPeriodfunction) to elapse before it can be accepted by the consensus. This delay serves as a layer of protection against malicious validators, private-key leakage, smart-contract bugs, and other issues. If a malicious claim is ever staged, the application guardian should have enough time to foreclose the application, preventing the claim from ever being accepted, and allowing users to withdraw their funds from the last-finalized machine Merkle root. If the claim staging period is elapsed, and the application was not foreclosed, the claim can be finally accepted, and any outputs generated during that epoch can now be validated on-chain.
Functions
submitClaim
Submit a claim to the consensus.
MUST fire a ClaimSubmitted event.
MAY fire a ClaimStaged event, if the staging criteria is met.
function submitClaim(
address appContract,
uint256 lastProcessedBlockNumber,
bytes32 machineMerkleRoot,
MachineValidityProof calldata proof
) external;
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
lastProcessedBlockNumber | uint256 | The number of the last processed block |
machineMerkleRoot | bytes32 | The machine Merkle root |
proof | MachineValidityProof | The machine validity proof |
acceptClaim
Accept a staged claim whose staging period has elapsed.
MUST fire a ClaimAccepted event.
function acceptClaim(
address appContract,
uint256 lastProcessedBlockNumber,
bytes32 machineMerkleRoot
) external;
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
lastProcessedBlockNumber | uint256 | The number of the last processed block |
machineMerkleRoot | bytes32 | The machine Merkle root |
getEpochLength
Get the epoch length, in number of base-layer blocks.
The epoch number of a block is defined as the integer division of the block number by the epoch length.
function getEpochLength() external view returns (uint256);
getClaimStagingPeriod
Get the number of base-layer blocks after which a staged claim can be accepted.
function getClaimStagingPeriod() external view returns (uint256);
getNumberOfAcceptedClaims
Get the number of claims accepted by the consensus regarding a specific app.
function getNumberOfAcceptedClaims(address appContract)
external
view
returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
getNumberOfStagedClaims
Get the number of claims staged by the consensus regarding a specific app.
function getNumberOfStagedClaims(address appContract) external view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
getNumberOfSubmittedClaims
Get the number of claims submitted to the consensus regarding a specific app.
function getNumberOfSubmittedClaims(address appContract)
external
view
returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
getClaim
Get information about a claim.
function getClaim(
address appContract,
uint256 lastProcessedBlockNumber,
bytes32 machineMerkleRoot
) external view returns (Claim memory claim);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
lastProcessedBlockNumber | uint256 | The number of the last processed block |
machineMerkleRoot | bytes32 | The machine Merkle root |
Returns
| Name | Type | Description |
|---|---|---|
claim | Claim | Information about the claim |
Events
ClaimSubmitted
MUST trigger when a claim is submitted.
event ClaimSubmitted(
address indexed submitter,
address indexed appContract,
uint256 lastProcessedBlockNumber,
bytes32 outputsMerkleRoot,
bytes32 machineMerkleRoot
);
Parameters
| Name | Type | Description |
|---|---|---|
submitter | address | The submitter address |
appContract | address | The application contract address |
lastProcessedBlockNumber | uint256 | The number of the last processed block |
outputsMerkleRoot | bytes32 | The outputs Merkle root |
machineMerkleRoot | bytes32 | The machine Merkle root |
ClaimStaged
MUST trigger when a claim is staged.
For each application and lastProcessedBlockNumber, there can be at most one staged claim.
event ClaimStaged(
address indexed appContract,
uint256 lastProcessedBlockNumber,
bytes32 outputsMerkleRoot,
bytes32 machineMerkleRoot
);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
lastProcessedBlockNumber | uint256 | The number of the last processed block |
outputsMerkleRoot | bytes32 | The outputs Merkle root |
machineMerkleRoot | bytes32 | The machine Merkle root |
ClaimAccepted
MUST trigger when a claim is accepted.
For each application and lastProcessedBlockNumber, there can be at most one accepted claim.
event ClaimAccepted(
address indexed appContract,
uint256 lastProcessedBlockNumber,
bytes32 outputsMerkleRoot,
bytes32 machineMerkleRoot
);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
lastProcessedBlockNumber | uint256 | The number of the last processed block |
outputsMerkleRoot | bytes32 | The outputs Merkle root |
machineMerkleRoot | bytes32 | The machine Merkle root |
Errors
NotEpochFinalBlock
The claim contains the number of a block that is not at the end of an epoch (its modulo epoch length is not epoch length - 1).
error NotEpochFinalBlock(uint256 lastProcessedBlockNumber, uint256 epochLength);
Parameters
| Name | Type | Description |
|---|---|---|
lastProcessedBlockNumber | uint256 | The number of the last processed block |
epochLength | uint256 | The epoch length |
NotPastBlock
The claim contains the number of a block in the future (it is greater or equal to the current block number).
error NotPastBlock(uint256 lastProcessedBlockNumber, uint256 currentBlockNumber);
Parameters
| Name | Type | Description |
|---|---|---|
lastProcessedBlockNumber | uint256 | The number of the last processed block |
currentBlockNumber | uint256 | The number of the current block |
NotFirstClaim
A claim for that application and epoch was already submitted by the validator.
error NotFirstClaim(address appContract, uint256 lastProcessedBlockNumber);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
lastProcessedBlockNumber | uint256 | The number of the last processed block |
ClaimNotStaged
The claim was not staged and therefore cannot be accepted.
error ClaimNotStaged(
address appContract,
uint256 lastProcessedBlockNumber,
bytes32 machineMerkleRoot,
ClaimStatus claimStatus
);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
lastProcessedBlockNumber | uint256 | The number of the last processed block |
machineMerkleRoot | bytes32 | The machine Merkle root |
claimStatus | ClaimStatus | The status of the claim |
ClaimStagingPeriodNotOverYet
The claim was staged but its staging period is not over yet.
error ClaimStagingPeriodNotOverYet(
address appContract,
uint256 lastProcessedBlockNumber,
bytes32 machineMerkleRoot,
uint256 numberOfBlocksAfterStaging,
uint256 claimStagingPeriod
);
Parameters
| Name | Type | Description |
|---|---|---|
appContract | address | The application contract address |
lastProcessedBlockNumber | uint256 | The number of the last processed block |
machineMerkleRoot | bytes32 | The machine Merkle root |
numberOfBlocksAfterStaging | uint256 | The number of blocks since the claim was staged |
claimStagingPeriod | uint256 | The claim staging period, in number of blocks |
Structs
Claim
Information about a claim.
The values of the fields stagingBlockNumber and stagedOutputsMerkleRoot
only have meaning if the claim was staged. Otherwise, they are meaningless.
struct Claim {
ClaimStatus status;
uint256 stagingBlockNumber;
bytes32 stagedOutputsMerkleRoot;
}
Properties
| Name | Type | Description |
|---|---|---|
status | ClaimStatus | The status of the claim |
stagingBlockNumber | uint256 | The number of the block in which the claim was staged |
stagedOutputsMerkleRoot | bytes32 | The outputs Merkle root that was proven on staging |
Enums
ClaimStatus
The status of a claim.
enum ClaimStatus {
UNSTAGED,
STAGED,
ACCEPTED
}
Variants
| Name | Description |
|---|---|
UNSTAGED | The claim was neither staged nor accepted |
STAGED | The claim was staged but not accepted |
ACCEPTED | The claim was staged and accepted |