diff --git a/src/HdpExecutionStore.sol b/src/HdpExecutionStore.sol index 1945819..4a77ab2 100644 --- a/src/HdpExecutionStore.sol +++ b/src/HdpExecutionStore.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.20; import {MerkleProof} from "openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol"; +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import {IFactsRegistry} from "./interfaces/IFactsRegistry.sol"; @@ -9,10 +10,7 @@ import {ISharpFactsAggregator} from "./interfaces/ISharpFactsAggregator.sol"; import {IAggregatorsFactory} from "./interfaces/IAggregatorsFactory.sol"; import {BlockSampledDatalake, BlockSampledDatalakeCodecs} from "./datatypes/datalake/BlockSampledDatalakeCodecs.sol"; -import { - TransactionsInBlockDatalake, - TransactionsInBlockDatalakeCodecs -} from "./datatypes/datalake/TransactionsInBlockDatalakeCodecs.sol"; +import {TransactionsInBlockDatalake, TransactionsInBlockDatalakeCodecs} from "./datatypes/datalake/TransactionsInBlockDatalakeCodecs.sol"; import {ComputationalTask, ComputationalTaskCodecs} from "./datatypes/datalake/ComputeCodecs.sol"; import {ModuleTask, ModuleCodecs} from "./datatypes/module/ModuleCodecs.sol"; @@ -30,7 +28,11 @@ error NotFinalized(); /// @title HdpExecutionStore /// @author Herodotus Dev Ltd /// @notice A contract to store the execution results of HDP tasks -contract HdpExecutionStore is UUPSUpgradeable, OwnableUpgradeable { +contract HdpExecutionStore is + Initializable, + UUPSUpgradeable, + OwnableUpgradeable +{ using MerkleProof for bytes32[]; using BlockSampledDatalakeCodecs for BlockSampledDatalake; using TransactionsInBlockDatalakeCodecs for TransactionsInBlockDatalake; @@ -54,10 +56,16 @@ contract HdpExecutionStore is UUPSUpgradeable, OwnableUpgradeable { event MmrRootCached(uint256 mmrId, uint256 mmrSize, bytes32 mmrRoot); /// @notice emitted when a new task with block sampled datalake is scheduled - event TaskWithBlockSampledDatalakeScheduled(BlockSampledDatalake datalake, ComputationalTask task); + event TaskWithBlockSampledDatalakeScheduled( + BlockSampledDatalake datalake, + ComputationalTask task + ); /// @notice emitted when a new task with transactions in block datalake is scheduled - event TaskWithTransactionsInBlockDatalakeScheduled(TransactionsInBlockDatalake datalake, ComputationalTask task); + event TaskWithTransactionsInBlockDatalakeScheduled( + TransactionsInBlockDatalake datalake, + ComputationalTask task + ); /// @notice emitted when a new module task is scheduled event ModuleTaskScheduled(ModuleTask moduleTask); @@ -78,12 +86,14 @@ contract HdpExecutionStore is UUPSUpgradeable, OwnableUpgradeable { mapping(bytes32 => TaskResult) public cachedTasksResult; /// @notice mapping of chain id => mmr id => mmr size => mmr root - mapping(uint256 => mapping(uint256 => mapping(uint256 => bytes32))) public cachedMMRsRoots; - - function initialize(IFactsRegistry factsRegistry, IAggregatorsFactory aggregatorsFactory, bytes32 programHash) - public - initializer - { + mapping(uint256 => mapping(uint256 => mapping(uint256 => bytes32))) + public cachedMMRsRoots; + + function initialize( + IFactsRegistry factsRegistry, + IAggregatorsFactory aggregatorsFactory, + bytes32 programHash + ) public initializer { __Ownable_init(msg.sender); __UUPSUpgradeable_init(); @@ -94,7 +104,9 @@ contract HdpExecutionStore is UUPSUpgradeable, OwnableUpgradeable { } /// @dev Allow to set a new implementation - function _authorizeUpgrade(address newImplementation) internal override onlyOwner {} + function _authorizeUpgrade( + address newImplementation + ) internal override onlyOwner {} /// @notice Set the program hash for the HDP program function setProgramHash(bytes32 programHash) external onlyOwner { @@ -108,11 +120,20 @@ contract HdpExecutionStore is UUPSUpgradeable, OwnableUpgradeable { /// @notice Caches the MMR root for a given MMR id /// @notice Get MMR size and root from the aggregator and cache it function cacheMmrRoot(uint256 mmrId) public { - ISharpFactsAggregator aggregator = AGGREGATORS_FACTORY.aggregatorsById(mmrId); - ISharpFactsAggregator.AggregatorState memory aggregatorState = aggregator.aggregatorState(); - cachedMMRsRoots[CHAIN_ID][mmrId][aggregatorState.mmrSize] = aggregatorState.poseidonMmrRoot; - - emit MmrRootCached(mmrId, aggregatorState.mmrSize, aggregatorState.poseidonMmrRoot); + ISharpFactsAggregator aggregator = AGGREGATORS_FACTORY.aggregatorsById( + mmrId + ); + ISharpFactsAggregator.AggregatorState + memory aggregatorState = aggregator.aggregatorState(); + cachedMMRsRoots[CHAIN_ID][mmrId][ + aggregatorState.mmrSize + ] = aggregatorState.poseidonMmrRoot; + + emit MmrRootCached( + mmrId, + aggregatorState.mmrSize, + aggregatorState.poseidonMmrRoot + ); } /// @notice Requests the execution of a task with a block sampled datalake @@ -131,9 +152,15 @@ contract HdpExecutionStore is UUPSUpgradeable, OwnableUpgradeable { } // Store the task result - cachedTasksResult[taskCommitment] = TaskResult({status: TaskStatus.SCHEDULED, result: ""}); - - emit TaskWithBlockSampledDatalakeScheduled(blockSampledDatalake, computationalTask); + cachedTasksResult[taskCommitment] = TaskResult({ + status: TaskStatus.SCHEDULED, + result: "" + }); + + emit TaskWithBlockSampledDatalakeScheduled( + blockSampledDatalake, + computationalTask + ); } /// @notice Requests the execution of a task with a transactions in block datalake @@ -152,14 +179,22 @@ contract HdpExecutionStore is UUPSUpgradeable, OwnableUpgradeable { } // Store the task result - cachedTasksResult[taskCommitment] = TaskResult({status: TaskStatus.SCHEDULED, result: ""}); - - emit TaskWithTransactionsInBlockDatalakeScheduled(transactionsInBlockDatalake, computationalTask); + cachedTasksResult[taskCommitment] = TaskResult({ + status: TaskStatus.SCHEDULED, + result: "" + }); + + emit TaskWithTransactionsInBlockDatalakeScheduled( + transactionsInBlockDatalake, + computationalTask + ); } /// @notice Requests the execution of a task with a module /// @param moduleTask module task - function requestExecutionOfModuleTask(ModuleTask calldata moduleTask) external { + function requestExecutionOfModuleTask( + ModuleTask calldata moduleTask + ) external { bytes32 taskCommitment = moduleTask.commit(); // Ensure task is not already scheduled @@ -168,7 +203,10 @@ contract HdpExecutionStore is UUPSUpgradeable, OwnableUpgradeable { } // Store the task result - cachedTasksResult[taskCommitment] = TaskResult({status: TaskStatus.SCHEDULED, result: ""}); + cachedTasksResult[taskCommitment] = TaskResult({ + status: TaskStatus.SCHEDULED, + result: "" + }); emit ModuleTaskScheduled(moduleTask); } @@ -220,7 +258,9 @@ contract HdpExecutionStore is UUPSUpgradeable, OwnableUpgradeable { bytes32 programOutputHash = keccak256(abi.encodePacked(programOutput)); // Compute GPS fact hash - bytes32 gpsFactHash = keccak256(abi.encode(PROGRAM_HASH, programOutputHash)); + bytes32 gpsFactHash = keccak256( + abi.encode(PROGRAM_HASH, programOutputHash) + ); // Ensure GPS fact is registered if (!SHARP_FACTS_REGISTRY.isValid(gpsFactHash)) { @@ -234,42 +274,63 @@ contract HdpExecutionStore is UUPSUpgradeable, OwnableUpgradeable { bytes32[] memory resultInclusionProof = resultsInclusionProofs[i]; // Convert the low and high 128 bits to a single 256 bit value - bytes32 resultMerkleRoot = bytes32((resultMerkleRootHigh << 128) | resultMerkleRootLow); - bytes32 taskMerkleRoot = bytes32((taskMerkleRootHigh << 128) | taskMerkleRootLow); + bytes32 resultMerkleRoot = bytes32( + (resultMerkleRootHigh << 128) | resultMerkleRootLow + ); + bytes32 taskMerkleRoot = bytes32( + (taskMerkleRootHigh << 128) | taskMerkleRootLow + ); // Compute the Merkle leaf of the task bytes32 taskCommitment = taskCommitments[i]; bytes32 taskMerkleLeaf = standardLeafHash(taskCommitment); // Ensure that the task is included in the batch, by verifying the Merkle proof - bool isVerifiedTask = taskInclusionProof.verify(taskMerkleRoot, taskMerkleLeaf); + bool isVerifiedTask = taskInclusionProof.verify( + taskMerkleRoot, + taskMerkleLeaf + ); if (!isVerifiedTask) { revert NotInBatch(); } // Compute the Merkle leaf of the task result - bytes32 taskResultCommitment = keccak256(abi.encode(taskCommitment, computationalTaskResult)); - bytes32 taskResultMerkleLeaf = standardLeafHash(taskResultCommitment); + bytes32 taskResultCommitment = keccak256( + abi.encode(taskCommitment, computationalTaskResult) + ); + bytes32 taskResultMerkleLeaf = standardLeafHash( + taskResultCommitment + ); // Ensure that the task result is included in the batch, by verifying the Merkle proof - bool isVerifiedResult = resultInclusionProof.verify(resultMerkleRoot, taskResultMerkleLeaf); + bool isVerifiedResult = resultInclusionProof.verify( + resultMerkleRoot, + taskResultMerkleLeaf + ); if (!isVerifiedResult) { revert NotInBatch(); } // Store the task result - cachedTasksResult[taskCommitment] = - TaskResult({status: TaskStatus.FINALIZED, result: computationalTaskResult}); + cachedTasksResult[taskCommitment] = TaskResult({ + status: TaskStatus.FINALIZED, + result: computationalTaskResult + }); } } /// @notice Load MMR root from cache with given mmrId and mmrSize - function loadMmrRoot(uint256 mmrId, uint256 mmrSize) public view returns (bytes32) { + function loadMmrRoot( + uint256 mmrId, + uint256 mmrSize + ) public view returns (bytes32) { return cachedMMRsRoots[CHAIN_ID][mmrId][mmrSize]; } /// @notice Returns the result of a finalized task - function getFinalizedTaskResult(bytes32 taskCommitment) external view returns (bytes32) { + function getFinalizedTaskResult( + bytes32 taskCommitment + ) external view returns (bytes32) { // Ensure task is finalized if (cachedTasksResult[taskCommitment].status != TaskStatus.FINALIZED) { revert NotFinalized(); @@ -278,7 +339,9 @@ contract HdpExecutionStore is UUPSUpgradeable, OwnableUpgradeable { } /// @notice Returns the status of a task - function getTaskStatus(bytes32 taskCommitment) external view returns (TaskStatus) { + function getTaskStatus( + bytes32 taskCommitment + ) external view returns (TaskStatus) { return cachedTasksResult[taskCommitment].status; }