diff --git a/.changeset/cold-cities-sit.md b/.changeset/cold-cities-sit.md new file mode 100644 index 00000000..a35fbc14 --- /dev/null +++ b/.changeset/cold-cities-sit.md @@ -0,0 +1,5 @@ +--- +"@cartesi/rollups": major +--- + +Renamed DaveConsensus to OneOfN diff --git a/README.md b/README.md index 7fe00c9b..56a07f04 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ to Ethereum, Arbitrum, Optimism, Base, and their respective testnets. Data Availability of user transactions and Consensus over their order is provided by the `InputBox` contract, while Settlement is provided by the `Application` contract in conjunction with a settlement module. -Currently, we have implemented a quorum-based module (`Quorum`) and our very own fraud proof system (`DaveConsensus`). +Currently, we have implemented a quorum-based module (`Quorum`) and our very own fraud proof system (`Dave`). The Cartesi Rollups Contracts are an integral part of the Cartesi Rollups SDK, and are used by the [Cartesi Rollups Node], the [Cartesi Rollups Explorer], diff --git a/src/consensus/dave/DaveConsensus.sol b/src/consensus/dave/OneOfN.sol similarity index 99% rename from src/consensus/dave/DaveConsensus.sol rename to src/consensus/dave/OneOfN.sol index e5644330..f0631b76 100644 --- a/src/consensus/dave/DaveConsensus.sol +++ b/src/consensus/dave/OneOfN.sol @@ -41,7 +41,7 @@ import {LibKeccak256} from "../../library/LibKeccak256.sol"; /// After it, the next epoch is accumulating inputs. Once this epoch is settled, /// the accumlating epoch is sealed, and a new accumulating epoch is created. /// -contract DaveConsensus is IDataProvider, IOutputsMerkleRootValidator, ERC165 { +contract OneOfN is IDataProvider, IOutputsMerkleRootValidator, ERC165 { using LibBinaryMerkleTree for bytes32[]; /// @notice The input box contract diff --git a/src/consensus/dave/DaveConsensusFactory.sol b/src/consensus/dave/OneOfNFactory.sol similarity index 70% rename from src/consensus/dave/DaveConsensusFactory.sol rename to src/consensus/dave/OneOfNFactory.sol index f381bd37..258d1476 100644 --- a/src/consensus/dave/DaveConsensusFactory.sol +++ b/src/consensus/dave/OneOfNFactory.sol @@ -8,37 +8,37 @@ import {Create2} from "@openzeppelin-contracts-5.2.0/utils/Create2.sol"; import {ITournamentFactory} from "prt-contracts/ITournamentFactory.sol"; import {Machine} from "prt-contracts/types/Machine.sol"; -import {DaveConsensus} from "./DaveConsensus.sol"; +import {OneOfN} from "./OneOfN.sol"; import {IInputBox} from "../../inputs/IInputBox.sol"; /// @title Dave Consensus Factory -/// @notice Allows anyone to reliably deploy a new `DaveConsensus` contract. -contract DaveConsensusFactory { +/// @notice Allows anyone to reliably deploy a new `OneOfN` contract. +contract OneOfNFactory { IInputBox inputBox; ITournamentFactory tournamentFactory; - event DaveConsensusCreated(DaveConsensus daveConsensus); + event OneOfNCreated(OneOfN oneOfN); constructor(IInputBox _inputBox, ITournamentFactory _tournament) { inputBox = _inputBox; tournamentFactory = _tournament; } - function newDaveConsensus( + function newOneOfN( address appContract, Machine.Hash initialMachineStateHash, bytes32 salt - ) external returns (DaveConsensus) { - DaveConsensus daveConsensus = new DaveConsensus{salt: salt}( + ) external returns (OneOfN) { + OneOfN oneOfN = new OneOfN{salt: salt}( inputBox, appContract, tournamentFactory, initialMachineStateHash ); - emit DaveConsensusCreated(daveConsensus); + emit OneOfNCreated(oneOfN); - return daveConsensus; + return oneOfN; } - function calculateDaveConsensusAddress( + function calculateOneOfNAddress( address appContract, Machine.Hash initialMachineStateHash, bytes32 salt @@ -47,7 +47,7 @@ contract DaveConsensusFactory { salt, keccak256( abi.encodePacked( - type(DaveConsensus).creationCode, + type(OneOfN).creationCode, abi.encode( inputBox, appContract, tournamentFactory, initialMachineStateHash ) diff --git a/test/consensus/dave/DaveConsensus.t.sol b/test/consensus/dave/OneOfN.t.sol similarity index 82% rename from test/consensus/dave/DaveConsensus.t.sol rename to test/consensus/dave/OneOfN.t.sol index e89a1a72..e528cb11 100644 --- a/test/consensus/dave/DaveConsensus.t.sol +++ b/test/consensus/dave/OneOfN.t.sol @@ -20,7 +20,7 @@ import {Tree} from "prt-contracts/types/Tree.sol"; import {EmulatorConstants} from "step/src/EmulatorConstants.sol"; import {Memory} from "step/src/Memory.sol"; -import {DaveConsensus} from "src/consensus/dave/DaveConsensus.sol"; +import {OneOfN} from "src/consensus/dave/OneOfN.sol"; import {MockContract} from "../../util/MockContract.sol"; @@ -109,7 +109,7 @@ contract MockTournamentFactory is ITournamentFactory { } } -contract DaveConsensusTest is Test { +contract OneOfNTest is Test { IInputBox _inputBox; MockTournamentFactory _mockTournamentFactory; @@ -142,38 +142,33 @@ contract DaveConsensusTest is Test { _addInputs(appContract, inputCounts[0]); (Machine.Hash state0,,) = _statesAndProofs(outputsMerkleRoots[0]); - address daveConsensusAddress = - _calculateNewDaveConsensus(appContract, state0, salts[0]); + address oneOfNAddress = _calculateNewOneOfN(appContract, state0, salts[0]); _mockTournamentFactory.setSalt(salts[1]); address mockTournamentAddress = _mockTournamentFactory.calculateTournamentAddress( - state0, IDataProvider(daveConsensusAddress) + state0, IDataProvider(oneOfNAddress) ); - vm.expectEmit(daveConsensusAddress); - emit DaveConsensus.ConsensusCreation( - _inputBox, appContract, _mockTournamentFactory - ); + vm.expectEmit(oneOfNAddress); + emit OneOfN.ConsensusCreation(_inputBox, appContract, _mockTournamentFactory); - vm.expectEmit(daveConsensusAddress); - emit DaveConsensus.EpochSealed( + vm.expectEmit(oneOfNAddress); + emit OneOfN.EpochSealed( 0, 0, inputCounts[0], state0, bytes32(0), ITournament(mockTournamentAddress) ); - DaveConsensus daveConsensus = _newDaveConsensus(appContract, state0, salts[0]); + OneOfN oneOfN = _newOneOfN(appContract, state0, salts[0]); - assertEq(address(daveConsensus), daveConsensusAddress); - assertEq(address(daveConsensus.getInputBox()), address(_inputBox)); - assertEq(daveConsensus.getApplicationContract(), appContract); - assertEq( - address(daveConsensus.getTournamentFactory()), address(_mockTournamentFactory) - ); + assertEq(address(oneOfN), oneOfNAddress); + assertEq(address(oneOfN.getInputBox()), address(_inputBox)); + assertEq(oneOfN.getApplicationContract(), appContract); + assertEq(address(oneOfN.getTournamentFactory()), address(_mockTournamentFactory)); { bool isFinished; uint256 epochNumber; - (isFinished, epochNumber,) = daveConsensus.canSettle(); + (isFinished, epochNumber,) = oneOfN.canSettle(); assertFalse(isFinished); assertEq(epochNumber, 0); @@ -186,7 +181,7 @@ contract DaveConsensusTest is Test { ITournament tournament; (epochNumber, inputIndexLowerBound, inputIndexUpperBound, tournament) = - daveConsensus.getCurrentSealedEpoch(); + oneOfN.getCurrentSealedEpoch(); assertEq(epochNumber, 0); assertEq(inputIndexLowerBound, 0); @@ -205,7 +200,7 @@ contract DaveConsensusTest is Test { Machine.Hash.unwrap(mockTournament.getInitialState()), Machine.Hash.unwrap(state0) ); - assertEq(address(mockTournament.getProvider()), address(daveConsensus)); + assertEq(address(mockTournament.getProvider()), address(oneOfN)); { (bool isFinished,,) = mockTournament.arbitrationResult(); @@ -237,7 +232,7 @@ contract DaveConsensusTest is Test { bool isFinished; uint256 epochNumber; - (isFinished, epochNumber,) = daveConsensus.canSettle(); + (isFinished, epochNumber,) = oneOfN.canSettle(); assertTrue(isFinished); assertEq(epochNumber, 0); @@ -249,11 +244,11 @@ contract DaveConsensusTest is Test { _mockTournamentFactory.setSalt(salts[2]); mockTournamentAddress = _mockTournamentFactory.calculateTournamentAddress( - state1, IDataProvider(daveConsensusAddress) + state1, IDataProvider(oneOfNAddress) ); - vm.expectEmit(daveConsensusAddress); - emit DaveConsensus.EpochSealed( + vm.expectEmit(oneOfNAddress); + emit OneOfN.EpochSealed( 1, inputCounts[0], inputCounts[0] + inputCounts[1], @@ -262,13 +257,13 @@ contract DaveConsensusTest is Test { ITournament(mockTournamentAddress) ); - daveConsensus.settle(0, leaf1, proof1); + oneOfN.settle(0, leaf1, proof1); { bool isFinished; uint256 epochNumber; - (isFinished, epochNumber,) = daveConsensus.canSettle(); + (isFinished, epochNumber,) = oneOfN.canSettle(); assertFalse(isFinished); assertEq(epochNumber, 1); @@ -281,7 +276,7 @@ contract DaveConsensusTest is Test { ITournament tournament; (epochNumber, inputIndexLowerBound, inputIndexUpperBound, tournament) = - daveConsensus.getCurrentSealedEpoch(); + oneOfN.getCurrentSealedEpoch(); assertEq(epochNumber, 1); assertEq(inputIndexLowerBound, inputCounts[0]); @@ -304,7 +299,7 @@ contract DaveConsensusTest is Test { Machine.Hash.unwrap(mockTournament.getInitialState()), Machine.Hash.unwrap(state1) ); - assertEq(address(mockTournament.getProvider()), address(daveConsensus)); + assertEq(address(mockTournament.getProvider()), address(oneOfN)); { (bool isFinished,,) = mockTournament.arbitrationResult(); @@ -350,19 +345,19 @@ contract DaveConsensusTest is Test { _mockTournamentFactory.setSalt(salts[0]); - DaveConsensus daveConsensus = _newDaveConsensus(appContract, states[0], salts[1]); + OneOfN oneOfN = _newOneOfN(appContract, states[0], salts[1]); _addInputs(appContract, inputCounts[1]); vm.expectRevert( abi.encodeWithSelector( - DaveConsensus.IncorrectEpochNumber.selector, wrongEpochNumber, 0 + OneOfN.IncorrectEpochNumber.selector, wrongEpochNumber, 0 ) ); - daveConsensus.settle(wrongEpochNumber, bytes32(0), new bytes32[](0)); + oneOfN.settle(wrongEpochNumber, bytes32(0), new bytes32[](0)); - vm.expectRevert(DaveConsensus.TournamentNotFinishedYet.selector); - daveConsensus.settle(0, bytes32(0), new bytes32[](0)); + vm.expectRevert(OneOfN.TournamentNotFinishedYet.selector); + oneOfN.settle(0, bytes32(0), new bytes32[](0)); } function testProvideMerkleRootOfInput( @@ -378,14 +373,12 @@ contract DaveConsensusTest is Test { _mockTournamentFactory.setSalt(salts[0]); - DaveConsensus daveConsensus = - _newDaveConsensus(appContract, initialState, salts[1]); + OneOfN oneOfN = _newOneOfN(appContract, initialState, salts[1]); if (payloads.length > 0) { inputIndexWithinBounds = bound(inputIndexWithinBounds, 0, payloads.length - 1); - bytes32 root = daveConsensus.provideMerkleRootOfInput( - inputIndexWithinBounds, new bytes(0) - ); + bytes32 root = + oneOfN.provideMerkleRootOfInput(inputIndexWithinBounds, new bytes(0)); assertEq( root, _inputBox.getInputMerkleRoot(appContract, inputIndexWithinBounds) ); @@ -394,9 +387,8 @@ contract DaveConsensusTest is Test { { inputIndexOutsideBounds = bound(inputIndexOutsideBounds, payloads.length, type(uint256).max); - bytes32 root = daveConsensus.provideMerkleRootOfInput( - inputIndexOutsideBounds, new bytes(0) - ); + bytes32 root = + oneOfN.provideMerkleRootOfInput(inputIndexOutsideBounds, new bytes(0)); assertEq(root, bytes32(0)); } } @@ -413,7 +405,7 @@ contract DaveConsensusTest is Test { } } - function _calculateNewDaveConsensus( + function _calculateNewOneOfN( address appContract, Machine.Hash initialState, bytes32 salt @@ -422,7 +414,7 @@ contract DaveConsensusTest is Test { salt, keccak256( abi.encodePacked( - type(DaveConsensus).creationCode, + type(OneOfN).creationCode, abi.encode( _inputBox, appContract, _mockTournamentFactory, initialState ) @@ -431,12 +423,11 @@ contract DaveConsensusTest is Test { ); } - function _newDaveConsensus( - address appContract, - Machine.Hash initialState, - bytes32 salt - ) internal returns (DaveConsensus) { - return new DaveConsensus{salt: salt}( + function _newOneOfN(address appContract, Machine.Hash initialState, bytes32 salt) + internal + returns (OneOfN) + { + return new OneOfN{salt: salt}( _inputBox, appContract, _mockTournamentFactory, initialState ); } diff --git a/test/consensus/dave/DaveConsensusFactory.t.sol b/test/consensus/dave/OneOfNFactory.t.sol similarity index 69% rename from test/consensus/dave/DaveConsensusFactory.t.sol rename to test/consensus/dave/OneOfNFactory.t.sol index 18083cd5..38d5ed0c 100644 --- a/test/consensus/dave/DaveConsensusFactory.t.sol +++ b/test/consensus/dave/OneOfNFactory.t.sol @@ -10,8 +10,8 @@ import {Create2} from "@openzeppelin-contracts-5.2.0/utils/Create2.sol"; import {IInputBox} from "src/inputs/IInputBox.sol"; import {InputBox} from "src/inputs/InputBox.sol"; -import {DaveConsensusFactory} from "src/consensus/dave/DaveConsensusFactory.sol"; -import {DaveConsensus} from "src/consensus/dave/DaveConsensus.sol"; +import {OneOfNFactory} from "src/consensus/dave/OneOfNFactory.sol"; +import {OneOfN} from "src/consensus/dave/OneOfN.sol"; import {IDataProvider} from "prt-contracts/IDataProvider.sol"; import {ITournamentFactory} from "prt-contracts/ITournamentFactory.sol"; @@ -37,8 +37,8 @@ contract MockTournamentFactory is ITournamentFactory { } } -contract DaveConsensusFactoryTest is Test { - DaveConsensusFactory _factory; +contract OneOfNFactoryTest is Test { + OneOfNFactory _factory; InputBox _inputBox; MockTournamentFactory _tournamentFactory; Machine.Hash _initialMachineStateHash; @@ -46,20 +46,19 @@ contract DaveConsensusFactoryTest is Test { function setUp() public { _inputBox = new InputBox(); _tournamentFactory = new MockTournamentFactory(); - _factory = new DaveConsensusFactory(_inputBox, _tournamentFactory); + _factory = new OneOfNFactory(_inputBox, _tournamentFactory); _initialMachineStateHash = Machine.Hash.wrap(0x0); } - function testNewDaveConsensusDeterministic( + function testNewOneOfNDeterministic( address _tournamentAddress, uint256 numberOfInputs, bytes32 salt ) public { address appContract = address(new MockContract()); - address precalculatedAddress = _factory.calculateDaveConsensusAddress( - appContract, _initialMachineStateHash, salt - ); + address precalculatedAddress = + _factory.calculateOneOfNAddress(appContract, _initialMachineStateHash, salt); vm.recordLogs(); @@ -68,41 +67,37 @@ contract DaveConsensusFactoryTest is Test { for (uint256 i = 0; i < numberOfInputs; ++i) { _inputBox.addInput(appContract, new bytes(i)); } - DaveConsensus daveConsensus = - _factory.newDaveConsensus(appContract, _initialMachineStateHash, salt); + OneOfN oneOfN = _factory.newOneOfN(appContract, _initialMachineStateHash, salt); - _testNewDaveConsensusAux(daveConsensus, _tournamentAddress, numberOfInputs); + _testNewOneOfNAux(oneOfN, _tournamentAddress, numberOfInputs); - assertEq(precalculatedAddress, address(daveConsensus)); + assertEq(precalculatedAddress, address(oneOfN)); // Ensure the address remains the same when recalculated - precalculatedAddress = _factory.calculateDaveConsensusAddress( - appContract, _initialMachineStateHash, salt - ); - assertEq(precalculatedAddress, address(daveConsensus)); + precalculatedAddress = + _factory.calculateOneOfNAddress(appContract, _initialMachineStateHash, salt); + assertEq(precalculatedAddress, address(oneOfN)); // Cannot deploy the same contract twice with the same salt vm.expectRevert(); - _factory.newDaveConsensus(appContract, _initialMachineStateHash, salt); + _factory.newOneOfN(appContract, _initialMachineStateHash, salt); } - function _testNewDaveConsensusAux( - DaveConsensus daveConsensus, - address fuzzAddress, - uint256 nInputs - ) internal { + function _testNewOneOfNAux(OneOfN oneOfN, address fuzzAddress, uint256 nInputs) + internal + { Vm.Log[] memory entries = vm.getRecordedLogs(); uint256 numOfConsensusCreated; for (uint256 i; i < entries.length; ++i) { Vm.Log memory entry = entries[i]; - if (entry.topics[0] == DaveConsensusFactory.DaveConsensusCreated.selector) { + if (entry.topics[0] == OneOfNFactory.OneOfNCreated.selector) { ++numOfConsensusCreated; address emittedAddress = abi.decode(entry.data, (address)); - assertEq(emittedAddress, address(daveConsensus)); + assertEq(emittedAddress, address(oneOfN)); } - if (entry.topics[0] == DaveConsensus.EpochSealed.selector) { + if (entry.topics[0] == OneOfN.EpochSealed.selector) { ( , uint256 inputIndexLowerBound,