@cofhe/mock-contracts 0.7.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +10 -0
- package/contracts/MockACL.sol +33 -15
- package/contracts/MockCoFHE.sol +165 -74
- package/contracts/MockCoFHEAddressBook.sol +64 -0
- package/contracts/MockTaskManager.sol +74 -24
- package/contracts/MockZkVerifier.sol +2 -2
- package/dist/index.d.mts +291 -20
- package/dist/index.d.ts +291 -20
- package/dist/index.js +224 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +224 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/MockACL.ts +37 -13
- package/src/MockCoFHEAddressBook.ts +114 -0
- package/src/MockTaskManager.ts +73 -1
- package/src/index.ts +2 -0
- package/src/typechain-types/MockACL.ts +38 -6
- package/src/typechain-types/MockCoFHEAddressBook.ts +124 -0
- package/src/typechain-types/MockTaskManager.ts +66 -1
- package/src/typechain-types/index.ts +1 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
|
2
|
+
pragma solidity >=0.8.19 <0.9.0;
|
|
3
|
+
|
|
4
|
+
import { ICoFHEAddressBook } from '@fhenixprotocol/cofhe-contracts/ICofhe.sol';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @title MockCoFHEAddressBook
|
|
8
|
+
* @notice Mock of the CoFHEAddressBook: maps a TaskManager id to the TaskManager that FHE.sol
|
|
9
|
+
* releases pinned to that id talk to. Deployed to `COFHE_ADDRESS_BOOK` (from FHE.sol)
|
|
10
|
+
* with `hardhat_setCode` / `deployCodeTo`, so no constructor or initializer runs.
|
|
11
|
+
* @dev The production book is an Ownable2Step UUPS proxy; setters here are unrestricted.
|
|
12
|
+
*/
|
|
13
|
+
contract MockCoFHEAddressBook is ICoFHEAddressBook {
|
|
14
|
+
mapping(uint256 id => address tm) private taskManagers;
|
|
15
|
+
|
|
16
|
+
/// @notice Emitted when an id is set or unset (`current == address(0)`).
|
|
17
|
+
/// @param id TaskManager id.
|
|
18
|
+
/// @param previous Address the id resolved to before, zero if it was unset.
|
|
19
|
+
/// @param current Address the id resolves to now, zero if it was unset.
|
|
20
|
+
event TaskManagerSet(uint256 indexed id, address indexed previous, address indexed current);
|
|
21
|
+
|
|
22
|
+
/// @notice Returned when an id resolves to nothing.
|
|
23
|
+
/// @param id TaskManager id.
|
|
24
|
+
error TaskManagerNotSet(uint256 id);
|
|
25
|
+
|
|
26
|
+
/// @notice Returned when setting an id to the zero address.
|
|
27
|
+
error InvalidAddress();
|
|
28
|
+
|
|
29
|
+
function exists() public pure returns (bool) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/// @notice Resolves an id to its TaskManager.
|
|
34
|
+
/// @param id TaskManager id.
|
|
35
|
+
/// @return tm The TaskManager address; reverts with {TaskManagerNotSet} when unset.
|
|
36
|
+
function getTm(uint256 id) external view returns (address tm) {
|
|
37
|
+
tm = taskManagers[id];
|
|
38
|
+
if (tm == address(0)) {
|
|
39
|
+
revert TaskManagerNotSet(id);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/// @notice Points an id at a TaskManager, replacing any previous target.
|
|
44
|
+
/// @param id TaskManager id.
|
|
45
|
+
/// @param tm TaskManager address.
|
|
46
|
+
function setTm(uint256 id, address tm) external {
|
|
47
|
+
if (tm == address(0)) {
|
|
48
|
+
revert InvalidAddress();
|
|
49
|
+
}
|
|
50
|
+
emit TaskManagerSet(id, taskManagers[id], tm);
|
|
51
|
+
taskManagers[id] = tm;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/// @notice Retires an id: every FHE.sol build pinned to it reverts from then on.
|
|
55
|
+
/// @param id TaskManager id.
|
|
56
|
+
function unsetTm(uint256 id) external {
|
|
57
|
+
address previous = taskManagers[id];
|
|
58
|
+
if (previous == address(0)) {
|
|
59
|
+
revert TaskManagerNotSet(id);
|
|
60
|
+
}
|
|
61
|
+
emit TaskManagerSet(id, previous, address(0));
|
|
62
|
+
delete taskManagers[id];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -263,22 +263,63 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
|
|
|
263
263
|
return true;
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
-
|
|
267
|
-
if (inputs.length == 1 || opIs(operation, FunctionId.cast)) {
|
|
268
|
-
emit TaskCreated(ctHash, operation, inputs[0], 0, 0);
|
|
266
|
+
error OnlySelf();
|
|
269
267
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
268
|
+
function sendEventCreated(
|
|
269
|
+
uint256 ctHash,
|
|
270
|
+
FunctionId funcId,
|
|
271
|
+
string memory operation,
|
|
272
|
+
uint256[] memory inputs
|
|
273
|
+
) private {
|
|
274
|
+
uint8 arity = (inputs.length == 1 || funcId == FunctionId.cast) ? 1 : (inputs.length == 2 ? 2 : 3);
|
|
274
275
|
|
|
275
|
-
|
|
276
|
-
|
|
276
|
+
if (arity == 1) {
|
|
277
|
+
emit TaskCreated(ctHash, operation, inputs[0], 0, 0);
|
|
278
|
+
} else if (arity == 2) {
|
|
279
|
+
emit TaskCreated(ctHash, operation, inputs[0], inputs[1], 0);
|
|
277
280
|
} else {
|
|
278
281
|
emit TaskCreated(ctHash, operation, inputs[0], inputs[1], inputs[2]);
|
|
282
|
+
}
|
|
279
283
|
|
|
280
|
-
|
|
281
|
-
|
|
284
|
+
// NOTE: MOCK - plaintext replication is mock-only work that doesn't exist in the real
|
|
285
|
+
// task manager, so (under forge, when enabled) it runs with gas metering paused; when
|
|
286
|
+
// metered (hardhat) its cost is reported via MockGasConsumed instead.
|
|
287
|
+
(MockGasMode mode, uint256 startGas) = _mockGasTrackStart();
|
|
288
|
+
if (mode != MockGasMode.PAUSED_BY_MOCK) {
|
|
289
|
+
// MEASURE, or the caller's test already paused metering (nothing of ours to leak
|
|
290
|
+
// on revert in either case).
|
|
291
|
+
_mockDispatch(ctHash, funcId, inputs, arity);
|
|
292
|
+
_mockGasTrackEnd(mode, startGas);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// External self-call so a revert inside the mock op can be caught and gas metering
|
|
297
|
+
// resumed before bubbling the original error - otherwise the paused state leaks into
|
|
298
|
+
// the rest of the test and every later call reports ~0 gas. The extra call itself
|
|
299
|
+
// runs unmetered.
|
|
300
|
+
try this.MOCK_dispatchOperation(ctHash, funcId, inputs, arity) {
|
|
301
|
+
_mockGasTrackEnd(mode, startGas);
|
|
302
|
+
} catch (bytes memory err) {
|
|
303
|
+
_mockGasTrackEnd(mode, startGas);
|
|
304
|
+
assembly ('memory-safe') {
|
|
305
|
+
revert(add(err, 0x20), mload(err))
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/// @dev Trampoline for `sendEventCreated`'s try/catch; not part of the mocked interface.
|
|
311
|
+
function MOCK_dispatchOperation(uint256 ctHash, FunctionId funcId, uint256[] calldata inputs, uint8 arity) external {
|
|
312
|
+
if (msg.sender != address(this)) revert OnlySelf();
|
|
313
|
+
_mockDispatch(ctHash, funcId, inputs, arity);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function _mockDispatch(uint256 ctHash, FunctionId funcId, uint256[] memory inputs, uint8 arity) private {
|
|
317
|
+
if (arity == 1) {
|
|
318
|
+
MOCK_unaryOperation(ctHash, funcId, inputs[0]);
|
|
319
|
+
} else if (arity == 2) {
|
|
320
|
+
MOCK_twoInputOperation(ctHash, funcId, inputs[0], inputs[1]);
|
|
321
|
+
} else {
|
|
322
|
+
MOCK_threeInputOperation(ctHash, funcId, inputs[0], inputs[1], inputs[2]);
|
|
282
323
|
}
|
|
283
324
|
}
|
|
284
325
|
|
|
@@ -299,12 +340,18 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
|
|
|
299
340
|
// );
|
|
300
341
|
// }
|
|
301
342
|
|
|
302
|
-
// NOTE: MOCK
|
|
343
|
+
// NOTE: MOCK - the real task manager only emits a task event here and the result lands
|
|
344
|
+
// in a later transaction; storing it synchronously is mock-only work. Only the cheap
|
|
345
|
+
// existence check runs before the tracked block (so an InputNotInMockStorage revert
|
|
346
|
+
// can't leak paused gas metering); the read itself is mock-only and stays inside.
|
|
347
|
+
MOCK_verifyKeyInStorage(ctHash);
|
|
348
|
+
(MockGasMode mode, uint256 startGas) = _mockGasTrackStart();
|
|
303
349
|
_decryptResultReady[ctHash] = true;
|
|
304
350
|
_decryptResult[ctHash] = _get(ctHash);
|
|
305
351
|
|
|
306
352
|
uint64 asyncOffset = uint64((block.timestamp % 10) + 1);
|
|
307
353
|
_decryptResultReadyTimestamp[ctHash] = uint64(block.timestamp) + asyncOffset;
|
|
354
|
+
_mockGasTrackEnd(mode, startGas);
|
|
308
355
|
}
|
|
309
356
|
|
|
310
357
|
function getDecryptResult(uint256 ctHash) public view returns (uint256) {
|
|
@@ -399,9 +446,11 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
|
|
|
399
446
|
}
|
|
400
447
|
}
|
|
401
448
|
|
|
402
|
-
function validateInputs(
|
|
403
|
-
|
|
404
|
-
|
|
449
|
+
function validateInputs(
|
|
450
|
+
uint256[] memory encryptedHashes,
|
|
451
|
+
FunctionId funcId,
|
|
452
|
+
string memory functionName
|
|
453
|
+
) internal view {
|
|
405
454
|
if (encryptedHashes.length == 0) {
|
|
406
455
|
if (!isPlaintextOperation(funcId)) {
|
|
407
456
|
revert InvalidOperationInputs(functionName);
|
|
@@ -455,19 +504,20 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
|
|
|
455
504
|
if (funcId == FunctionId.random) {
|
|
456
505
|
revert RandomFunctionNotSupported();
|
|
457
506
|
}
|
|
507
|
+
string memory operation = Utils.functionIdToString(funcId);
|
|
458
508
|
uint256 inputsLength = encryptedHashes.length + extraInputs.length;
|
|
459
509
|
if (inputsLength > 3) {
|
|
460
|
-
revert TooManyInputs(
|
|
510
|
+
revert TooManyInputs(operation, inputsLength, 3);
|
|
461
511
|
}
|
|
462
512
|
|
|
463
|
-
validateInputs(encryptedHashes, funcId);
|
|
513
|
+
validateInputs(encryptedHashes, funcId, operation);
|
|
464
514
|
uint256[] memory inputs = TMCommon.combineInputs(encryptedHashes, extraInputs);
|
|
465
515
|
|
|
466
516
|
int32 securityZone = getSecurityZone(funcId, encryptedHashes, extraInputs);
|
|
467
517
|
uint256 ctHash = TMCommon.calcPlaceholderKey(returnType, securityZone, inputs, funcId);
|
|
468
518
|
|
|
469
519
|
acl.allowTransient(ctHash, msg.sender, address(this));
|
|
470
|
-
sendEventCreated(ctHash,
|
|
520
|
+
sendEventCreated(ctHash, funcId, operation, inputs);
|
|
471
521
|
|
|
472
522
|
return ctHash;
|
|
473
523
|
}
|
|
@@ -611,7 +661,7 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
|
|
|
611
661
|
acl.allow(ctHash, account, msg.sender);
|
|
612
662
|
|
|
613
663
|
// NOTE: MOCK
|
|
614
|
-
|
|
664
|
+
MOCK_trackedLogAllow(account == msg.sender ? 'FHE.allowThis' : 'FHE.allow', ctHash, account);
|
|
615
665
|
}
|
|
616
666
|
}
|
|
617
667
|
|
|
@@ -620,7 +670,7 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
|
|
|
620
670
|
acl.allowGlobal(ctHash, msg.sender);
|
|
621
671
|
|
|
622
672
|
// NOTE: MOCK
|
|
623
|
-
|
|
673
|
+
MOCK_trackedLogAllow('FHE.allowGlobal', ctHash, msg.sender);
|
|
624
674
|
}
|
|
625
675
|
}
|
|
626
676
|
|
|
@@ -629,7 +679,7 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
|
|
|
629
679
|
acl.allowTransient(ctHash, account, msg.sender);
|
|
630
680
|
|
|
631
681
|
// NOTE: MOCK
|
|
632
|
-
|
|
682
|
+
MOCK_trackedLogAllow('FHE.allowTransient', ctHash, account);
|
|
633
683
|
}
|
|
634
684
|
}
|
|
635
685
|
|
|
@@ -640,7 +690,7 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
|
|
|
640
690
|
acl.allowForDecryption(hashes, msg.sender);
|
|
641
691
|
|
|
642
692
|
// NOTE: MOCK
|
|
643
|
-
|
|
693
|
+
MOCK_trackedLogAllow('FHE.allowForDecryption', ctHash, msg.sender);
|
|
644
694
|
}
|
|
645
695
|
}
|
|
646
696
|
|
|
@@ -655,14 +705,14 @@ contract MockTaskManager is ITaskManager, MockCoFHE {
|
|
|
655
705
|
acl.shareCtHash(ctHash, msg.sender, receiver);
|
|
656
706
|
|
|
657
707
|
// NOTE: MOCK
|
|
658
|
-
|
|
708
|
+
MOCK_trackedLogAllow('FHE.share', ctHash, receiver);
|
|
659
709
|
}
|
|
660
710
|
|
|
661
711
|
function receiveCtHash(uint256 ctHash, address expectedSharer) external {
|
|
662
712
|
acl.receiveCtHash(ctHash, expectedSharer, msg.sender);
|
|
663
713
|
|
|
664
714
|
// NOTE: MOCK
|
|
665
|
-
|
|
715
|
+
MOCK_trackedLogAllow('FHE.receive', ctHash, expectedSharer);
|
|
666
716
|
}
|
|
667
717
|
|
|
668
718
|
/// @dev Per-input message hash used by batch verification:
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
pragma solidity >=0.8.19 <0.9.0;
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { Common } from '@fhenixprotocol/cofhe-contracts/FHE.sol';
|
|
7
7
|
import { EncryptedInput } from '@fhenixprotocol/cofhe-contracts/ICofhe.sol';
|
|
8
8
|
import { MockTaskManager } from './MockTaskManager.sol';
|
|
9
9
|
|
|
@@ -104,7 +104,7 @@ contract MockZkVerifier {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
function insertCtHash(uint256 ctHash, uint256 value) public {
|
|
107
|
-
MockTaskManager(
|
|
107
|
+
MockTaskManager(address(Common.tm())).MOCK_setInEuintKey(ctHash, value);
|
|
108
108
|
salt += 1;
|
|
109
109
|
}
|
|
110
110
|
|