Skip to content

Commit 0993dc1

Browse files
committed
chore(host-contracts): adding failing test to show edge case bug in mocked relayer
1 parent aa896a6 commit 0993dc1

2 files changed

Lines changed: 97 additions & 0 deletions

File tree

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// SPDX-License-Identifier: BSD-3-Clause-Clear
2+
3+
pragma solidity ^0.8.24;
4+
5+
import "../lib/FHE.sol";
6+
import {CoprocessorSetup} from "../lib/CoprocessorSetup.sol";
7+
8+
/// @notice First contract for testing asynchronous decryption via multiple contracts
9+
contract TestAsyncDecryptA {
10+
euint64 xUint64;
11+
uint64 public yUint64;
12+
13+
constructor() {
14+
FHE.setCoprocessor(CoprocessorSetup.defaultConfig());
15+
xUint64 = FHE.asEuint64(424242);
16+
FHE.allowThis(xUint64);
17+
}
18+
19+
function requestUint64() public {
20+
bytes32[] memory cts = new bytes32[](1);
21+
cts[0] = FHE.toBytes32(xUint64);
22+
FHE.requestDecryption(cts, this.callbackUint64.selector);
23+
}
24+
25+
function callbackUint64(uint256 requestID, bytes memory cleartexts, bytes memory decryptionProof) public {
26+
FHE.checkSignatures(requestID, cleartexts, decryptionProof);
27+
uint64 decryptedInput = abi.decode(cleartexts, (uint64));
28+
yUint64 = decryptedInput;
29+
revert();
30+
}
31+
}
32+
33+
/// @notice Second contract for testing asynchronous decryption via multiple contracts
34+
contract TestAsyncDecryptB {
35+
euint64 xUint64;
36+
uint64 public yUint64;
37+
38+
constructor() {
39+
FHE.setCoprocessor(CoprocessorSetup.defaultConfig());
40+
xUint64 = FHE.asEuint64(373737);
41+
FHE.allowThis(xUint64);
42+
}
43+
44+
function requestUint64() public {
45+
bytes32[] memory cts = new bytes32[](1);
46+
cts[0] = FHE.toBytes32(xUint64);
47+
FHE.requestDecryption(cts, this.callbackUint64.selector);
48+
}
49+
50+
function callbackUint64(uint256 requestID, bytes memory cleartexts, bytes memory decryptionProof) public {
51+
FHE.checkSignatures(requestID, cleartexts, decryptionProof);
52+
uint64 decryptedInput = abi.decode(cleartexts, (uint64));
53+
yUint64 = decryptedInput;
54+
}
55+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { expect } from 'chai';
2+
import { ethers, network } from 'hardhat';
3+
4+
import { awaitAllDecryptionResults, initDecryptionOracle } from '../asyncDecrypt';
5+
import { createInstances } from '../instance';
6+
import { getSigners, initSigners } from '../signers';
7+
8+
describe.only('TestAsyncDecryptMultiContracts', function () {
9+
before(async function () {
10+
await initSigners(2);
11+
this.signers = await getSigners();
12+
this.instances = await createInstances(this.signers);
13+
await initDecryptionOracle();
14+
});
15+
16+
beforeEach(async function () {
17+
const contractFactoryA = await ethers.getContractFactory('TestAsyncDecryptA');
18+
this.contractA = await contractFactoryA.connect(this.signers.alice).deploy();
19+
await this.contractA.waitForDeployment();
20+
const contractFactoryB = await ethers.getContractFactory('TestAsyncDecryptB');
21+
this.contractB = await contractFactoryB.connect(this.signers.alice).deploy();
22+
await this.contractB.waitForDeployment();
23+
this.instances = await createInstances(this.signers);
24+
});
25+
26+
it('test async decrypt euint64 via 2 contracts', async function () {
27+
const tx = await this.contractA.connect(this.signers.carol).requestUint64();
28+
await tx.wait();
29+
try {
30+
await awaitAllDecryptionResults();
31+
} catch {
32+
// we expect an error after first decryption, due to the revert in callback, so we silence it
33+
}
34+
const tx2 = await this.contractB.connect(this.signers.carol).requestUint64();
35+
await tx2.wait();
36+
await awaitAllDecryptionResults();
37+
const y = await this.contractA.yUint64();
38+
const y2 = await this.contractB.yUint64();
39+
expect(y).to.equal(0); // because first decryption callback reverted
40+
expect(y2).to.equal(373737); // this second decryption, on the other hand, should succeed, but currently it is not fulfilled by mocked mode due to a logic bug in mocked relayer
41+
});
42+
});

0 commit comments

Comments
 (0)