⚠️ The Cartesi team keeps working internally on the next version of this repository, following its regular development roadmap. Whenever there's a new version ready or important fix, these are published to the public source tree as new releases.
Arbitration D-Lib
ArbitrationLib is the combination of the on-chain protocol and off-chain protocol that work together to resolve any disputes that might occur during the execution of a Cartesi Dapp. The behavior of the off-chain and on-chain code are very similar. The on-chain code is written in Solidity and the off-chain in Rust.
Most of the Solidity contracts in this repository follow the Instantiator design pattern.
Arbitration Test Instantiator
The Arbitration Test contract is a simplified contract that simulates the behavior of a Dapp when two participants disagree with each other. It's inital state, after being instantiated, is Idle. The Challenger requests the state changing to Waiting state and instantiates a compute instance for future computation. Only after the compute ends, the participants can claim the state to be Finished. A working demo and be found at https://github.com/cartesi/demo/.
// These are the possible states and transitions of the contract.
// +---+
// | |
// +---+
// |
// | constructor
// v
// +------+
// | Idle |
// +------+
// |
// | claimWaiting
// v
// +---------+
// | Waiting |
// +---------+
// |
// | claimFinished
// v
// +----------+
// | Finished |
// +----------+
Compute Instantiator
A Compute contract is instantiated with a computation proposal. It's inital state, after being instantiated, is WaitingClaim. There is a deadline, therefore, for the Claimer to submit a result to the proposed computation. After the Claimer submits a final hash for that proposal, there is a period in which the Challenger can either accept or challenge that result.
If the result is accepted we reach a Consensus state. If not, the dispute is resolved through a Verification Game.
The possible states of an instance of this contract are:
// +---+
// | |
// +---+
// |
// | instantiate
// v
// +--------------+ claimVictoryByTime +-----------------------+
// | WaitingClaim |------------------->| ClaimerMisseddeadline |
// +--------------+ +-----------------------+
// |
// | submitClaim
// v
// +---------------------+ confirm +-----------------+
// | WaitingConfirmation |------------>| ConsensusResult |
// +---------------------+ or deadline +-----------------+
// |
// | challenge
// v
// +------------------+ winByVG +---------------+
// | WaitingChallenge |--------------->| ChallengerWon |
// +------------------+ +---------------+
// |
// |
// | winByVG +------------+
// +-------------------------------->| ClaimerWon |
// +------------+
VG Instantiator
The Verification Game Instantiator is responsible for solving the disputes that may arise during the Compute Instantiator execution. It is evoked when a Claimed result gets challenged.
The first step of a Verification Game is finding the divergence point, which is done by the Partition Instantiator contract (detailed in the following section).
If the Partition Instantiator concludes successfully, the VG moves to the MemoryManager phase, in which the Claimer has to fill the MM with the activity log. This phase is also better described in a following section.
After the Memory Manager is filled with the necessary data, VG contract settles the game instantiating a machine and running one step on it.By checking the final hash generated by the step, the VG instantiator can define the winner. The Step transition is further explained in theSolidity Machine Repo.
These are the possible states and transitions of the contract.
//
// +---+
// | |
// +---+
// |
// | instantiate
// v
// +----------------+ winByPartitionTimeout
// +-----------| WaitPartition |------------------------+
// | +----------------+ |
// | | |
// | winByPartitionTimeout | startMachineRunChallenge |
// | v |
// | +-----------------------+ |
// | +---------| WaitMemoryProveValues |---------------+ |
// | | +-----------------------+ | |
// | | | |
// | |claimVictoryByDeadline settleVerificationGame | |
// v v v v
// +--------------------+ +-----------------------+
// | FinishedClaimerWon | | FinishedChallengerWon |
// +--------------------+ +-----------------------+
//
Partition Instantiator
The Partition contract is responsible for the interactions between Alice and Bob while they find the divergence point (the exact step performed during the computation in which they agree with the inital hash but disagree with the final one).
The possible states of an instance of this contract are:
//
// +---+
// | |
// +---+
// |
// | instantiate
// v
// +---------------+ claimVictoryByTimeout +---------------+
// | WaitingHashes |------------------------>| ChallengerWon |
// +---------------+ +---------------+
// | ^
// replyQuery | | makeQuery
// v |
// +--------------+ claimVictoryByTimeout +------------+
// | WaitingQuery |------------------------->| ClaimerWon |
// +--------------+ +------------+
// |
// | presentDivergence
// v
// +-----------------+
// | DivergenceFound |
// +-----------------+
//
MemoryManager Instantiator
When a dispute arises and a machine run challenge begins, the Claimer is responsible to send their off-chain state access log to the MemoryManager instance referent to that Verification Game.
The information sent by them is consumed by the RISC-V Solidity emulator as if the entire state content was available - since the off and on-chain emulators match down to the order in which accesses are logged.
The MemoryManager contract offers the RISC-V Solidity emulator a very simple interface that consists of:
- read - reads a word in a specific address.
- write - writes a word in a specific address.
- finishReplayPhase - signals that the Step has completed.
It also makes sure that all accesses performed by the Step function match the ones provided by the Claimer and are consistent with the Merkle proofs provided by him. If that is not the case, the Claimer loses the dispute.
The possible states of an instance of this contract are:
//
// +---+
// | |
// +---+
// |
// | instantiate
// v
// +---------------+ | proveRead
// | WaitingProofs |----| proveWrite
// +---------------+
// |
// | finishProofPhase
// v
// +----------------+ |read
// | WaitingReplay |----|write
// +----------------+
// |
// | finishReplayPhase
// v
// +----------------+
// | FinishedReplay |
// +----------------+
//
Getting Started - on-chain code
Install
Install dependencies
npm install
Compile contracts with
npm run build
Having a node listening to 8545, you can deploy using
npm run deploy
Run tests
Migrate contracts and prepare testing files ./deploy_development.sh
Run tests ./run_python_tests.sh
Getting Started - off-chain code
Install
Install rust curl https://sh.rustup.rs -sSf | sh
Add cargo to your path in .bashrc
export PATH=$PATH:/home/user/.cargo/bin
Move to compute dir: cd compute
Build project: cargo build
TODO
Use safemath on contracts
Protect against replay attacks
Review if events are appropriate for light client
Contributing
Thank you for your interest in Cartesi! Head over to our Contributing Guidelines for instructions on how to sign our Contributors Agreement and get started with Cartesi!
Please note we have a Code of Conduct, please follow it in all your interactions with the project.
Authors
- Augusto Teixeira
License
Note: This component currently has dependencies that are licensed under the GNU GPL, version 3, and so you should treat this component as a whole as being under the GPL version 3. But all Cartesi-written code in this component is licensed under the Apache License, version 2, or a compatible permissive license, and can be used independently under the Apache v2 license. After this component is rewritten, the entire component will be released under the Apache v2 license. The arbitration d-lib repository and all contributions are licensed under GPL 3. Please review our COPYING file.