Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ tokio = { version = "1", features = ["full"] }
# sqlite
lazy_static = "1.4"
rusqlite = { version = "0.31.0", features = ["bundled", "functions"] }
rusqlite_migration = "1.2.0"

clap = { version = "4.5", features = ["derive", "env"] }
hex = "0.4"
Expand Down
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,14 +153,15 @@ smaller build and test prerequisites as well.

At any point, run:
```bash
just doctor # build and pre-commit-check readiness
just doctor-e2e # machine images, devnet, and E2E state
just doctor # build/check readiness, including echo and yield images
just doctor-e2e # full E2E images, devnet, and E2E state
just doctor-all # both scopes
```
Each command prints the fix for anything missing. Keeping E2E artifacts out of
the base doctor prevents an otherwise build-ready checkout from appearing
permanently unhealthy. `just --list` shows every available recipe, and
`just check` is the pre-commit gate.
the base doctor, except for the echo/yield images used by standard Rust tests,
prevents an otherwise check-ready checkout from appearing permanently
unhealthy. `just --list` shows every available recipe, and `just check` is the
pre-commit gate.

### Running Examples

Expand Down
36 changes: 16 additions & 20 deletions cartesi-rollups/contracts/src/DaveConsensus.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import {ERC165} from "@openzeppelin-contracts-5.2.0/utils/introspection/ERC165.s
import {IERC165} from "@openzeppelin-contracts-5.2.0/utils/introspection/IERC165.sol";
import {BitMaps} from "@openzeppelin-contracts-5.2.0/utils/structs/BitMaps.sol";

import {MachineValidityProof} from "cartesi-rollups-contracts-3.0.0/src/common/MachineValidityProof.sol";
import {IOutputsMerkleRootValidator} from "cartesi-rollups-contracts-3.0.0/src/consensus/IOutputsMerkleRootValidator.sol";
import {ApplicationChecker} from "cartesi-rollups-contracts-3.0.0/src/dapp/ApplicationChecker.sol";
import {IInputBox} from "cartesi-rollups-contracts-3.0.0/src/inputs/IInputBox.sol";
import {LibBinaryMerkleTree} from "cartesi-rollups-contracts-3.0.0/src/library/LibBinaryMerkleTree.sol";
import {LibKeccak256} from "cartesi-rollups-contracts-3.0.0/src/library/LibKeccak256.sol";
import {LibMachineValidityProof} from "cartesi-rollups-contracts-3.0.0/src/library/LibMachineValidityProof.sol";
import {LibMath} from "cartesi-rollups-contracts-3.0.0/src/library/LibMath.sol";

import {IDataProvider} from "prt-contracts/IDataProvider.sol";
Expand All @@ -21,7 +23,6 @@ import {ITournamentFactory} from "prt-contracts/ITournamentFactory.sol";
import {Machine} from "prt-contracts/types/Machine.sol";
import {Tree} from "prt-contracts/types/Tree.sol";

import {EmulatorConstants} from "step/src/EmulatorConstants.sol";
import {Memory} from "step/src/Memory.sol";

import {IDaveConsensus} from "./IDaveConsensus.sol";
Expand All @@ -30,7 +31,7 @@ contract DaveConsensus is IDaveConsensus, ERC165, ApplicationChecker {
using LibMath for uint256;
using BitMaps for BitMaps.BitMap;
using LibBinaryMerkleTree for bytes;
using LibBinaryMerkleTree for bytes32[];
using LibMachineValidityProof for MachineValidityProof;

/// @notice The input box contract
IInputBox immutable _INPUT_BOX;
Expand Down Expand Up @@ -156,7 +157,7 @@ contract DaveConsensus is IDaveConsensus, ERC165, ApplicationChecker {
(isFinished, winnerCommitment, winnerPostEpochMachineStateHash) = _tournamentResult(_tournament);
}

function stageTournamentResult(uint256 epochNumber, bytes32 outputsMerkleRoot, bytes32[] calldata proof)
function stageTournamentResult(uint256 epochNumber, MachineValidityProof calldata proof)
external
override
notForeclosed(_APP_CONTRACT)
Expand All @@ -171,8 +172,8 @@ contract DaveConsensus is IDaveConsensus, ERC165, ApplicationChecker {
(bool isFinished,, Machine.Hash finalMachineStateHash) = _tournamentResult(_tournament);
require(isFinished, TournamentNotFinishedYet());

// Check outputs Merkle root
_validateOutputTree(finalMachineStateHash, outputsMerkleRoot, proof);
// Validate post-epoch machine state and prove outputs Merkle root
bytes32 outputsMerkleRoot = _validateMachine(finalMachineStateHash, proof);

// Stage tournament result, and store the current block number for
// later checking whether the claim staging period has elapsed.
Expand Down Expand Up @@ -442,21 +443,16 @@ contract DaveConsensus is IDaveConsensus, ERC165, ApplicationChecker {
}
}

function _validateOutputTree(
Machine.Hash finalMachineStateHash,
bytes32 outputsMerkleRoot,
bytes32[] calldata proof
) internal pure {
bytes32 machineStateHash = Machine.Hash.unwrap(finalMachineStateHash);

require(proof.length == Memory.LOG2_MAX_SIZE, InvalidOutputsMerkleRootProofSize(proof.length));
bytes32 allegedStateHash = proof.merkleRootAfterReplacement(
EmulatorConstants.AR_CMIO_TX_BUFFER_START >> EmulatorConstants.HASH_TREE_LOG2_WORD_SIZE,
keccak256(abi.encode(outputsMerkleRoot)),
LibKeccak256.hashPair
);

require(machineStateHash == allegedStateHash, InvalidOutputsMerkleRootProof(finalMachineStateHash));
/// @notice Validates a post-epoch machine given its state hash and a validity proof.
/// @param finalMachineStateHash The post-epoch machine state hash
/// @param proof The machine validity proof
/// @return outputsMerkleRoot The proven outputs Merkle root
function _validateMachine(Machine.Hash finalMachineStateHash, MachineValidityProof calldata proof)
internal
pure
returns (bytes32 outputsMerkleRoot)
{
return proof.validate(Machine.Hash.unwrap(finalMachineStateHash));
}

function _doAllSentriesAgreeWithStagedTournamentResult() internal view returns (bool) {
Expand Down
16 changes: 5 additions & 11 deletions cartesi-rollups/contracts/src/IDaveConsensus.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
pragma solidity ^0.8.30;

import {BinaryMerkleTreeErrors} from "cartesi-rollups-contracts-3.0.0/src/common/BinaryMerkleTreeErrors.sol";
import {MachineValidationErrors} from "cartesi-rollups-contracts-3.0.0/src/common/MachineValidationErrors.sol";
import {MachineValidityProof} from "cartesi-rollups-contracts-3.0.0/src/common/MachineValidityProof.sol";
import {IOutputsMerkleRootValidator} from "cartesi-rollups-contracts-3.0.0/src/consensus/IOutputsMerkleRootValidator.sol";
import {IApplicationChecker} from "cartesi-rollups-contracts-3.0.0/src/dapp/IApplicationChecker.sol";
import {IInputBox} from "cartesi-rollups-contracts-3.0.0/src/inputs/IInputBox.sol";
Expand Down Expand Up @@ -53,6 +55,7 @@ interface IDaveConsensus is
IOutputsMerkleRootValidator,
IApplicationChecker,
BinaryMerkleTreeErrors,
MachineValidationErrors,
ISentryErrors
{
/// @notice Consensus contract was created
Expand Down Expand Up @@ -134,14 +137,6 @@ interface IDaveConsensus is
/// @param fromInputBox Hash of input stored on the input box contract
error InputHashMismatch(bytes32 fromReceivedInput, bytes32 fromInputBox);

/// @notice Supplied output tree proof not consistent with settled machine hash
/// @param settledState Settled machine state hash
error InvalidOutputsMerkleRootProof(Machine.Hash settledState);

/// @notice Supplied output tree proof size is incorrect
/// @param suppliedProofSize Supplied proof size
error InvalidOutputsMerkleRootProofSize(uint256 suppliedProofSize);

/// @notice Application address does not match
/// @param expected Expected application address
/// @param received Received application address
Expand Down Expand Up @@ -285,12 +280,11 @@ interface IDaveConsensus is

/// @notice Stage the tournament result of the current sealed epoch.
/// @param epochNumber The current sealed epoch number (used to avoid race conditions)
/// @param outputsMerkleRoot The post-epoch outputs Merkle root (used to validate outputs)
/// @param proof The bottom-up Merkle proof of the outputs Merkle root in the final machine state
/// @param proof The post-epoch machine validity proof
/// @dev On success, stores the staged result and emits an `EpochStaged`
/// event. Bond recovery is a separate permissionless action on the
/// tournament and cannot affect staging.
function stageTournamentResult(uint256 epochNumber, bytes32 outputsMerkleRoot, bytes32[] calldata proof) external;
function stageTournamentResult(uint256 epochNumber, MachineValidityProof calldata proof) external;

/// @notice As a sentry, claim the post-epoch machine state hash for the current sealed epoch.
/// If all sentries claim the same post-epoch machine state hash as the staged tournament result,
Expand Down
Loading
Loading