Skip to content

Commit 486dd2a

Browse files
committed
Refactor DataProcessor module to support multiple program hashes and improve task authentication and calldata input
1 parent 6ae2e93 commit 486dd2a

File tree

2 files changed

+67
-36
lines changed

2 files changed

+67
-36
lines changed

src/interfaces/modules/IDataProcessorModule.sol

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ interface IDataProcessorModule is IFactsRegistryCommon {
2121

2222
/// @notice Storage structure for the module
2323
struct DataProcessorModuleStorage {
24-
bytes32 programHash;
2524
IFactsRegistry factsRegistry;
2625
mapping(bytes32 => TaskResult) cachedTasksResult;
26+
mapping(bytes32 => bool) authorizedProgramHashes;
2727
}
2828

2929
struct MmrData {
@@ -32,15 +32,19 @@ interface IDataProcessorModule is IFactsRegistryCommon {
3232
uint256 mmrSize;
3333
}
3434

35+
/// @param mmrData For each used MMR, its chain ID, ID and size
36+
/// @param taskResultLow The low part of the task result
37+
/// @param taskResultHigh The high part of the task result
38+
/// @param taskHashLow The low part of the task hash
39+
/// @param taskHashHigh The high part of the task hash
40+
/// @param programHash The program hash that was used to compute the task
3541
struct TaskData {
36-
/// @dev The Merkle proof of the task
37-
bytes32[] taskInclusionProof;
38-
/// @dev The Merkle proof of the result
39-
bytes32[] resultInclusionProof;
40-
/// @dev The commitment of the task
41-
bytes32 commitment;
42-
/// @dev The result of the computational task
43-
bytes32 result;
42+
MmrData[] mmrData;
43+
uint256 taskResultLow;
44+
uint256 taskResultHigh;
45+
uint256 taskHashLow;
46+
uint256 taskHashHigh;
47+
bytes32 programHash;
4448
}
4549

4650
/// @notice emitted when a task already stored
@@ -55,32 +59,41 @@ interface IDataProcessorModule is IFactsRegistryCommon {
5559
error NotInBatch();
5660
/// Task is not finalized
5761
error NotFinalized();
62+
/// Unauthorized or inactive program hash
63+
error UnauthorizedProgramHash();
64+
/// Invalid MMR root
65+
error InvalidMmrRoot();
66+
67+
/// @notice Emitted when a program hash is enabled
68+
event ProgramHashEnabled(bytes32 enabledProgramHash);
69+
70+
/// @notice Emitted when some program hashes are disabled
71+
event ProgramHashesDisabled(bytes32[] disabledProgramHashes);
5872

5973
/// @notice Set the program hash for the HDP program
6074
function setDataProcessorProgramHash(bytes32 programHash) external;
6175

76+
/// @notice Disable some program hashes
77+
function disableProgramHashes(bytes32[] calldata programHashes) external;
78+
6279
/// @notice Set the facts registry contract
6380
function setDataProcessorFactsRegistry(IFactsRegistry factsRegistry) external;
6481

65-
/// @notice Get the program hash
66-
function getDataProcessorProgramHash() external view returns (bytes32);
67-
6882
/// @notice Requests the execution of a task with a module
6983
/// @param moduleTask module task
7084
function requestDataProcessorExecutionOfTask(ModuleTask calldata moduleTask) external;
7185

7286
/// @notice Authenticates the execution of a task is finalized
7387
/// by verifying the locally computed fact with the FactsRegistry
74-
/// @param mmrData For each used MMR, its chain ID, ID and size
75-
/// @param taskResultLow The low part of the task result
76-
/// @param taskResultHigh The high part of the task result
77-
/// @param taskHashLow The low part of the task hash
78-
/// @param taskHashHigh The high part of the task hash
79-
function authenticateDataProcessorTaskExecution(MmrData[] calldata mmrData, uint256 taskResultLow, uint256 taskResultHigh, uint256 taskHashLow, uint256 taskHashHigh) external;
88+
/// @param taskData The task data
89+
function authenticateDataProcessorTaskExecution(TaskData calldata taskData) external;
8090

8191
/// @notice Returns the result of a finalized task
8292
function getDataProcessorFinalizedTaskResult(bytes32 taskCommitment) external view returns (bytes32);
8393

8494
/// @notice Returns the status of a task
8595
function getDataProcessorTaskStatus(bytes32 taskCommitment) external view returns (TaskStatus);
96+
97+
/// @notice Checks if a program hash is currently authorized
98+
function isProgramHashAuthorized(bytes32 programHash) external view returns (bool);
8699
}

src/modules/DataProcessorModule.sol

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {LibSatellite} from "src/libraries/LibSatellite.sol";
88
import {ModuleTask, ModuleCodecs} from "src/libraries/internal/data-processor/ModuleCodecs.sol";
99
import {IDataProcessorModule} from "src/interfaces/modules/IDataProcessorModule.sol";
1010
import {AccessController} from "src/libraries/AccessController.sol";
11+
1112
/// @title DataProcessorModule
1213
/// @author Herodotus Dev Ltd
1314
/// @notice A contract to store the execution results of HDP tasks
@@ -37,7 +38,18 @@ contract DataProcessorModule is IDataProcessorModule, AccessController {
3738
/// @inheritdoc IDataProcessorModule
3839
function setDataProcessorProgramHash(bytes32 programHash) external onlyOwner {
3940
DataProcessorModuleStorage storage ms = moduleStorage();
40-
ms.programHash = programHash;
41+
ms.authorizedProgramHashes[programHash] = true;
42+
emit ProgramHashEnabled(programHash);
43+
}
44+
45+
/// @inheritdoc IDataProcessorModule
46+
function disableProgramHashes(bytes32[] calldata programHashes) external onlyOwner {
47+
DataProcessorModuleStorage storage ms = moduleStorage();
48+
49+
for (uint256 i = 0; i < programHashes.length; i++) {
50+
ms.authorizedProgramHashes[programHashes[i]] = false;
51+
}
52+
emit ProgramHashesDisabled(programHashes);
4153
}
4254

4355
/// @inheritdoc IDataProcessorModule
@@ -69,23 +81,29 @@ contract DataProcessorModule is IDataProcessorModule, AccessController {
6981
}
7082

7183
/// @inheritdoc IDataProcessorModule
72-
function authenticateDataProcessorTaskExecution(MmrData[] calldata mmrData, uint256 taskResultLow, uint256 taskResultHigh, uint256 taskHashLow, uint256 taskHashHigh) external {
84+
function authenticateDataProcessorTaskExecution(TaskData calldata taskData) external {
7385
DataProcessorModuleStorage storage ms = moduleStorage();
7486

87+
if (!isProgramHashAuthorized(taskData.programHash)) {
88+
revert UnauthorizedProgramHash();
89+
}
90+
7591
// Initialize an array of uint256 to store the program output
76-
uint256[] memory programOutput = new uint256[](3 + mmrData.length * 4);
92+
uint256[] memory programOutput = new uint256[](3 + taskData.mmrData.length * 4);
7793

7894
// Assign values to the program output array
7995
// This needs to be compatible with cairo program
8096
// https://github.com/HerodotusDev/hdp-cairo/blob/main/src/utils/utils.cairo#L27-L48
81-
programOutput[0] = uint256(ms.programHash);
82-
programOutput[1] = taskResultLow;
83-
programOutput[2] = taskResultHigh;
97+
programOutput[0] = uint256(taskData.programHash);
98+
programOutput[1] = taskData.taskResultLow;
99+
programOutput[2] = taskData.taskResultHigh;
84100

85-
for (uint8 i = 0; i < mmrData.length; i++) {
86-
MmrData memory mmr = mmrData[i];
101+
for (uint8 i = 0; i < taskData.mmrData.length; i++) {
102+
MmrData memory mmr = taskData.mmrData[i];
87103
bytes32 usedMmrRoot = loadMmrRoot(mmr.mmrId, mmr.mmrSize, mmr.chainId);
88-
require(usedMmrRoot != bytes32(0), "Could not retrieve MMR root");
104+
if (usedMmrRoot == bytes32(0)) {
105+
revert InvalidMmrRoot();
106+
}
89107
programOutput[3 + i * 4] = mmr.mmrId;
90108
programOutput[3 + i * 4 + 1] = mmr.mmrSize;
91109
programOutput[3 + i * 4 + 2] = mmr.chainId;
@@ -96,28 +114,22 @@ contract DataProcessorModule is IDataProcessorModule, AccessController {
96114
bytes32 programOutputHash = keccak256(abi.encodePacked(programOutput));
97115

98116
// Compute GPS fact hash
99-
bytes32 gpsFactHash = keccak256(abi.encode(ms.programHash, programOutputHash));
117+
bytes32 gpsFactHash = keccak256(abi.encode(taskData.programHash, programOutputHash));
100118

101119
// Ensure GPS fact is registered
102120
if (!ms.factsRegistry.isValid(gpsFactHash)) {
103121
revert InvalidFact();
104122
}
105123

106-
bytes32 taskHash = bytes32((taskHashHigh << 128) | taskHashLow);
107-
bytes32 taskResult = bytes32((taskResultHigh << 128) | taskResultLow);
124+
bytes32 taskHash = bytes32((taskData.taskHashHigh << 128) | taskData.taskHashLow);
125+
bytes32 taskResult = bytes32((taskData.taskResultHigh << 128) | taskData.taskResultLow);
108126

109127
// Store the task result
110128
ms.cachedTasksResult[taskHash] = TaskResult({status: TaskStatus.FINALIZED, result: taskResult});
111129
}
112130

113131
// ========================= View Functions ========================= //
114132

115-
/// @inheritdoc IDataProcessorModule
116-
function getDataProcessorProgramHash() external view returns (bytes32) {
117-
DataProcessorModuleStorage storage ms = moduleStorage();
118-
return ms.programHash;
119-
}
120-
121133
/// @inheritdoc IDataProcessorModule
122134
function getDataProcessorFinalizedTaskResult(bytes32 taskCommitment) external view returns (bytes32) {
123135
DataProcessorModuleStorage storage ms = moduleStorage();
@@ -134,6 +146,12 @@ contract DataProcessorModule is IDataProcessorModule, AccessController {
134146
return ms.cachedTasksResult[taskCommitment].status;
135147
}
136148

149+
/// @inheritdoc IDataProcessorModule
150+
function isProgramHashAuthorized(bytes32 programHash) public view returns (bool) {
151+
DataProcessorModuleStorage storage ms = moduleStorage();
152+
return ms.authorizedProgramHashes[programHash];
153+
}
154+
137155
// ========================= Internal Functions ========================= //
138156

139157
/// @notice Load MMR root from cache with given mmrId and mmrSize

0 commit comments

Comments
 (0)