diff --git a/Cargo.lock b/Cargo.lock index e0d214bc..54007370 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1736,7 +1736,6 @@ dependencies = [ "ruint", "rusqlite", "rusqlite_migration", - "serde", "serde_json", "tempfile", "testcontainers-modules", diff --git a/cartesi-rollups/contracts/foundry.toml b/cartesi-rollups/contracts/foundry.toml index a46bb89a..f0a105ec 100644 --- a/cartesi-rollups/contracts/foundry.toml +++ b/cartesi-rollups/contracts/foundry.toml @@ -8,21 +8,22 @@ via_ir = true allow_paths = ["../../prt/contracts", "../../machine/step"] remappings = [ - "@openzeppelin-contracts-5.2.0/=dependencies/cartesi-rollups-contracts-3.0.0-alpha.6/dependencies/@openzeppelin-contracts-5.2.0/", + "@openzeppelin-contracts-5.2.0/=dependencies/cartesi-rollups-contracts-3.0.0-alpha.9/dependencies/@openzeppelin-contracts-5.2.0/", "@openzeppelin-contracts-5.5.0/=dependencies/@openzeppelin-contracts-5.5.0/", - "cartesi-machine-solidity-step-0.13.0/=dependencies/cartesi-rollups-contracts-3.0.0-alpha.6/dependencies/cartesi-machine-solidity-step-0.13.0/", - "cartesi-rollups-contracts-3.0.0/=dependencies/cartesi-rollups-contracts-3.0.0-alpha.6/", + "cartesi-machine-solidity-step-0.15.0/=dependencies/cartesi-rollups-contracts-3.0.0-alpha.9/dependencies/cartesi-machine-solidity-step-0.15.0/", + "cartesi-rollups-contracts-3.0.0/=dependencies/cartesi-rollups-contracts-3.0.0-alpha.9/", "forge-std-1.9.6/=dependencies/forge-std-1.9.6/", - "prt-contracts/=../../prt/contracts/src/", "prt-contracts-test/=../../prt/contracts/test/", + "prt-contracts/=../../prt/contracts/src/", "step/=../../machine/step/", ] solc_version = "0.8.30" evm_version = "prague" +always_use_create_2_factory = true fs_permissions = [ { access = "read-write", path = "deployments" }, - { access = "read", path = "dependencies/cartesi-rollups-contracts-3.0.0-alpha.6/deployments" }, + { access = "read", path = "dependencies/cartesi-rollups-contracts-3.0.0-alpha.9/deployments" }, { access = "read", path = "../../prt/contracts/deployments" }, ] @@ -32,6 +33,7 @@ recursive_deps = true [fmt] sort_imports = true +single_line_imports = true [lint] exclude_lints = ["incorrect-shift"] @@ -39,4 +41,4 @@ exclude_lints = ["incorrect-shift"] [dependencies] "@openzeppelin-contracts" = "5.5.0" forge-std = "1.9.6" -cartesi-rollups-contracts = "3.0.0-alpha.6" +cartesi-rollups-contracts = "3.0.0-alpha.9" diff --git a/cartesi-rollups/contracts/script/Deployment.s.sol b/cartesi-rollups/contracts/script/Deployment.s.sol index 7de8a6e4..b5e55b02 100644 --- a/cartesi-rollups/contracts/script/Deployment.s.sol +++ b/cartesi-rollups/contracts/script/Deployment.s.sol @@ -10,7 +10,7 @@ import {DaveAppFactory} from "src/DaveAppFactory.sol"; contract DeploymentScript is BaseDeploymentScript { function run() external { _importDeployments("../../prt/contracts"); - _importDeployments("dependencies/cartesi-rollups-contracts-3.0.0-alpha.6"); + _importDeployments("dependencies/cartesi-rollups-contracts-3.0.0-alpha.9"); address inputBox = _loadDeployment(".", "InputBox"); address appFactory = _loadDeployment(".", "ApplicationFactory"); diff --git a/cartesi-rollups/contracts/script/build-devnet.sh b/cartesi-rollups/contracts/script/build-devnet.sh index a56ba5c5..7d94a590 100755 --- a/cartesi-rollups/contracts/script/build-devnet.sh +++ b/cartesi-rollups/contracts/script/build-devnet.sh @@ -6,7 +6,7 @@ cd "${BASH_SOURCE%/*}/.." deployment_complete=0 build_fingerprint=$(../../script/devnet-fingerprint.sh inputs) -base_contracts=dependencies/cartesi-rollups-contracts-3.0.0-alpha.6 +base_contracts=dependencies/cartesi-rollups-contracts-3.0.0-alpha.9 cleanup() { exit_code=$? diff --git a/cartesi-rollups/contracts/script/deploy.sh b/cartesi-rollups/contracts/script/deploy.sh index 843d5f70..7bc0c164 100755 --- a/cartesi-rollups/contracts/script/deploy.sh +++ b/cartesi-rollups/contracts/script/deploy.sh @@ -6,7 +6,7 @@ cd "${BASH_SOURCE%/*}/.." roots=( '../../prt/contracts' - 'dependencies/cartesi-rollups-contracts-3.0.0-alpha.6' + 'dependencies/cartesi-rollups-contracts-3.0.0-alpha.9' '.' ) diff --git a/cartesi-rollups/contracts/soldeer.lock b/cartesi-rollups/contracts/soldeer.lock index 7e7a34fc..f7d87c85 100644 --- a/cartesi-rollups/contracts/soldeer.lock +++ b/cartesi-rollups/contracts/soldeer.lock @@ -7,10 +7,10 @@ integrity = "da8336cf949f0e0667ae8360af849681e3a3e76d7e61e7a86b1a3414a158aeea" [[dependencies]] name = "cartesi-rollups-contracts" -version = "3.0.0-alpha.6" -url = "https://soldeer-revisions.s3.amazonaws.com/cartesi-rollups-contracts/3_0_0-alpha_6_21-05-2026_12:17:44_rollups-contracts.zip" -checksum = "cdfd86f90895ba37e188103e8fb62d6ca8e45a53846ebc63cb7b7af66f18d034" -integrity = "6fd07e7d895795aca4877d1c0f357f19f88adc56e1ff1ff88950900391328969" +version = "3.0.0-alpha.9" +url = "https://soldeer-revisions.s3.amazonaws.com/cartesi-rollups-contracts/3_0_0-alpha_9_19-08-2026_11:52:19_rollups-contracts.zip" +checksum = "c17618f6aa3313ce8e28f043877b8e16695b358ccf0f77ecca19b234718ebf16" +integrity = "f606c1db57d8b6ff0de8a73ec8b7d762e79d3b06959554e748663f03d0b1f588" [[dependencies]] name = "forge-std" diff --git a/cartesi-rollups/contracts/src/DaveAppFactory.sol b/cartesi-rollups/contracts/src/DaveAppFactory.sol index c759905e..050bdbca 100644 --- a/cartesi-rollups/contracts/src/DaveAppFactory.sol +++ b/cartesi-rollups/contracts/src/DaveAppFactory.sol @@ -5,11 +5,8 @@ pragma solidity ^0.8.30; import {Create2} from "@openzeppelin-contracts-5.5.0/utils/Create2.sol"; -import {DataAvailability} from "cartesi-rollups-contracts-3.0.0/src/common/DataAvailability.sol"; import {WithdrawalConfig} from "cartesi-rollups-contracts-3.0.0/src/common/WithdrawalConfig.sol"; -import { - IOutputsMerkleRootValidator -} from "cartesi-rollups-contracts-3.0.0/src/consensus/IOutputsMerkleRootValidator.sol"; +import {IOutputsMerkleRootValidator} from "cartesi-rollups-contracts-3.0.0/src/consensus/IOutputsMerkleRootValidator.sol"; import {IApplication} from "cartesi-rollups-contracts-3.0.0/src/dapp/IApplication.sol"; import {IApplicationFactory} from "cartesi-rollups-contracts-3.0.0/src/dapp/IApplicationFactory.sol"; import {IInputBox} from "cartesi-rollups-contracts-3.0.0/src/inputs/IInputBox.sol"; @@ -64,23 +61,14 @@ contract DaveAppFactory is IDaveAppFactory { ); } - /// @notice Encode the data availability blob for applications that only use the input box as DA. - function _encodeInputBoxDataAvailability() internal view returns (bytes memory) { - return abi.encodeCall(DataAvailability.InputBox, (INPUT_BOX)); - } - /// @notice Instantiate a new application contract owned by the current contract, /// with no outputs Merkle root validator (the zero address), and with the input box - /// as the only data availability source. + /// as the data-availability source. function _newApplication(bytes32 templateHash, WithdrawalConfig calldata withdrawalConfig, bytes32 salt) internal returns (IApplication) { - bytes memory dataAvailability = _encodeInputBoxDataAvailability(); - return - APP_FACTORY.newApplication( - NO_VALIDATOR, address(this), templateHash, dataAvailability, withdrawalConfig, salt - ); + return APP_FACTORY.newApplication(NO_VALIDATOR, address(this), templateHash, INPUT_BOX, withdrawalConfig, salt); } /// @notice Instantiate a new `DaveConsensus` contract. @@ -110,9 +98,8 @@ contract DaveAppFactory is IDaveAppFactory { WithdrawalConfig calldata withdrawalConfig, bytes32 salt ) internal view returns (address) { - bytes memory dataAvailability = _encodeInputBoxDataAvailability(); return APP_FACTORY.calculateApplicationAddress( - NO_VALIDATOR, address(this), templateHash, dataAvailability, withdrawalConfig, salt + NO_VALIDATOR, address(this), templateHash, INPUT_BOX, withdrawalConfig, salt ); } diff --git a/cartesi-rollups/contracts/src/DaveConsensus.sol b/cartesi-rollups/contracts/src/DaveConsensus.sol index 20298bc4..8e325908 100644 --- a/cartesi-rollups/contracts/src/DaveConsensus.sol +++ b/cartesi-rollups/contracts/src/DaveConsensus.sol @@ -7,9 +7,7 @@ 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 { - IOutputsMerkleRootValidator -} from "cartesi-rollups-contracts-3.0.0/src/consensus/IOutputsMerkleRootValidator.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"; @@ -407,6 +405,16 @@ contract DaveConsensus is IDaveConsensus, ERC165, ApplicationChecker { return Machine.Hash.unwrap(_lastFinalizedMachineStateHash); } + function wasInputFinalized(address appContract, uint256 inputIndex, uint256) + external + view + override + onlyValidAppContract(appContract) + returns (bool) + { + return inputIndex < _inputIndexLowerBound; + } + function supportsInterface(bytes4 interfaceId) public view override(IERC165, ERC165) returns (bool) { return interfaceId == type(IDaveConsensus).interfaceId || interfaceId == type(IDataProvider).interfaceId || interfaceId == type(IOutputsMerkleRootValidator).interfaceId || super.supportsInterface(interfaceId); diff --git a/cartesi-rollups/contracts/src/IDaveConsensus.sol b/cartesi-rollups/contracts/src/IDaveConsensus.sol index f6306788..73a91c66 100644 --- a/cartesi-rollups/contracts/src/IDaveConsensus.sol +++ b/cartesi-rollups/contracts/src/IDaveConsensus.sol @@ -4,9 +4,7 @@ pragma solidity ^0.8.30; import {BinaryMerkleTreeErrors} from "cartesi-rollups-contracts-3.0.0/src/common/BinaryMerkleTreeErrors.sol"; -import { - IOutputsMerkleRootValidator -} from "cartesi-rollups-contracts-3.0.0/src/consensus/IOutputsMerkleRootValidator.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"; diff --git a/cartesi-rollups/contracts/test/DaveAppFactory.t.sol b/cartesi-rollups/contracts/test/DaveAppFactory.t.sol index d519ec8f..12abe04c 100644 --- a/cartesi-rollups/contracts/test/DaveAppFactory.t.sol +++ b/cartesi-rollups/contracts/test/DaveAppFactory.t.sol @@ -1,27 +1,22 @@ pragma solidity ^0.8.30; -import {Test} from "forge-std-1.9.6/src/Test.sol"; import {Vm} from "forge-std-1.9.6/src/Vm.sol"; import {Ownable} from "@openzeppelin-contracts-5.2.0/access/Ownable.sol"; import {IERC165} from "@openzeppelin-contracts-5.2.0/utils/introspection/IERC165.sol"; -import {DataAvailability} from "cartesi-rollups-contracts-3.0.0/src/common/DataAvailability.sol"; import {WithdrawalConfig} from "cartesi-rollups-contracts-3.0.0/src/common/WithdrawalConfig.sol"; -import { - IOutputsMerkleRootValidator -} from "cartesi-rollups-contracts-3.0.0/src/consensus/IOutputsMerkleRootValidator.sol"; -import {ApplicationFactory} from "cartesi-rollups-contracts-3.0.0/src/dapp/ApplicationFactory.sol"; +import {IOutputsMerkleRootValidator} from "cartesi-rollups-contracts-3.0.0/src/consensus/IOutputsMerkleRootValidator.sol"; import {IApplication} from "cartesi-rollups-contracts-3.0.0/src/dapp/IApplication.sol"; import {IApplicationChecker} from "cartesi-rollups-contracts-3.0.0/src/dapp/IApplicationChecker.sol"; import {IApplicationFactory} from "cartesi-rollups-contracts-3.0.0/src/dapp/IApplicationFactory.sol"; import {IApplicationFactoryErrors} from "cartesi-rollups-contracts-3.0.0/src/dapp/IApplicationFactoryErrors.sol"; import {IInputBox} from "cartesi-rollups-contracts-3.0.0/src/inputs/IInputBox.sol"; -import {InputBox} from "cartesi-rollups-contracts-3.0.0/src/inputs/InputBox.sol"; import {LibBinaryMerkleTree} from "cartesi-rollups-contracts-3.0.0/src/library/LibBinaryMerkleTree.sol"; import {LibBytes} from "cartesi-rollups-contracts-3.0.0/src/library/LibBytes.sol"; import {LibKeccak256} from "cartesi-rollups-contracts-3.0.0/src/library/LibKeccak256.sol"; import {LibWithdrawalConfig} from "cartesi-rollups-contracts-3.0.0/src/library/LibWithdrawalConfig.sol"; +import {RollupsTest} from "cartesi-rollups-contracts-3.0.0/test/util/RollupsTest.sol"; import {EmulatorConstants} from "step/src/EmulatorConstants.sol"; import {Memory} from "step/src/Memory.sol"; @@ -30,9 +25,7 @@ import {IDataProvider} from "prt-contracts/IDataProvider.sol"; import {IStateTransition} from "prt-contracts/IStateTransition.sol"; import {ITournament} from "prt-contracts/ITournament.sol"; import {ITournamentFactory} from "prt-contracts/ITournamentFactory.sol"; -import { - CanonicalTournamentParametersProvider -} from "prt-contracts/arbitration-config/CanonicalTournamentParametersProvider.sol"; +import {CanonicalTournamentParametersProvider} from "prt-contracts/arbitration-config/CanonicalTournamentParametersProvider.sol"; import {CartesiStateTransition} from "prt-contracts/state-transition/CartesiStateTransition.sol"; import {Tournament} from "prt-contracts/tournament/Tournament.sol"; import {MultiLevelTournamentFactory} from "prt-contracts/tournament/factories/MultiLevelTournamentFactory.sol"; @@ -78,7 +71,7 @@ contract SettlementCallbackReceiver { } } -contract DaveAppFactoryTest is Test { +contract DaveAppFactoryTest is RollupsTest { using LibExternalBinaryKeccak256MerkleTree for bytes32[]; using LibWithdrawalConfig for WithdrawalConfig; using LibBytes for bytes; @@ -86,8 +79,6 @@ contract DaveAppFactoryTest is Test { error UnexpectedLogEmitter(Vm.Log log); error UnexpectedLogTopic0(Vm.Log log); - IInputBox _inputBox; - IApplicationFactory _appFactory; IStateTransition _stateTransition; ITournamentFactory _tournamentFactory; IDaveAppFactory _daveAppFactory; @@ -98,15 +89,14 @@ contract DaveAppFactoryTest is Test { uint256 constant STAGING_GAS_CEILING = 500_000; function setUp() external { - _inputBox = new InputBox(); - _appFactory = new ApplicationFactory(); _stateTransition = new CartesiStateTransition(); _tournamentFactory = new MultiLevelTournamentFactory( new Tournament(), new CanonicalTournamentParametersProvider(RESPONSE_BUDGET, MAX_ALLOWANCE), _stateTransition ); - _daveAppFactory = new DaveAppFactory(_inputBox, _appFactory, _tournamentFactory); + _daveAppFactory = + new DaveAppFactory(_contracts.core.inputBox, _contracts.core.applicationFactory, _tournamentFactory); _settlementCallbackReceiver = new SettlementCallbackReceiver(); } @@ -561,6 +551,7 @@ contract DaveAppFactoryTest is Test { assertEq(daveConsensus.getLastFinalizedMachineMerkleRoot(address(appContract)), bytes32(0)); assertFalse(daveConsensus.isOutputsMerkleRootValid(address(appContract), outputsMerkleRoot)); + assertFalse(daveConsensus.wasInputFinalized(address(appContract), vm.randomUint(), vm.randomUint())); // Try re-staging tournament result vm.expectRevert(IDaveConsensus.TournamentResultAlreadyStaged.selector); @@ -650,6 +641,7 @@ contract DaveAppFactoryTest is Test { assertEq(daveConsensus.getLastFinalizedMachineMerkleRoot(address(appContract)), bytes32(0)); assertFalse(daveConsensus.isOutputsMerkleRootValid(address(appContract), outputsMerkleRoot)); + assertFalse(daveConsensus.wasInputFinalized(address(appContract), vm.randomUint(), vm.randomUint())); vm.expectRevert(_encodeApplicationForeclosed(address(appContract))); this.simulateForeclosureAndAcceptance(appContract, daveConsensus, 0); @@ -757,6 +749,9 @@ contract DaveAppFactoryTest is Test { assertEq(daveConsensus.getLastFinalizedMachineMerkleRoot(address(appContract)), machineMerkleRoot); assertTrue(daveConsensus.isOutputsMerkleRootValid(address(appContract), outputsMerkleRoot)); + // No input was finalized yet because the first epoch is always empty + assertFalse(daveConsensus.wasInputFinalized(address(appContract), vm.randomUint(), vm.randomUint())); + // Acceptance advanced the epoch without touching the retired // tournament's balance; recovery is an explicit call afterward. if (!recoverBeforeStaging) { @@ -786,6 +781,107 @@ contract DaveAppFactoryTest is Test { bytes memory input = vm.randomBytes(inputLength); assertEq(daveConsensus.provideMerkleRootOfInput(inputIndexOutOfBounds, input), bytes32(0)); } + + // See `testWasInputFinalized` for the behavior of `wasInputFinalized` + // once epoch #1 (the first non-empty epoch) is finalized as well. + } + + /// @notice Test `wasInputFinalized` across epoch boundaries. + /// @dev Epoch #0 is sealed on construction and is always empty, so accepting + /// its tournament result finalizes no input at all. Only once epoch #1 is + /// finalized do the inputs it spans become finalized. + function testWasInputFinalized( + bytes32 templateHash, + uint64 claimStagingPeriod, + address sentryManager, + address[] calldata sentries, + WithdrawalConfig calldata withdrawalConfig, + bytes32 salt, + bytes32 outputsMerkleRoot, + bytes[] calldata inputPayloadsOfEpoch1, + bytes[] calldata inputPayloadsOfEpoch2 + ) external { + // This test settles two epochs, so it needs twice the block-number slack. + _randomizeBlockNumber(claimStagingPeriod, 2); + + IApplication appContract; + IDaveConsensus daveConsensus; + + vm.assumeNoRevert(); + (appContract, daveConsensus) = _daveAppFactory.newDaveApp( + templateHash, claimStagingPeriod, sentryManager, sentries, withdrawalConfig, salt + ); + + uint256 numOfInputsOfEpoch1 = inputPayloadsOfEpoch1.length; + uint256 numOfInputsOfEpoch2 = inputPayloadsOfEpoch2.length; + + // Epoch #0 was sealed on construction and is empty, so these inputs are spanned by epoch #1 + for (uint256 i; i < numOfInputsOfEpoch1; ++i) { + _addInput(address(appContract), inputPayloadsOfEpoch1[i]); + } + + // Settling epoch #0 seals epoch #1 over inputs [0, numOfInputsOfEpoch1) + _settleCurrentSealedEpoch(daveConsensus, 0, claimStagingPeriod, outputsMerkleRoot); + + { + uint256 val1; + uint256 val2; + uint256 val3; + + (val1, val2, val3,,,,,) = daveConsensus.getCurrentSealedEpoch(); + + assertEq(val1, 1); // epochNumber + assertEq(val2, 0); // inputIndexLowerBound + assertEq(val3, numOfInputsOfEpoch1); // inputIndexUpperBound + } + + // Epoch #0 was empty, so no input was finalized by its acceptance + for (uint256 i; i < numOfInputsOfEpoch1; ++i) { + assertFalse(daveConsensus.wasInputFinalized(address(appContract), i, vm.randomUint())); + } + assertFalse(daveConsensus.wasInputFinalized(address(appContract), vm.randomUint(), vm.randomUint())); + + // These inputs are spanned by epoch #2, which is still accumulating + for (uint256 i; i < numOfInputsOfEpoch2; ++i) { + _addInput(address(appContract), inputPayloadsOfEpoch2[i]); + } + + // Settling epoch #1 seals epoch #2 over + // inputs [numOfInputsOfEpoch1, numOfInputsOfEpoch1 + numOfInputsOfEpoch2) + _settleCurrentSealedEpoch(daveConsensus, 1, claimStagingPeriod, outputsMerkleRoot); + + { + uint256 val1; + uint256 val2; + uint256 val3; + + (val1, val2, val3,,,,,) = daveConsensus.getCurrentSealedEpoch(); + + assertEq(val1, 2); // epochNumber + assertEq(val2, numOfInputsOfEpoch1); // inputIndexLowerBound + assertEq(val3, numOfInputsOfEpoch1 + numOfInputsOfEpoch2); // inputIndexUpperBound + } + + // Every input spanned by epoch #1 is now finalized, + // regardless of the block number passed to the function + for (uint256 i; i < numOfInputsOfEpoch1; ++i) { + assertTrue(daveConsensus.wasInputFinalized(address(appContract), i, vm.randomUint())); + } + + // No input spanned by epoch #2 is finalized, because epoch #2 is still accumulating + for (uint256 i = numOfInputsOfEpoch1; i < numOfInputsOfEpoch1 + numOfInputsOfEpoch2; ++i) { + assertFalse(daveConsensus.wasInputFinalized(address(appContract), i, vm.randomUint())); + } + + // Any index at or past the lower bound is reported as not finalized, + // whether or not an input with such an index exists in the input box + uint256 randomInputIndex = vm.randomUint(numOfInputsOfEpoch1, type(uint256).max); + assertFalse(daveConsensus.wasInputFinalized(address(appContract), randomInputIndex, vm.randomUint())); + + // The function still rejects any address other than the application contract + address notAppContract = _randomAddressNotEq(address(appContract)); + vm.expectRevert(_encodeApplicationMismatch(address(appContract), notAppContract)); + daveConsensus.wasInputFinalized(notAppContract, vm.randomUint(), vm.randomUint()); } function testRootFailureCannotBeStaged( @@ -1068,26 +1164,20 @@ contract DaveAppFactoryTest is Test { } else { revert UnexpectedLogTopic0(log); } - } else if (log.emitter == address(_appFactory)) { + } else if (log.emitter == address(_contracts.core.applicationFactory)) { if (log.topics[0] == IApplicationFactory.ApplicationCreated.selector) { ++numOfApplicationCreatedEvents; assertEq(log.topics[1], bytes32(0)); // outputsMerkleRootValidator address arg1; bytes32 arg2; - bytes memory arg3; + address arg3; WithdrawalConfig memory arg4; address arg5; (arg1, arg2, arg3, arg4, arg5) = - abi.decode(log.data, (address, bytes32, bytes, WithdrawalConfig, address)); + abi.decode(log.data, (address, bytes32, address, WithdrawalConfig, address)); assertEq(arg1, address(_daveAppFactory)); // appOwner assertEq(arg2, templateHash); - { - (bool isValid, bytes32 selector, bytes memory args) = arg3.consumeBytes4(); - assertTrue(isValid, "Expected data availability to be valid"); - assertEq(selector, DataAvailability.InputBox.selector); - address inputBoxAddress = abi.decode(args, (address)); - assertEq(inputBoxAddress, address(_inputBox)); - } + assertEq(arg3, address(_contracts.core.inputBox)); assertEq(abi.encode(arg4), abi.encode(withdrawalConfig)); assertEq(arg5, address(appContract)); } else { @@ -1103,7 +1193,7 @@ contract DaveAppFactoryTest is Test { (arg1, arg2, arg3) = abi.decode(log.data, (address, address, address)); - assertEq(arg1, address(_inputBox)); + assertEq(arg1, address(_contracts.core.inputBox)); assertEq(arg2, address(appContract)); assertEq(arg3, address(_tournamentFactory)); } else if (log.topics[0] == IDaveConsensus.EpochSealed.selector) { @@ -1212,7 +1302,7 @@ contract DaveAppFactoryTest is Test { assertEq(val3, 0); // epochNumber } - assertEq(address(daveConsensus.getInputBox()), address(_inputBox)); + assertEq(address(daveConsensus.getInputBox()), address(_contracts.core.inputBox)); assertEq(address(daveConsensus.getApplicationContract()), address(appContract)); assertEq(address(daveConsensus.getTournamentFactory()), address(_tournamentFactory)); assertEq(daveConsensus.getClaimStagingPeriod(), claimStagingPeriod); @@ -1235,6 +1325,9 @@ contract DaveAppFactoryTest is Test { vm.expectRevert(_encodeApplicationMismatch(address(appContract), notAppContract)); daveConsensus.isOutputsMerkleRootValid(notAppContract, bytes32(vm.randomUint())); + vm.expectRevert(_encodeApplicationMismatch(address(appContract), notAppContract)); + daveConsensus.wasInputFinalized(notAppContract, vm.randomUint(), vm.randomUint()); + bytes4 unsupportedInterfaceId; while (true) { @@ -1291,19 +1384,68 @@ contract DaveAppFactoryTest is Test { } function _randomizeBlockNumber(uint64 claimStagingPeriod) internal { + _randomizeBlockNumber(claimStagingPeriod, 1); + } + + function _randomizeBlockNumber(uint64 claimStagingPeriod, uint256 numOfEpochsToSettle) internal { // We limit the block number by type(uint64).max because the PRT contracts // use block numbers for time-keeping, and stores them as uint64 values. // We assume there is some slack so we can fast-forward to a block in which // the tournament is closed, and we can stage the tournament result, and a - // block in which the staged tournament result can be accepted. + // block in which the staged tournament result can be accepted. Tests that + // settle more than one epoch need one such slack per epoch. // We type the claim staging period as uint64 because otherwise the fuzzer // would often pick values too high for these assumptions. uint256 blockNumber = vm.getBlockNumber(); - uint64 maxAllowance = Time.Duration.unwrap(MAX_ALLOWANCE); - vm.assume(blockNumber <= type(uint256).max - maxAllowance); - vm.assume(blockNumber + maxAllowance <= type(uint256).max - claimStagingPeriod); - vm.assume(blockNumber + maxAllowance + claimStagingPeriod <= type(uint64).max); - vm.roll(blockNumber + vm.randomUint(0, type(uint64).max - maxAllowance - claimStagingPeriod)); + uint256 maxAllowance = Time.Duration.unwrap(MAX_ALLOWANCE); + uint256 slack = numOfEpochsToSettle * (maxAllowance + uint256(claimStagingPeriod)); + vm.assume(blockNumber + slack <= type(uint64).max); + vm.roll(vm.randomUint(blockNumber, type(uint64).max - slack)); + } + + /// @notice Join, close, stage and accept the tournament of the current sealed epoch. + /// @dev Assumes that the block number budget reserved by `_randomizeBlockNumber` + /// still has room for one epoch settlement. + function _settleCurrentSealedEpoch( + IDaveConsensus daveConsensus, + uint256 epochNumber, + uint64 claimStagingPeriod, + bytes32 outputsMerkleRoot + ) internal { + ITournament tournament; + (,,, tournament,,,,) = daveConsensus.getCurrentSealedEpoch(); + + bytes32[] memory outputsMerkleRootProof = _randomProof(Memory.LOG2_MAX_SIZE); + bytes32 machineMerkleRoot = outputsMerkleRootProof.merkleRootAfterReplacement( + EmulatorConstants.AR_CMIO_TX_BUFFER_START >> EmulatorConstants.HASH_TREE_LOG2_WORD_SIZE, + keccak256(abi.encode(outputsMerkleRoot)) + ); + + bytes32[] memory finalStateProof = _randomProof(tournament.tournamentArguments().commitmentArgs.height); + (bytes32 leftChild, bytes32 rightChild) = _getCommitmentChildren(machineMerkleRoot, finalStateProof); + + address submitter = vm.randomAddress(); + uint256 bondValue = tournament.bondValue(); + vm.deal(submitter, bondValue); + + vm.prank(submitter); + tournament.joinTournament{value: bondValue}( + Machine.Hash.wrap(machineMerkleRoot), finalStateProof, Tree.Node.wrap(leftChild), Tree.Node.wrap(rightChild) + ); + + // Fast-forward to a block in which the tournament is closed and finished + vm.roll(vm.getBlockNumber() + Time.Duration.unwrap(MAX_ALLOWANCE)); + assertTrue(tournament.isFinished()); + + vm.prank(vm.randomAddress()); + daveConsensus.stageTournamentResult(epochNumber, outputsMerkleRoot, outputsMerkleRootProof); + + // Fast-forward to a block in which the claim staging period is over. Since the + // application has no sentries, this is the only way of accepting the staged result. + vm.roll(vm.getBlockNumber() + claimStagingPeriod); + + vm.prank(vm.randomAddress()); + daveConsensus.acceptStagedTournamentResult(epochNumber); } function _randomProof(uint256 n) internal returns (bytes32[] memory proof) { @@ -1327,11 +1469,11 @@ contract DaveAppFactoryTest is Test { } function _addInput(address appContract, bytes memory payload) internal returns (bytes memory input) { - uint256 index = _inputBox.getNumberOfInputs(appContract); + uint256 index = _contracts.core.inputBox.getNumberOfInputs(appContract); vm.recordLogs(); - _inputBox.addInput(appContract, payload); + _contracts.core.inputBox.addInput(appContract, payload); Vm.Log[] memory logs = vm.getRecordedLogs(); @@ -1339,7 +1481,7 @@ contract DaveAppFactoryTest is Test { Vm.Log memory log = logs[0]; - if (log.emitter == address(_inputBox)) { + if (log.emitter == address(_contracts.core.inputBox)) { if (log.topics[0] == IInputBox.InputAdded.selector) { assertEq(log.topics[1], bytes32(uint256(uint160(appContract)))); assertEq(log.topics[2], bytes32(index)); diff --git a/cartesi-rollups/node/Cargo.toml b/cartesi-rollups/node/Cargo.toml index d51d084f..a971b3ee 100644 --- a/cartesi-rollups/node/Cargo.toml +++ b/cartesi-rollups/node/Cargo.toml @@ -48,7 +48,6 @@ log = { workspace = true } rusqlite = { workspace = true } rusqlite_migration = { workspace = true } hex = { workspace = true } -serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" tempfile = "3" env_logger = "0.11.5" diff --git a/cartesi-rollups/node/src/blockchain_reader/test_utils.rs b/cartesi-rollups/node/src/blockchain_reader/test_utils.rs index 59bcd64f..823f8747 100644 --- a/cartesi-rollups/node/src/blockchain_reader/test_utils.rs +++ b/cartesi-rollups/node/src/blockchain_reader/test_utils.rs @@ -14,7 +14,6 @@ use alloy::{ use cartesi_dave_contracts::i_dave_app_factory::IDaveAppFactory::{self, WithdrawalConfig}; use cartesi_machine::{Machine, config::runtime::RuntimeConfig}; use cartesi_rollups_contracts::i_input_box::IInputBox; -use serde::Deserialize; use std::{fs, path::PathBuf}; type Result = std::result::Result>; @@ -23,11 +22,6 @@ const PROGRAM: &str = "../../test/programs/echo/"; const ANVIL_STATE: &str = "../../cartesi-rollups/contracts/state.json"; const DEPLOYMENTS: &str = "../../cartesi-rollups/contracts/deployments/31337"; -#[derive(Deserialize)] -struct Deployment { - address: String, -} - pub fn program_path() -> PathBuf { PathBuf::from(PROGRAM).canonicalize().unwrap() } @@ -58,10 +52,9 @@ pub fn deployments_path() -> PathBuf { } pub fn deployment_address(contract_id: &str) -> Address { - let deployment_path = deployments_path().join(format!("{}.json", contract_id)); - let deployment_json = fs::read_to_string(deployment_path).unwrap(); - let deployment: Deployment = serde_json::from_str(&deployment_json).unwrap(); - Address::from_hex(deployment.address).unwrap() + let deployment_path = deployments_path().join(format!("{}.txt", contract_id)); + let deployment = fs::read_to_string(deployment_path).unwrap(); + Address::from_hex(deployment).unwrap() } /// A per-request timeout on every test provider: a wedged anvil must diff --git a/prt/contracts/foundry.toml b/prt/contracts/foundry.toml index d4920511..7b642418 100644 --- a/prt/contracts/foundry.toml +++ b/prt/contracts/foundry.toml @@ -32,6 +32,7 @@ exclude_lints = ["incorrect-shift"] line_length = 80 tab_width = 4 sort_imports = true +single_line_imports = true [dependencies] forge-std = "1.9.6" diff --git a/prt/contracts/script/BaseDeploymentScript.sol b/prt/contracts/script/BaseDeploymentScript.sol index ba7c9dcc..92dc27c7 100644 --- a/prt/contracts/script/BaseDeploymentScript.sol +++ b/prt/contracts/script/BaseDeploymentScript.sol @@ -9,11 +9,23 @@ import {Script} from "forge-std-1.9.6/src/Script.sol"; import {Vm} from "forge-std-1.9.6/src/Vm.sol"; /// @notice A base contract for deployment scripts. -/// @dev Deployments are serialized to JSON files containing the -/// contract name and address, and stored in chain-specific directories -/// per project. They can be stored (requires read-write fs permission) -/// and loaded from other projects (requires read fs permission). +/// @dev Deployments are serialized to files named after the contract and +/// stored in chain-specific directories per project. Every deployment is +/// written in two formats: a plaintext (TXT) file containing only the +/// address, and a JSON file containing the address and the contract name. +/// The TXT format is the canonical one, and the only one read back by +/// `_loadDeployment`. The JSON format is deprecated and kept only so that +/// clients still reading it can migrate at their own pace; it will be +/// removed once they have. They can be stored (requires read-write fs +/// permission) and loaded from other projects (requires read fs permission). abstract contract BaseDeploymentScript is Script { + /// @notice The extension of plaintext deployment files. + string constant TXT_EXTENSION = ".txt"; + + /// @notice The extension of JSON deployment files. + /// @dev Deprecated. See the contract-level documentation. + string constant JSON_EXTENSION = ".json"; + /// @notice The set of deployed contract names of the current project. mapping(string => bool) private _wasContractDeployed; @@ -54,7 +66,8 @@ abstract contract BaseDeploymentScript is Script { /// @notice Store a deployment in the current project. /// @param contractName The contract name /// @param deployment The deployment address - /// @return depoyment The deployment address + /// @return deployment The deployment address + /// @dev Writes the deployment in both the TXT and the JSON formats. function _storeDeployment(string memory contractName, address deployment) internal returns (address) @@ -76,50 +89,129 @@ abstract contract BaseDeploymentScript is Script { _wasContractDeployed[contractName] = true; _deploymentByContractName[contractName] = deployment; - string memory deploymentStr = vm.toString(deployment); - string memory objectKey = - string.concat(contractName, "@", deploymentStr); - string memory json; - json = vmSafe.serializeAddress(objectKey, "address", deployment); - json = vmSafe.serializeString(objectKey, "contractName", contractName); string memory dir = _getCurrentChainDeploymentsDir("."); vm.createDir(dir, true); - string memory path = _getDeploymentFilePath(dir, contractName); - vmSafe.writeJson(json, path); + _writeTxtDeployment(dir, contractName, deployment); + _writeJsonDeployment(dir, contractName, deployment); return deployment; } + /// @notice Write a deployment to a TXT file, which holds the + /// deployment address and nothing else. + /// @param dir The deployment directory + /// @param contractName The contract name + /// @param deployment The deployment address + function _writeTxtDeployment( + string memory dir, + string memory contractName, + address deployment + ) private { + /// forge-lint: disable-next-line(unsafe-cheatcode) + vmSafe.writeFile( + _getDeploymentFilePath(dir, contractName, TXT_EXTENSION), + vmSafe.toString(deployment) + ); + } + + /// @notice Write a deployment to a JSON file, which holds the + /// deployment address along with the contract name. + /// @param dir The deployment directory + /// @param contractName The contract name + /// @param deployment The deployment address + /// @dev Deprecated. See the contract-level documentation. + function _writeJsonDeployment( + string memory dir, + string memory contractName, + address deployment + ) private { + string memory objectKey = string.concat( + contractName, "@", vmSafe.toString(deployment) + ); + string memory json; + json = vmSafe.serializeAddress(objectKey, "address", deployment); + json = vmSafe.serializeString(objectKey, "contractName", contractName); + /// forge-lint: disable-next-line(unsafe-cheatcode) + vmSafe.writeFile( + _getDeploymentFilePath(dir, contractName, JSON_EXTENSION), json + ); + } + /// @notice Load a deployment from a project. /// @param projectRoot The project root path /// @param contractName The contract name /// @return deployment The deployment address + /// @dev Reads the TXT file. The JSON file is deprecated and, even + /// though it is still written, it is no longer read back. function _loadDeployment( string memory projectRoot, string memory contractName ) internal view returns (address deployment) { string memory dir = _getCurrentChainDeploymentsDir(projectRoot); - string memory path = _getDeploymentFilePath(dir, contractName); + return _readTxtDeployment( + _getDeploymentFilePath(dir, contractName, TXT_EXTENSION) + ); + } + + /// @notice Read a deployment address from a TXT file. + /// @param path The TXT file path + /// @return deployment The deployment address + /// @dev The file is expected to hold the address and nothing else, + /// with no trailing newline, as written by `_writeTxtDeployment`. + function _readTxtDeployment(string memory path) + private + view + returns (address deployment) + { + /// forge-lint: disable-next-line(unsafe-cheatcode) + return vmSafe.parseAddress(vmSafe.readFile(path)); + } + + /// @notice Read a deployment address from a JSON file. + /// @param path The JSON file path + /// @return contractName The contract name + /// @return deployment The deployment address + /// @dev Deprecated. See the contract-level documentation. + function _readJsonDeployment(string memory path) + private + view + returns (string memory contractName, address deployment) + { /// forge-lint: disable-next-line(unsafe-cheatcode) string memory json = vmSafe.readFile(path); - return vmSafe.parseJsonAddress(json, ".address"); + contractName = vmSafe.parseJsonString(json, ".contractName"); + deployment = vmSafe.parseJsonAddress(json, ".address"); } /// @notice Import all deployments from a project. /// @param projectRoot The project root path /// @dev The traversal of the deployments directory is shallow (maxDepth = 1). /// Symbolic links are not followed to avoid unbounded recursion. + /// Both TXT and JSON files are imported, since a project may have + /// migrated to the TXT format already, or may not have yet. A contract + /// deployed in both formats is therefore imported twice; the second + /// import is a no-op if both files agree, and raises a + /// `ContractNameConflict` error if they do not. Files with any other + /// extension are not deployment artifacts, and are skipped. function _importDeployments(string memory projectRoot) internal { string memory dir = _getCurrentChainDeploymentsDir(projectRoot); Vm.DirEntry[] memory dirEntries = vm.readDir(dir, 1, false); for (uint256 i; i < dirEntries.length; ++i) { Vm.DirEntry memory dirEntry = dirEntries[i]; - if (vm.isFile(dirEntry.path)) { - /// forge-lint: disable-next-line(unsafe-cheatcode) - string memory json = vmSafe.readFile(dirEntry.path); + if (!vm.isFile(dirEntry.path)) { + continue; + } + if (_hasSuffix(dirEntry.path, TXT_EXTENSION)) { + // A TXT file holds no contract name, + // so it is taken from the file name instead. + string memory contractName = + _getContractNameFromFilePath(dirEntry.path, TXT_EXTENSION); _storeDeployment( - vmSafe.parseJsonString(json, ".contractName"), - vmSafe.parseJsonAddress(json, ".address") + contractName, _readTxtDeployment(dirEntry.path) ); + } else if (_hasSuffix(dirEntry.path, JSON_EXTENSION)) { + (string memory contractName, address deployment) = + _readJsonDeployment(dirEntry.path); + _storeDeployment(contractName, deployment); } } } @@ -137,15 +229,74 @@ abstract contract BaseDeploymentScript is Script { ); } - /// @notice Get the path of a deployment file given the directory and contract name. + /// @notice Get the path of a deployment file given the directory, + /// the contract name and the file extension. /// @param dir The deployment directory (see `_getCurrentChainDeploymentsDir`) /// @param contractName The contract name + /// @param extension The file extension, including the leading dot /// @return path The deployment file path function _getDeploymentFilePath( string memory dir, - string memory contractName + string memory contractName, + string memory extension ) internal pure returns (string memory path) { - path = string.concat(dir, "/", contractName, ".json"); + path = string.concat(dir, "/", contractName, extension); + } + + /// @notice Get the contract name a deployment file is named after. + /// @param path The deployment file path + /// @param extension The file extension, including the leading dot + /// @return contractName The contract name + /// @dev Assumes `path` ends with `extension` (see `_hasSuffix`). + /// The result is not validated here: `_storeDeployment` rejects it + /// through `_isContractNameValid` if the file was named arbitrarily. + function _getContractNameFromFilePath( + string memory path, + string memory extension + ) internal pure returns (string memory contractName) { + bytes memory pathBytes = bytes(path); + uint256 end = pathBytes.length - bytes(extension).length; + + // The name starts right after the last path separator, if any. + uint256 start; + for (uint256 i = end; i > 0; --i) { + if (pathBytes[i - 1] == "/") { + start = i; + break; + } + } + + bytes memory nameBytes = new bytes(end - start); + for (uint256 i; i < nameBytes.length; ++i) { + nameBytes[i] = pathBytes[start + i]; + } + contractName = string(nameBytes); + } + + /// @notice Check whether a string ends with a given suffix. + /// @param str The string + /// @param suffix The suffix + /// @return True if `str` ends with `suffix`, false otherwise + function _hasSuffix(string memory str, string memory suffix) + internal + pure + returns (bool) + { + bytes memory strBytes = bytes(str); + bytes memory suffixBytes = bytes(suffix); + + if (strBytes.length < suffixBytes.length) { + return false; + } + + uint256 offset = strBytes.length - suffixBytes.length; + for (uint256 i; i < suffixBytes.length; ++i) { + if (strBytes[offset + i] != suffixBytes[i]) { + return false; + } + } + + return true; } /// @notice Checks if a contract name is valid according to Solidity naming rules @@ -166,23 +317,18 @@ abstract contract BaseDeploymentScript is Script { // Check first character: must be a-z, A-Z, _, or $ bytes1 firstChar = nameBytes[0]; - if (!((firstChar >= 0x41 && firstChar <= 0x5A) // A-Z - || (firstChar >= 0x61 && firstChar <= 0x7A) // a-z - || firstChar == 0x5F // _ - || firstChar == 0x24 // $ - )) { + if (!((firstChar >= "A" && firstChar <= "Z") + || (firstChar >= "a" && firstChar <= "z") + || firstChar == "_" || firstChar == "$")) { return false; } // Check remaining characters: must be a-z, A-Z, 0-9, _, or $ for (uint256 i = 1; i < nameBytes.length; i++) { bytes1 char = nameBytes[i]; - if (!((char >= 0x41 && char <= 0x5A) // A-Z - || (char >= 0x61 && char <= 0x7A) // a-z - || (char >= 0x30 && char <= 0x39) // 0-9 - || char == 0x5F // _ - || char == 0x24 // $ - )) { + if (!((char >= "A" && char <= "Z") || (char >= "a" && char <= "z") + || (char >= "0" && char <= "9") || char == "_" + || char == "$")) { return false; } } diff --git a/prt/contracts/script/Deployment.s.sol b/prt/contracts/script/Deployment.s.sol index 2f16be39..745d2046 100644 --- a/prt/contracts/script/Deployment.s.sol +++ b/prt/contracts/script/Deployment.s.sol @@ -5,16 +5,10 @@ pragma solidity ^0.8.8; import {BaseDeploymentScript} from "./BaseDeploymentScript.sol"; -import { - CanonicalTournamentParametersProvider -} from "src/arbitration-config/CanonicalTournamentParametersProvider.sol"; -import { - CartesiStateTransition -} from "src/state-transition/CartesiStateTransition.sol"; +import {CanonicalTournamentParametersProvider} from "src/arbitration-config/CanonicalTournamentParametersProvider.sol"; +import {CartesiStateTransition} from "src/state-transition/CartesiStateTransition.sol"; import {Tournament} from "src/tournament/Tournament.sol"; -import { - MultiLevelTournamentFactory -} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; +import {MultiLevelTournamentFactory} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; import {Time} from "src/tournament/libs/Time.sol"; type Milliseconds is uint64; @@ -137,7 +131,9 @@ contract DeploymentScript is BaseDeploymentScript { error UnregisteredChainKind(ChainKind chainKind); /// @notice Deploy the PRT contracts. - /// @dev Serializes deployed contract addresses to `deployments.json`. + /// @dev Serializes deployed contract addresses to both + /// `deployments//.txt` and + /// `deployments//.json` (deprecated). function run() external { _registerChains(); _registerChainKinds(); diff --git a/prt/contracts/src/arbitration-config/CanonicalTournamentParametersProvider.sol b/prt/contracts/src/arbitration-config/CanonicalTournamentParametersProvider.sol index 5f20533f..c0769fcd 100644 --- a/prt/contracts/src/arbitration-config/CanonicalTournamentParametersProvider.sol +++ b/prt/contracts/src/arbitration-config/CanonicalTournamentParametersProvider.sol @@ -4,13 +4,9 @@ pragma solidity ^0.8.17; import {ArbitrationConstants} from "./ArbitrationConstants.sol"; -import { - ITournamentParametersProvider -} from "./ITournamentParametersProvider.sol"; +import {ITournamentParametersProvider} from "./ITournamentParametersProvider.sol"; import {Time} from "prt-contracts/tournament/libs/Time.sol"; -import { - TournamentParameters -} from "prt-contracts/types/TournamentParameters.sol"; +import {TournamentParameters} from "prt-contracts/types/TournamentParameters.sol"; contract CanonicalTournamentParametersProvider is ITournamentParametersProvider diff --git a/prt/contracts/src/arbitration-config/ITournamentParametersProvider.sol b/prt/contracts/src/arbitration-config/ITournamentParametersProvider.sol index de1d20f0..97974e4a 100644 --- a/prt/contracts/src/arbitration-config/ITournamentParametersProvider.sol +++ b/prt/contracts/src/arbitration-config/ITournamentParametersProvider.sol @@ -3,9 +3,7 @@ pragma solidity ^0.8.17; -import { - TournamentParameters -} from "prt-contracts/types/TournamentParameters.sol"; +import {TournamentParameters} from "prt-contracts/types/TournamentParameters.sol"; interface ITournamentParametersProvider { /// @notice Get tournament parameters for a given level. diff --git a/prt/contracts/src/tournament/Tournament.sol b/prt/contracts/src/tournament/Tournament.sol index 6b12375d..c652f147 100644 --- a/prt/contracts/src/tournament/Tournament.sol +++ b/prt/contracts/src/tournament/Tournament.sol @@ -8,9 +8,7 @@ import {Math} from "@openzeppelin-contracts-5.5.0/utils/math/Math.sol"; import {IStateTransition} from "prt-contracts/IStateTransition.sol"; import {ITournament} from "prt-contracts/ITournament.sol"; -import { - IMultiLevelTournamentFactory -} from "prt-contracts/tournament/factories/IMultiLevelTournamentFactory.sol"; +import {IMultiLevelTournamentFactory} from "prt-contracts/tournament/factories/IMultiLevelTournamentFactory.sol"; import {Bond} from "prt-contracts/tournament/libs/Bond.sol"; import {Clock} from "prt-contracts/tournament/libs/Clock.sol"; import {Commitment} from "prt-contracts/tournament/libs/Commitment.sol"; diff --git a/prt/contracts/src/tournament/factories/IMultiLevelTournamentFactory.sol b/prt/contracts/src/tournament/factories/IMultiLevelTournamentFactory.sol index a26f1a67..f985ca90 100644 --- a/prt/contracts/src/tournament/factories/IMultiLevelTournamentFactory.sol +++ b/prt/contracts/src/tournament/factories/IMultiLevelTournamentFactory.sol @@ -9,9 +9,7 @@ import {ITournament} from "prt-contracts/ITournament.sol"; import {ITournamentFactory} from "prt-contracts/ITournamentFactory.sol"; import {Time} from "prt-contracts/tournament/libs/Time.sol"; import {Machine} from "prt-contracts/types/Machine.sol"; -import { - TournamentParameters -} from "prt-contracts/types/TournamentParameters.sol"; +import {TournamentParameters} from "prt-contracts/types/TournamentParameters.sol"; import {Tree} from "prt-contracts/types/Tree.sol"; interface IMultiLevelTournamentFactory is ITournamentFactory { diff --git a/prt/contracts/src/tournament/factories/MultiLevelTournamentFactory.sol b/prt/contracts/src/tournament/factories/MultiLevelTournamentFactory.sol index 0ee8dab6..1a085606 100644 --- a/prt/contracts/src/tournament/factories/MultiLevelTournamentFactory.sol +++ b/prt/contracts/src/tournament/factories/MultiLevelTournamentFactory.sol @@ -10,16 +10,12 @@ import {IMultiLevelTournamentFactory} from "./IMultiLevelTournamentFactory.sol"; import {IDataProvider} from "prt-contracts/IDataProvider.sol"; import {IStateTransition} from "prt-contracts/IStateTransition.sol"; import {ITournament} from "prt-contracts/ITournament.sol"; -import { - ITournamentParametersProvider -} from "prt-contracts/arbitration-config/ITournamentParametersProvider.sol"; +import {ITournamentParametersProvider} from "prt-contracts/arbitration-config/ITournamentParametersProvider.sol"; import {Tournament} from "prt-contracts/tournament/Tournament.sol"; import {Commitment} from "prt-contracts/tournament/libs/Commitment.sol"; import {Time} from "prt-contracts/tournament/libs/Time.sol"; import {Machine} from "prt-contracts/types/Machine.sol"; -import { - TournamentParameters -} from "prt-contracts/types/TournamentParameters.sol"; +import {TournamentParameters} from "prt-contracts/types/TournamentParameters.sol"; import {Tree} from "prt-contracts/types/Tree.sol"; /// @dev The immutable provider is the sole authority for a parameter table diff --git a/prt/contracts/src/tournament/libs/Commitment.sol b/prt/contracts/src/tournament/libs/Commitment.sol index 30d3f2f9..fa946783 100644 --- a/prt/contracts/src/tournament/libs/Commitment.sol +++ b/prt/contracts/src/tournament/libs/Commitment.sol @@ -3,9 +3,7 @@ pragma solidity ^0.8.17; -import { - Hashes -} from "@openzeppelin-contracts-5.5.0/utils/cryptography/Hashes.sol"; +import {Hashes} from "@openzeppelin-contracts-5.5.0/utils/cryptography/Hashes.sol"; import {ITournament} from "prt-contracts/ITournament.sol"; import {Machine} from "prt-contracts/types/Machine.sol"; diff --git a/prt/contracts/src/types/Tree.sol b/prt/contracts/src/types/Tree.sol index 358b1a95..f3fd6bd3 100644 --- a/prt/contracts/src/types/Tree.sol +++ b/prt/contracts/src/types/Tree.sol @@ -3,9 +3,7 @@ pragma solidity ^0.8.17; -import { - Hashes -} from "@openzeppelin-contracts-5.5.0/utils/cryptography/Hashes.sol"; +import {Hashes} from "@openzeppelin-contracts-5.5.0/utils/cryptography/Hashes.sol"; import {ITournament} from "prt-contracts/ITournament.sol"; import {Machine} from "prt-contracts/types/Machine.sol"; diff --git a/prt/contracts/test/StateTransition.t.sol b/prt/contracts/test/StateTransition.t.sol index 18dd1a6e..ce6534a0 100644 --- a/prt/contracts/test/StateTransition.t.sol +++ b/prt/contracts/test/StateTransition.t.sol @@ -18,9 +18,7 @@ import {EmulatorConstants} from "step/src/EmulatorConstants.sol"; import {Memory} from "step/src/Memory.sol"; import {IDataProvider} from "src/IDataProvider.sol"; -import { - CartesiStateTransition -} from "src/state-transition/CartesiStateTransition.sol"; +import {CartesiStateTransition} from "src/state-transition/CartesiStateTransition.sol"; import {Util} from "./Util.sol"; diff --git a/prt/contracts/test/StateTransitionFfi.t.sol b/prt/contracts/test/StateTransitionFfi.t.sol index 07d0fced..aed71f53 100644 --- a/prt/contracts/test/StateTransitionFfi.t.sol +++ b/prt/contracts/test/StateTransitionFfi.t.sol @@ -15,9 +15,7 @@ pragma solidity ^0.8.0; import {EmulatorConstants} from "step/src/EmulatorConstants.sol"; import {IDataProvider} from "src/IDataProvider.sol"; -import { - CartesiStateTransition -} from "src/state-transition/CartesiStateTransition.sol"; +import {CartesiStateTransition} from "src/state-transition/CartesiStateTransition.sol"; import {Util} from "./Util.sol"; diff --git a/prt/contracts/test/Tournament.t.sol b/prt/contracts/test/Tournament.t.sol index f807ee76..b2e2c9bb 100644 --- a/prt/contracts/test/Tournament.t.sol +++ b/prt/contracts/test/Tournament.t.sol @@ -14,9 +14,7 @@ pragma solidity ^0.8.0; import {IStateTransition} from "src/IStateTransition.sol"; import {ITournament} from "src/ITournament.sol"; -import { - MultiLevelTournamentFactory -} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; +import {MultiLevelTournamentFactory} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; import {Clock} from "src/tournament/libs/Clock.sol"; import {Match} from "src/tournament/libs/Match.sol"; import {MatchClocks} from "src/tournament/libs/MatchClocks.sol"; @@ -25,9 +23,7 @@ import {Machine} from "src/types/Machine.sol"; import {Tree} from "src/types/Tree.sol"; import {Util} from "./Util.sol"; -import { - HistoricalThreeLevelGeometry as HistoricalGeometry -} from "./fixtures/HistoricalThreeLevelGeometry.sol"; +import {HistoricalThreeLevelGeometry as HistoricalGeometry} from "./fixtures/HistoricalThreeLevelGeometry.sol"; import {TournamentInspector} from "test/fixtures/TournamentInspector.sol"; diff --git a/prt/contracts/test/TournamentStateTransitionFfi.t.sol b/prt/contracts/test/TournamentStateTransitionFfi.t.sol index 545b20e0..4316bc9f 100644 --- a/prt/contracts/test/TournamentStateTransitionFfi.t.sol +++ b/prt/contracts/test/TournamentStateTransitionFfi.t.sol @@ -5,9 +5,7 @@ pragma solidity ^0.8.22; import {IDataProvider} from "src/IDataProvider.sol"; import {ITournament} from "src/ITournament.sol"; -import { - MultiLevelTournamentFactory -} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; +import {MultiLevelTournamentFactory} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; import {Match} from "src/tournament/libs/Match.sol"; import {Machine} from "src/types/Machine.sol"; import {Tree} from "src/types/Tree.sol"; diff --git a/prt/contracts/test/Util.sol b/prt/contracts/test/Util.sol index 51333326..f8a2829a 100644 --- a/prt/contracts/test/Util.sol +++ b/prt/contracts/test/Util.sol @@ -16,19 +16,11 @@ import {Test} from "forge-std-1.9.6/src/Test.sol"; import {IDataProvider} from "src/IDataProvider.sol"; import {ITournament} from "src/ITournament.sol"; -import { - CanonicalTournamentParametersProvider -} from "src/arbitration-config/CanonicalTournamentParametersProvider.sol"; -import { - ITournamentParametersProvider -} from "src/arbitration-config/ITournamentParametersProvider.sol"; -import { - CartesiStateTransition -} from "src/state-transition/CartesiStateTransition.sol"; +import {CanonicalTournamentParametersProvider} from "src/arbitration-config/CanonicalTournamentParametersProvider.sol"; +import {ITournamentParametersProvider} from "src/arbitration-config/ITournamentParametersProvider.sol"; +import {CartesiStateTransition} from "src/state-transition/CartesiStateTransition.sol"; import {Tournament} from "src/tournament/Tournament.sol"; -import { - MultiLevelTournamentFactory -} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; +import {MultiLevelTournamentFactory} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; import {Match} from "src/tournament/libs/Match.sol"; import {Time} from "src/tournament/libs/Time.sol"; import {Machine} from "src/types/Machine.sol"; diff --git a/prt/contracts/test/accounting/RefundCallbacks.t.sol b/prt/contracts/test/accounting/RefundCallbacks.t.sol index ed4869bd..24c77fca 100644 --- a/prt/contracts/test/accounting/RefundCallbacks.t.sol +++ b/prt/contracts/test/accounting/RefundCallbacks.t.sol @@ -9,13 +9,9 @@ import {Vm} from "forge-std-1.9.6/src/Vm.sol"; import {IDataProvider} from "src/IDataProvider.sol"; import {IStateTransition} from "src/IStateTransition.sol"; import {ITournament} from "src/ITournament.sol"; -import { - ITournamentParametersProvider -} from "src/arbitration-config/ITournamentParametersProvider.sol"; +import {ITournamentParametersProvider} from "src/arbitration-config/ITournamentParametersProvider.sol"; import {Tournament} from "src/tournament/Tournament.sol"; -import { - MultiLevelTournamentFactory -} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; +import {MultiLevelTournamentFactory} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; import {Bond} from "src/tournament/libs/Bond.sol"; import {Match} from "src/tournament/libs/Match.sol"; import {Time} from "src/tournament/libs/Time.sol"; diff --git a/prt/contracts/test/accounting/RefundReserve.t.sol b/prt/contracts/test/accounting/RefundReserve.t.sol index d5128317..80bfb21b 100644 --- a/prt/contracts/test/accounting/RefundReserve.t.sol +++ b/prt/contracts/test/accounting/RefundReserve.t.sol @@ -8,13 +8,9 @@ import {Test} from "forge-std-1.9.6/src/Test.sol"; import {IDataProvider} from "src/IDataProvider.sol"; import {IStateTransition} from "src/IStateTransition.sol"; import {ITournament} from "src/ITournament.sol"; -import { - ITournamentParametersProvider -} from "src/arbitration-config/ITournamentParametersProvider.sol"; +import {ITournamentParametersProvider} from "src/arbitration-config/ITournamentParametersProvider.sol"; import {Tournament} from "src/tournament/Tournament.sol"; -import { - MultiLevelTournamentFactory -} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; +import {MultiLevelTournamentFactory} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; import {Bond} from "src/tournament/libs/Bond.sol"; import {Clock} from "src/tournament/libs/Clock.sol"; import {Gas} from "src/tournament/libs/Gas.sol"; diff --git a/prt/contracts/test/characterization/HistoricalThreeLevelInner.t.sol b/prt/contracts/test/characterization/HistoricalThreeLevelInner.t.sol index be86679c..1d8e7430 100644 --- a/prt/contracts/test/characterization/HistoricalThreeLevelInner.t.sol +++ b/prt/contracts/test/characterization/HistoricalThreeLevelInner.t.sol @@ -15,9 +15,7 @@ pragma solidity ^0.8.0; import {Vm} from "forge-std-1.9.6/src/Vm.sol"; import {ITournament} from "src/ITournament.sol"; -import { - MultiLevelTournamentFactory -} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; +import {MultiLevelTournamentFactory} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; import {Clock} from "src/tournament/libs/Clock.sol"; import {Match} from "src/tournament/libs/Match.sol"; import {Time} from "src/tournament/libs/Time.sol"; @@ -25,9 +23,7 @@ import {Machine} from "src/types/Machine.sol"; import {Tree} from "src/types/Tree.sol"; import {Util} from "../Util.sol"; -import { - HistoricalThreeLevelGeometry as HistoricalGeometry -} from "../fixtures/HistoricalThreeLevelGeometry.sol"; +import {HistoricalThreeLevelGeometry as HistoricalGeometry} from "../fixtures/HistoricalThreeLevelGeometry.sol"; import {TournamentInspector} from "test/fixtures/TournamentInspector.sol"; diff --git a/prt/contracts/test/characterization/HistoricalThreeLevelLeaf.t.sol b/prt/contracts/test/characterization/HistoricalThreeLevelLeaf.t.sol index ceb520f3..a010ccba 100644 --- a/prt/contracts/test/characterization/HistoricalThreeLevelLeaf.t.sol +++ b/prt/contracts/test/characterization/HistoricalThreeLevelLeaf.t.sol @@ -17,12 +17,8 @@ import {Vm} from "forge-std-1.9.6/src/Vm.sol"; import {IDataProvider} from "src/IDataProvider.sol"; import {IStateTransition} from "src/IStateTransition.sol"; import {ITournament} from "src/ITournament.sol"; -import { - CartesiStateTransition -} from "src/state-transition/CartesiStateTransition.sol"; -import { - MultiLevelTournamentFactory -} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; +import {CartesiStateTransition} from "src/state-transition/CartesiStateTransition.sol"; +import {MultiLevelTournamentFactory} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; import {Clock} from "src/tournament/libs/Clock.sol"; import {Match} from "src/tournament/libs/Match.sol"; import {Time} from "src/tournament/libs/Time.sol"; @@ -30,9 +26,7 @@ import {Machine} from "src/types/Machine.sol"; import {Tree} from "src/types/Tree.sol"; import {Util} from "../Util.sol"; -import { - HistoricalThreeLevelGeometry as HistoricalGeometry -} from "../fixtures/HistoricalThreeLevelGeometry.sol"; +import {HistoricalThreeLevelGeometry as HistoricalGeometry} from "../fixtures/HistoricalThreeLevelGeometry.sol"; import {TournamentInspector} from "test/fixtures/TournamentInspector.sol"; diff --git a/prt/contracts/test/characterization/HistoricalThreeLevelRoot.t.sol b/prt/contracts/test/characterization/HistoricalThreeLevelRoot.t.sol index 3bf4a924..eb533045 100644 --- a/prt/contracts/test/characterization/HistoricalThreeLevelRoot.t.sol +++ b/prt/contracts/test/characterization/HistoricalThreeLevelRoot.t.sol @@ -14,18 +14,14 @@ pragma solidity ^0.8.0; import {IDataProvider} from "src/IDataProvider.sol"; import {ITournament} from "src/ITournament.sol"; -import { - MultiLevelTournamentFactory -} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; +import {MultiLevelTournamentFactory} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; import {Match} from "src/tournament/libs/Match.sol"; import {Time} from "src/tournament/libs/Time.sol"; import {Machine} from "src/types/Machine.sol"; import {Tree} from "src/types/Tree.sol"; import {Util} from "../Util.sol"; -import { - HistoricalThreeLevelGeometry as HistoricalGeometry -} from "../fixtures/HistoricalThreeLevelGeometry.sol"; +import {HistoricalThreeLevelGeometry as HistoricalGeometry} from "../fixtures/HistoricalThreeLevelGeometry.sol"; import {TournamentInspector} from "test/fixtures/TournamentInspector.sol"; diff --git a/prt/contracts/test/config/CanonicalTournamentGeometry.t.sol b/prt/contracts/test/config/CanonicalTournamentGeometry.t.sol index 1236262b..fd618a10 100644 --- a/prt/contracts/test/config/CanonicalTournamentGeometry.t.sol +++ b/prt/contracts/test/config/CanonicalTournamentGeometry.t.sol @@ -14,15 +14,9 @@ pragma solidity ^0.8.17; import {IDataProvider} from "src/IDataProvider.sol"; import {ITournament} from "src/ITournament.sol"; -import { - ArbitrationConstants -} from "src/arbitration-config/ArbitrationConstants.sol"; -import { - CanonicalTournamentParametersProvider -} from "src/arbitration-config/CanonicalTournamentParametersProvider.sol"; -import { - MultiLevelTournamentFactory -} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; +import {ArbitrationConstants} from "src/arbitration-config/ArbitrationConstants.sol"; +import {CanonicalTournamentParametersProvider} from "src/arbitration-config/CanonicalTournamentParametersProvider.sol"; +import {MultiLevelTournamentFactory} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; import {Time} from "src/tournament/libs/Time.sol"; import {TournamentParameters} from "src/types/TournamentParameters.sol"; diff --git a/prt/contracts/test/config/MultiLevelTournamentFactoryDependencies.t.sol b/prt/contracts/test/config/MultiLevelTournamentFactoryDependencies.t.sol index e360a61b..09b94320 100644 --- a/prt/contracts/test/config/MultiLevelTournamentFactoryDependencies.t.sol +++ b/prt/contracts/test/config/MultiLevelTournamentFactoryDependencies.t.sol @@ -10,13 +10,9 @@ import {Errors} from "@openzeppelin-contracts-5.5.0/utils/Errors.sol"; import {IDataProvider} from "src/IDataProvider.sol"; import {IStateTransition} from "src/IStateTransition.sol"; import {ITournament} from "src/ITournament.sol"; -import { - ITournamentParametersProvider -} from "src/arbitration-config/ITournamentParametersProvider.sol"; +import {ITournamentParametersProvider} from "src/arbitration-config/ITournamentParametersProvider.sol"; import {Tournament} from "src/tournament/Tournament.sol"; -import { - MultiLevelTournamentFactory -} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; +import {MultiLevelTournamentFactory} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; import {Time} from "src/tournament/libs/Time.sol"; import {Machine} from "src/types/Machine.sol"; import {TournamentParameters} from "src/types/TournamentParameters.sol"; diff --git a/prt/contracts/test/config/TournamentParameterTableValidator.t.sol b/prt/contracts/test/config/TournamentParameterTableValidator.t.sol index 62eb10c8..fbd05218 100644 --- a/prt/contracts/test/config/TournamentParameterTableValidator.t.sol +++ b/prt/contracts/test/config/TournamentParameterTableValidator.t.sol @@ -5,13 +5,9 @@ pragma solidity ^0.8.17; import {Test} from "forge-std-1.9.6/src/Test.sol"; -import { - ArbitrationConstants -} from "prt-contracts/arbitration-config/ArbitrationConstants.sol"; +import {ArbitrationConstants} from "prt-contracts/arbitration-config/ArbitrationConstants.sol"; import {Time} from "prt-contracts/tournament/libs/Time.sol"; -import { - TournamentParameters -} from "prt-contracts/types/TournamentParameters.sol"; +import {TournamentParameters} from "prt-contracts/types/TournamentParameters.sol"; import { TournamentParameterTableValidator, diff --git a/prt/contracts/test/fixtures/ConfigurableCommitmentFixture.t.sol b/prt/contracts/test/fixtures/ConfigurableCommitmentFixture.t.sol index 04284eac..27b88d9c 100644 --- a/prt/contracts/test/fixtures/ConfigurableCommitmentFixture.t.sol +++ b/prt/contracts/test/fixtures/ConfigurableCommitmentFixture.t.sol @@ -9,9 +9,7 @@ import {Commitment} from "src/tournament/libs/Commitment.sol"; import {Machine} from "src/types/Machine.sol"; import {Tree} from "src/types/Tree.sol"; -import { - ConfigurableCommitmentFixture -} from "./ConfigurableCommitmentFixture.sol"; +import {ConfigurableCommitmentFixture} from "./ConfigurableCommitmentFixture.sol"; contract CommitmentProofVerifier { function rootAt( diff --git a/prt/contracts/test/fixtures/HistoricalThreeLevelGeometry.sol b/prt/contracts/test/fixtures/HistoricalThreeLevelGeometry.sol index 6c320804..ab83e8e6 100644 --- a/prt/contracts/test/fixtures/HistoricalThreeLevelGeometry.sol +++ b/prt/contracts/test/fixtures/HistoricalThreeLevelGeometry.sol @@ -3,9 +3,7 @@ pragma solidity ^0.8.17; -import { - ITournamentParametersProvider -} from "src/arbitration-config/ITournamentParametersProvider.sol"; +import {ITournamentParametersProvider} from "src/arbitration-config/ITournamentParametersProvider.sol"; import {Time} from "src/tournament/libs/Time.sol"; import {TournamentParameters} from "src/types/TournamentParameters.sol"; diff --git a/prt/contracts/test/fixtures/SmallFourLevelTournament.sol b/prt/contracts/test/fixtures/SmallFourLevelTournament.sol index 0e1c94c4..f721428b 100644 --- a/prt/contracts/test/fixtures/SmallFourLevelTournament.sol +++ b/prt/contracts/test/fixtures/SmallFourLevelTournament.sol @@ -3,12 +3,8 @@ pragma solidity ^0.8.17; -import { - ITournamentParametersProvider -} from "src/arbitration-config/ITournamentParametersProvider.sol"; -import { - MultiLevelTournamentFactory -} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; +import {ITournamentParametersProvider} from "src/arbitration-config/ITournamentParametersProvider.sol"; +import {MultiLevelTournamentFactory} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; import {Time} from "src/tournament/libs/Time.sol"; import {Machine} from "src/types/Machine.sol"; import {TournamentParameters} from "src/types/TournamentParameters.sol"; diff --git a/prt/contracts/test/fixtures/SmallSingleLevelTournament.sol b/prt/contracts/test/fixtures/SmallSingleLevelTournament.sol index 67624822..49101cea 100644 --- a/prt/contracts/test/fixtures/SmallSingleLevelTournament.sol +++ b/prt/contracts/test/fixtures/SmallSingleLevelTournament.sol @@ -3,12 +3,8 @@ pragma solidity ^0.8.17; -import { - ITournamentParametersProvider -} from "src/arbitration-config/ITournamentParametersProvider.sol"; -import { - MultiLevelTournamentFactory -} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; +import {ITournamentParametersProvider} from "src/arbitration-config/ITournamentParametersProvider.sol"; +import {MultiLevelTournamentFactory} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; import {Time} from "src/tournament/libs/Time.sol"; import {TournamentParameters} from "src/types/TournamentParameters.sol"; diff --git a/prt/contracts/test/fixtures/SmallTwoLevelTournament.sol b/prt/contracts/test/fixtures/SmallTwoLevelTournament.sol index bd1b0d46..95248387 100644 --- a/prt/contracts/test/fixtures/SmallTwoLevelTournament.sol +++ b/prt/contracts/test/fixtures/SmallTwoLevelTournament.sol @@ -3,12 +3,8 @@ pragma solidity ^0.8.17; -import { - ITournamentParametersProvider -} from "src/arbitration-config/ITournamentParametersProvider.sol"; -import { - MultiLevelTournamentFactory -} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; +import {ITournamentParametersProvider} from "src/arbitration-config/ITournamentParametersProvider.sol"; +import {MultiLevelTournamentFactory} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; import {Time} from "src/tournament/libs/Time.sol"; import {TournamentParameters} from "src/types/TournamentParameters.sol"; diff --git a/prt/contracts/test/fixtures/TournamentParameterTableValidator.sol b/prt/contracts/test/fixtures/TournamentParameterTableValidator.sol index 0534b9c7..d5c34766 100644 --- a/prt/contracts/test/fixtures/TournamentParameterTableValidator.sol +++ b/prt/contracts/test/fixtures/TournamentParameterTableValidator.sol @@ -4,9 +4,7 @@ pragma solidity ^0.8.17; import {Time} from "prt-contracts/tournament/libs/Time.sol"; -import { - TournamentParameters -} from "prt-contracts/types/TournamentParameters.sol"; +import {TournamentParameters} from "prt-contracts/types/TournamentParameters.sol"; /// @notice Test-only validation for an injected tournament parameter table. /// @dev Production keeps geometry static. This helper makes the generation diff --git a/prt/contracts/test/gas/TournamentGas.t.sol b/prt/contracts/test/gas/TournamentGas.t.sol index 092d626d..f85b2886 100644 --- a/prt/contracts/test/gas/TournamentGas.t.sol +++ b/prt/contracts/test/gas/TournamentGas.t.sol @@ -9,13 +9,9 @@ import {Vm} from "forge-std-1.9.6/src/Vm.sol"; import {IDataProvider} from "src/IDataProvider.sol"; import {IStateTransition} from "src/IStateTransition.sol"; import {ITournament} from "src/ITournament.sol"; -import { - ITournamentParametersProvider -} from "src/arbitration-config/ITournamentParametersProvider.sol"; +import {ITournamentParametersProvider} from "src/arbitration-config/ITournamentParametersProvider.sol"; import {Tournament} from "src/tournament/Tournament.sol"; -import { - MultiLevelTournamentFactory -} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; +import {MultiLevelTournamentFactory} from "src/tournament/factories/MultiLevelTournamentFactory.sol"; import {Bond} from "src/tournament/libs/Bond.sol"; import {Clock} from "src/tournament/libs/Clock.sol"; import {Gas} from "src/tournament/libs/Gas.sol"; @@ -25,9 +21,7 @@ import {Machine} from "src/types/Machine.sol"; import {TournamentParameters} from "src/types/TournamentParameters.sol"; import {Tree} from "src/types/Tree.sol"; -import { - ConfigurableCommitmentFixture -} from "../fixtures/ConfigurableCommitmentFixture.sol"; +import {ConfigurableCommitmentFixture} from "../fixtures/ConfigurableCommitmentFixture.sol"; import {TournamentInspector} from "test/fixtures/TournamentInspector.sol"; diff --git a/prt/contracts/test/properties/BoundedOneLevelDelay.t.sol b/prt/contracts/test/properties/BoundedOneLevelDelay.t.sol index cd1f8e6d..5fa704de 100644 --- a/prt/contracts/test/properties/BoundedOneLevelDelay.t.sol +++ b/prt/contracts/test/properties/BoundedOneLevelDelay.t.sol @@ -13,14 +13,10 @@ import {Time} from "src/tournament/libs/Time.sol"; import {Machine} from "src/types/Machine.sol"; import {Tree} from "src/types/Tree.sol"; -import { - BoundedOneLevelDelayModel -} from "../fixtures/BoundedOneLevelDelayModel.sol"; +import {BoundedOneLevelDelayModel} from "../fixtures/BoundedOneLevelDelayModel.sol"; import {InspectableTournament} from "../fixtures/InspectableTournament.sol"; import {SmallFullTree} from "../fixtures/SmallFullTree.sol"; -import { - SmallSingleLevelTournamentFactory -} from "../fixtures/SmallSingleLevelTournament.sol"; +import {SmallSingleLevelTournamentFactory} from "../fixtures/SmallSingleLevelTournament.sol"; import {TournamentInspector} from "test/fixtures/TournamentInspector.sol"; diff --git a/prt/contracts/test/properties/LeafPopulationDelay.t.sol b/prt/contracts/test/properties/LeafPopulationDelay.t.sol index 685a88cf..3743eb79 100644 --- a/prt/contracts/test/properties/LeafPopulationDelay.t.sol +++ b/prt/contracts/test/properties/LeafPopulationDelay.t.sol @@ -15,9 +15,7 @@ import {Tree} from "src/types/Tree.sol"; import {InspectableTournament} from "../fixtures/InspectableTournament.sol"; import {SmallFullTree} from "../fixtures/SmallFullTree.sol"; -import { - SmallSingleLevelTournamentFactory -} from "../fixtures/SmallSingleLevelTournament.sol"; +import {SmallSingleLevelTournamentFactory} from "../fixtures/SmallSingleLevelTournament.sol"; import {TournamentInspector} from "test/fixtures/TournamentInspector.sol"; diff --git a/prt/contracts/test/properties/TournamentLifecycleInvariant.t.sol b/prt/contracts/test/properties/TournamentLifecycleInvariant.t.sol index 737994b6..52bf009b 100644 --- a/prt/contracts/test/properties/TournamentLifecycleInvariant.t.sol +++ b/prt/contracts/test/properties/TournamentLifecycleInvariant.t.sol @@ -16,9 +16,7 @@ import {Tree} from "src/types/Tree.sol"; import {InspectableTournament} from "../fixtures/InspectableTournament.sol"; import {SmallFullTree} from "../fixtures/SmallFullTree.sol"; -import { - SmallSingleLevelTournamentFactory -} from "../fixtures/SmallSingleLevelTournament.sol"; +import {SmallSingleLevelTournamentFactory} from "../fixtures/SmallSingleLevelTournament.sol"; import {TournamentInspector} from "test/fixtures/TournamentInspector.sol"; diff --git a/script/devnet-fingerprint.sh b/script/devnet-fingerprint.sh index a3e3b691..e511d950 100755 --- a/script/devnet-fingerprint.sh +++ b/script/devnet-fingerprint.sh @@ -17,7 +17,7 @@ CDPATH= cd -- "$repo_root" || { exit 2 } -readonly base_contracts="cartesi-rollups/contracts/dependencies/cartesi-rollups-contracts-3.0.0-alpha.6" +readonly base_contracts="cartesi-rollups/contracts/dependencies/cartesi-rollups-contracts-3.0.0-alpha.9" readonly input_format="devnet-inputs-v5" readonly manifest_format="v4" diff --git a/script/machine-image-fingerprint.sh b/script/machine-image-fingerprint.sh index 9e719126..97557537 100755 --- a/script/machine-image-fingerprint.sh +++ b/script/machine-image-fingerprint.sh @@ -51,17 +51,13 @@ producer_script() { deployment_address() { local contract_name=$1 - local deployment="cartesi-rollups/contracts/deployments/31337/${contract_name}.json" + local deployment="cartesi-rollups/contracts/deployments/31337/${contract_name}.txt" if [ ! -f "$deployment" ]; then echo "error: missing devnet deployment: $deployment" >&2 return 1 fi - jq -er ' - .address - | select(type == "string") - | select(test("^0x[0-9A-Fa-f]{40}$")) - ' "$deployment" + cat "$deployment" } inputs_digest() { @@ -132,7 +128,7 @@ inputs_digest() { fi generator_hash=$(sha256_file \ test/programs/honeypot/generate-devnet-honeypot-config.sh) || return $? - portal_address=$(deployment_address ERC20Portal) || return 1 + portal_address=$(deployment_address Erc20Portal) || return 1 token_address=$(deployment_address TestFungibleToken) || return 1 else for input in linux.bin rootfs.ext2; do diff --git a/script/tests/devnet-fingerprint.sh b/script/tests/devnet-fingerprint.sh index 234bcea6..b429201e 100755 --- a/script/tests/devnet-fingerprint.sh +++ b/script/tests/devnet-fingerprint.sh @@ -27,7 +27,7 @@ source_roots=( config_roots=( prt/contracts cartesi-rollups/contracts - cartesi-rollups/contracts/dependencies/cartesi-rollups-contracts-3.0.0-alpha.6 + cartesi-rollups/contracts/dependencies/cartesi-rollups-contracts-3.0.0-alpha.9 ) for root in "${source_roots[@]}"; do @@ -54,6 +54,8 @@ printf '#!/usr/bin/env bash\n' \ mkdir -p "${fixture}/cartesi-rollups/contracts/deployments/31337" printf '{"state":"ready"}\n' \ >"${fixture}/cartesi-rollups/contracts/state.json" +printf '0x1' \ + >"${fixture}/cartesi-rollups/contracts/deployments/31337/Contract.txt" printf '{"address":"0x1"}\n' \ >"${fixture}/cartesi-rollups/contracts/deployments/31337/Contract.json" @@ -171,9 +173,13 @@ expect_status 1 verify "${fixture}/cartesi-rollups/contracts" printf '{"state":"ready"}\n' \ >"${fixture}/cartesi-rollups/contracts/state.json" +printf '0x2' \ + >"${fixture}/cartesi-rollups/contracts/deployments/31337/Contract.txt" printf '{"address":"0x2"}\n' \ >"${fixture}/cartesi-rollups/contracts/deployments/31337/Contract.json" expect_status 1 verify "${fixture}/cartesi-rollups/contracts" +printf '0x1' \ + >"${fixture}/cartesi-rollups/contracts/deployments/31337/Contract.txt" printf '{"address":"0x1"}\n' \ >"${fixture}/cartesi-rollups/contracts/deployments/31337/Contract.json" diff --git a/test/Dockerfile b/test/Dockerfile index 20f039fc..d92ea6d9 100644 --- a/test/Dockerfile +++ b/test/Dockerfile @@ -114,13 +114,19 @@ RUN just -f cartesi-rollups/contracts/justfile install-deps COPY machine/step/ machine/step/ COPY justfile justfile -# builds smart contracts and generate Rust bindings for smart contracts. +# builds smart contracts. RUN \ --mount=type=cache,target=cartesi-rollups/contracts/out,sharing=locked \ --mount=type=cache,target=cartesi-rollups/contracts/cache,sharing=locked \ --mount=type=cache,target=prt/contracts/out,sharing=locked \ --mount=type=cache,target=prt/contracts/cache,sharing=locked \ - just build-smart-contracts && just bind + just build-smart-contracts + +# generates Rust bindings for smart contracts. +# no --mount here: `forge bind --force` clears out/ and cache/, which fails on a +# mount point, and its src-only compile would evict the artifacts built above. +COPY script/contract-bindings.sh script/contract-bindings.sh +RUN just bind # builds test programs and create anvil state dump. # requires compiled smart contracts. diff --git a/test/e2e/rollups/justfile b/test/e2e/rollups/justfile index 35b02914..e3a5a94e 100644 --- a/test/e2e/rollups/justfile +++ b/test/e2e/rollups/justfile @@ -32,10 +32,10 @@ test PROGRAM SCENARIO: (preflight PROGRAM SCENARIO) ANVIL_LOAD_PATH=`realpath {{ANVIL_LOAD_PATH}}` \ TEMPLATE_MACHINE=`realpath "../../../test/programs/$1/machine-image"` \ TEMPLATE_MACHINE_HASH=`cartesi-machine-stored-hash "../../../test/programs/$1/machine-image"` \ - DAVE_APP_FACTORY=`jq -r .address {{DEPLOYMENTS_DIR}}/DaveAppFactory.json` \ - INPUT_BOX=`jq -r .address {{DEPLOYMENTS_DIR}}/InputBox.json` \ - ERC20_PORTAL=`jq -r .address {{DEPLOYMENTS_DIR}}/ERC20Portal.json` \ - ERC20_TOKEN=`jq -r .address {{DEPLOYMENTS_DIR}}/TestFungibleToken.json` \ + DAVE_APP_FACTORY=`cat {{DEPLOYMENTS_DIR}}/DaveAppFactory.txt` \ + INPUT_BOX=`cat {{DEPLOYMENTS_DIR}}/InputBox.txt` \ + ERC20_PORTAL=`cat {{DEPLOYMENTS_DIR}}/Erc20Portal.txt` \ + ERC20_TOKEN=`cat {{DEPLOYMENTS_DIR}}/TestFungibleToken.txt` \ lua5.4 "scenarios/$2.lua" # run PRT rollups echo test diff --git a/test/e2e/rollups/scenarios/deposit_withdrawal.lua b/test/e2e/rollups/scenarios/deposit_withdrawal.lua index 87138676..695fcb5b 100755 --- a/test/e2e/rollups/scenarios/deposit_withdrawal.lua +++ b/test/e2e/rollups/scenarios/deposit_withdrawal.lua @@ -77,7 +77,7 @@ assert( -- (This makes the portal send an input to the app) env.sender:_send_tx( ERC20_PORTAL_ADDRESS, - "depositERC20Tokens(address,address,uint256,bytes)", + "depositErc20Tokens(address,address,uint256,bytes)", {ERC20_TOKEN_ADDRESS, env.app_address, ERC20_AMOUNT, "0x"} ) diff --git a/test/programs/honeypot/generate-devnet-honeypot-config.sh b/test/programs/honeypot/generate-devnet-honeypot-config.sh index dc4b27f2..90118605 100755 --- a/test/programs/honeypot/generate-devnet-honeypot-config.sh +++ b/test/programs/honeypot/generate-devnet-honeypot-config.sh @@ -18,10 +18,10 @@ get_devnet_deployment_address() { [[ "$contract_name" =~ ^[a-zA-Z_$][a-zA-Z0-9_$]*$ ]] || (>&2 echo "$contract_name is not a valid contract name." && exit 1) - jq -r .address "cartesi-rollups/contracts/deployments/31337/${contract_name}.json" + cat "cartesi-rollups/contracts/deployments/31337/${contract_name}.txt" } -ERC20_PORTAL_ADDRESS=$(get_devnet_deployment_address ERC20Portal) +ERC20_PORTAL_ADDRESS=$(get_devnet_deployment_address Erc20Portal) ERC20_WITHDRAWAL_ADDRESS='0x70997970C51812dc3A010C7d01b50e0d17dc79C8' ERC20_TOKEN_ADDRESS=$(get_devnet_deployment_address TestFungibleToken)