From aa29609882ccf3c8574c2ba3e0ad57c019a510ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joseph-Andr=C3=A9=20Turk?= Date: Mon, 15 Apr 2024 19:41:32 +0200 Subject: [PATCH] fix: tests with fake handles --- examples/TestAsyncDecrypt.sol | 81 ++++++++++++++------------ oracle/OraclePredeploy.sol | 5 +- test/oracleDecrypt/testAsyncDecrypt.ts | 45 +++++++------- 3 files changed, 67 insertions(+), 64 deletions(-) diff --git a/examples/TestAsyncDecrypt.sol b/examples/TestAsyncDecrypt.sol index 5bec2633..b55cafcf 100644 --- a/examples/TestAsyncDecrypt.sol +++ b/examples/TestAsyncDecrypt.sol @@ -70,73 +70,79 @@ contract TestAsyncDecrypt is OracleCaller { } function requestFakeBool() public { - ebool[] memory cts = new ebool[](1); - cts[0] = ebool.wrap(42); + Ciphertext[] memory cts = new Ciphertext[](1); + cts[0] = Ciphertext(42, CiphertextType.EBOOL); Oracle.requestDecryption(cts, this.callbackBool.selector, 0, block.timestamp + 100); // this should revert because previous ebool is not honestly obtained } - function callbackBool(uint256 /*requestID*/, bool decryptedInput) public onlyOracle returns (bool) { + function callbackBool(uint256, bool decryptedInput) public onlyOracle returns (bool) { yBool = decryptedInput; return yBool; } + function requestUint4() public { + Ciphertext[] memory cts = new Ciphertext[](1); + cts[0] = Oracle.toCiphertext(xUint4); + Oracle.requestDecryption(cts, this.callbackUint4.selector, 0, block.timestamp + 100); + } + function requestFakeUint4() public { - euint4[] memory cts = new euint4[](1); - cts[0] = euint4.wrap(42); - Oracle.requestDecryption(cts, this.callbackUint4.selector, 0, block.timestamp + 100); // this should revert because previous ebool is not honestly obtained + Ciphertext[] memory cts = new Ciphertext[](1); + cts[0] = Ciphertext(42, CiphertextType.EUINT4); + Oracle.requestDecryption(cts, this.callbackUint4.selector, 0, block.timestamp + 100); // this should revert because previous handle is not honestly obtained } - function callbackUint4(uint256 /*requestID*/, uint8 decryptedInput) public onlyOracle returns (uint8) { + function callbackUint4(uint256, uint8 decryptedInput) public onlyOracle returns (uint8) { yUint4 = decryptedInput; return decryptedInput; } function requestUint8() public { - euint8[] memory cts = new euint8[](1); - cts[0] = xUint8; + Ciphertext[] memory cts = new Ciphertext[](1); + cts[0] = Oracle.toCiphertext(xUint8); Oracle.requestDecryption(cts, this.callbackUint8.selector, 0, block.timestamp + 100); } function requestFakeUint8() public { - euint8[] memory cts = new euint8[](1); - cts[0] = euint8.wrap(42); - Oracle.requestDecryption(cts, this.callbackUint8.selector, 0, block.timestamp + 100); // this should revert because previous ebool is not honestly obtained + Ciphertext[] memory cts = new Ciphertext[](1); + cts[0] = Ciphertext(42, CiphertextType.EUINT8); + Oracle.requestDecryption(cts, this.callbackUint8.selector, 0, block.timestamp + 100); // this should revert because previous handle is not honestly obtained } - function callbackUint8(uint256 /*requestID*/, uint8 decryptedInput) public onlyOracle returns (uint8) { + function callbackUint8(uint256, uint8 decryptedInput) public onlyOracle returns (uint8) { yUint8 = decryptedInput; return decryptedInput; } function requestUint16() public { - euint16[] memory cts = new euint16[](1); - cts[0] = xUint16; + Ciphertext[] memory cts = new Ciphertext[](1); + cts[0] = Oracle.toCiphertext(xUint16); Oracle.requestDecryption(cts, this.callbackUint16.selector, 0, block.timestamp + 100); } function requestFakeUint16() public { - euint16[] memory cts = new euint16[](1); - cts[0] = euint16.wrap(42); - Oracle.requestDecryption(cts, this.callbackUint16.selector, 0, block.timestamp + 100); // this should revert because previous ebool is not honestly obtained + Ciphertext[] memory cts = new Ciphertext[](1); + cts[0] = Ciphertext(42, CiphertextType.EUINT16); + Oracle.requestDecryption(cts, this.callbackUint16.selector, 0, block.timestamp + 100); // this should revert because previous handle is not honestly obtained } - function callbackUint16(uint256 /*requestID*/, uint16 decryptedInput) public onlyOracle returns (uint16) { + function callbackUint16(uint256, uint16 decryptedInput) public onlyOracle returns (uint16) { yUint16 = decryptedInput; return decryptedInput; } function requestUint32(uint32 input1, uint32 input2) public { - euint32[] memory cts = new euint32[](1); - cts[0] = xUint32; + Ciphertext[] memory cts = new Ciphertext[](1); + cts[0] = Oracle.toCiphertext(xUint32); uint256 requestID = Oracle.requestDecryption(cts, this.callbackUint32.selector, 0, block.timestamp + 100); addParamsUint(requestID, input1); addParamsUint(requestID, input2); } function requestFakeUint32() public { - euint32[] memory cts = new euint32[](1); - cts[0] = euint32.wrap(42); - Oracle.requestDecryption(cts, this.callbackUint32.selector, 0, block.timestamp + 100); // this should revert because previous ebool is not honestly obtained + Ciphertext[] memory cts = new Ciphertext[](1); + cts[0] = Ciphertext(42, CiphertextType.EUINT32); + Oracle.requestDecryption(cts, this.callbackUint32.selector, 0, block.timestamp + 100); // this should revert because previous handle is not honestly obtained } function callbackUint32(uint256 requestID, uint32 decryptedInput) public onlyOracle returns (uint32) { @@ -149,25 +155,25 @@ contract TestAsyncDecrypt is OracleCaller { } function requestUint64() public { - euint64[] memory cts = new euint64[](1); - cts[0] = xUint64; + Ciphertext[] memory cts = new Ciphertext[](1); + cts[0] = Oracle.toCiphertext(xUint64); Oracle.requestDecryption(cts, this.callbackUint64.selector, 0, block.timestamp + 100); } function requestFakeUint64() public { - euint64[] memory cts = new euint64[](1); - cts[0] = euint64.wrap(42); - Oracle.requestDecryption(cts, this.callbackUint64.selector, 0, block.timestamp + 100); // this should revert because previous ebool is not honestly obtained + Ciphertext[] memory cts = new Ciphertext[](1); + cts[0] = Ciphertext(42, CiphertextType.EUINT64); + Oracle.requestDecryption(cts, this.callbackUint64.selector, 0, block.timestamp + 100); // this should revert because previous handle is not honestly obtained } - function callbackUint64(uint256 /*requestID*/, uint64 decryptedInput) public onlyOracle returns (uint64) { + function callbackUint64(uint256, uint64 decryptedInput) public onlyOracle returns (uint64) { yUint64 = decryptedInput; return decryptedInput; } function requestAddress() public { - eaddress[] memory cts = new eaddress[](1); - cts[0] = xAddress; + Ciphertext[] memory cts = new Ciphertext[](1); + cts[0] = Oracle.toCiphertext(xAddress); Oracle.requestDecryption(cts, this.callbackAddress.selector, 0, block.timestamp + 100); } @@ -179,14 +185,15 @@ contract TestAsyncDecrypt is OracleCaller { } function requestFakeAddress() public { - eaddress[] memory cts = new eaddress[](1); - cts[0] = eaddress.wrap(42); - Oracle.requestDecryption(cts, this.callbackAddress.selector, 0, block.timestamp + 100); // this should revert because previous ebool is not honestly obtained + Ciphertext[] memory cts = new Ciphertext[](1); + cts[0] = Ciphertext(42, CiphertextType.EADDRESS); + Oracle.requestDecryption(cts, this.callbackAddress.selector, 0, block.timestamp + 100); // this should revert because previous handle is not honestly obtained } - function callbackAddress(uint256 /*requestID*/, address decryptedInput) public onlyOracle returns (address) { + function callbackAddress(uint256, address decryptedInput) public onlyOracle returns (address) { yAddress = decryptedInput; return decryptedInput; + } function requestMixed() public { Ciphertext[] memory cts = new Ciphertext[](10); @@ -204,7 +211,7 @@ contract TestAsyncDecrypt is OracleCaller { } function callbackMixed( - uint256 /*requestID*/, + uint256, bool decBool_1, bool decBool_2, uint8 decUint4, diff --git a/oracle/OraclePredeploy.sol b/oracle/OraclePredeploy.sol index 952315f0..079fc406 100644 --- a/oracle/OraclePredeploy.sol +++ b/oracle/OraclePredeploy.sol @@ -97,11 +97,10 @@ contract OraclePredeploy is Ownable2Step { if (ctType <= 5) { Impl.and(handle, handle); // this is similar to no-op, except it would fail if `handle` is a "fake" handle, needed to check that ciphertext is honestly obtained } else if (ctType == 7) { - Impl.eq(handle, handle, 0x00); // similar to previous no-op, used here because `` not supported by eaddress type - } + Impl.eq(handle, handle, false); // similar to previous no-op, used here because `Impl.and` not supported by eaddress type } else { revert NotImplementedError(); - } + } decryptionReq.cts.push(cts[i]); } decryptionReq.contractCaller = msg.sender; diff --git a/test/oracleDecrypt/testAsyncDecrypt.ts b/test/oracleDecrypt/testAsyncDecrypt.ts index 2d1befbc..cd67afaa 100644 --- a/test/oracleDecrypt/testAsyncDecrypt.ts +++ b/test/oracleDecrypt/testAsyncDecrypt.ts @@ -36,8 +36,19 @@ describe('TestAsyncDecrypt', function () { ); } else { // fhevm-mode - const tx = await this.contract.connect(this.signers.carol).requestBoolAboveDelay({ gasLimit: 1_000_000 }); - await expect(tx.wait()).to.throw; + const txObject = await this.contract.requestBoolAboveDelay.populateTransaction({ gasLimit: 1_000_000 }); + const tx = await this.signers.carol.sendTransaction(txObject); + let receipt = null; + let waitTime = 0; + while (receipt === null && waitTime < 15000) { + receipt = await ethers.provider.getTransactionReceipt(tx.hash); + if (receipt === null) { + console.log('Trying again to fetch txn receipt....'); + await new Promise((resolve) => setTimeout(resolve, 5000)); // Wait for 5 seconds + waitTime += 5000; + } + } + receipt === null ? expect(waitTime >= 15000).to.be.true : expect(receipt!.status).to.equal(0); } }); @@ -55,9 +66,7 @@ describe('TestAsyncDecrypt', function () { it('test async decrypt FAKE bool', async function () { if (network.name !== 'hardhat') { // only in fhevm mode - const txObject = await this.contract - .connect(this.signers.carol) - .requestFakeBool.populateTransaction({ gasLimit: 5_000_000 }); + const txObject = await this.contract.requestFakeBool.populateTransaction({ gasLimit: 5_000_000 }); const tx = await this.signers.carol.sendTransaction(txObject); let receipt = null; let waitTime = 0; @@ -69,7 +78,7 @@ describe('TestAsyncDecrypt', function () { waitTime += 5000; } } - expect(waitTime >= 15000).to.be.true; + receipt === null ? expect(waitTime >= 15000).to.be.true : expect(receipt!.status).to.equal(0); } }); @@ -87,9 +96,7 @@ describe('TestAsyncDecrypt', function () { it('test async decrypt FAKE uint4', async function () { if (network.name !== 'hardhat') { // only in fhevm mode - const txObject = await this.contract - .connect(this.signers.carol) - .requestFakeUint4.populateTransaction({ gasLimit: 5_000_000 }); + const txObject = await this.contract.requestFakeUint4.populateTransaction({ gasLimit: 5_000_000 }); const tx = await this.signers.carol.sendTransaction(txObject); let receipt = null; let waitTime = 0; @@ -116,9 +123,7 @@ describe('TestAsyncDecrypt', function () { it('test async decrypt FAKE uint8', async function () { if (network.name !== 'hardhat') { // only in fhevm mode - const txObject = await this.contract - .connect(this.signers.carol) - .requestFakeUint8.populateTransaction({ gasLimit: 5_000_000 }); + const txObject = await this.contract.requestFakeUint8.populateTransaction({ gasLimit: 5_000_000 }); const tx = await this.signers.carol.sendTransaction(txObject); let receipt = null; let waitTime = 0; @@ -145,9 +150,7 @@ describe('TestAsyncDecrypt', function () { it('test async decrypt FAKE uint16', async function () { if (network.name !== 'hardhat') { // only in fhevm mode - const txObject = await this.contract - .connect(this.signers.carol) - .requestFakeUint16.populateTransaction({ gasLimit: 5_000_000 }); + const txObject = await this.contract.requestFakeUint16.populateTransaction({ gasLimit: 5_000_000 }); const tx = await this.signers.carol.sendTransaction(txObject); let receipt = null; let waitTime = 0; @@ -174,9 +177,7 @@ describe('TestAsyncDecrypt', function () { it('test async decrypt FAKE uint32', async function () { if (network.name !== 'hardhat') { // only in fhevm mode - const txObject = await this.contract - .connect(this.signers.carol) - .requestFakeUint32.populateTransaction({ gasLimit: 5_000_000 }); + const txObject = await this.contract.requestFakeUint32.populateTransaction({ gasLimit: 5_000_000 }); const tx = await this.signers.carol.sendTransaction(txObject); let receipt = null; let waitTime = 0; @@ -203,9 +204,7 @@ describe('TestAsyncDecrypt', function () { it('test async decrypt FAKE uint64', async function () { if (network.name !== 'hardhat') { // only in fhevm mode - const txObject = await this.contract - .connect(this.signers.carol) - .requestFakeUint64.populateTransaction({ gasLimit: 5_000_000 }); + const txObject = await this.contract.requestFakeUint64.populateTransaction({ gasLimit: 5_000_000 }); const tx = await this.signers.carol.sendTransaction(txObject); let receipt = null; let waitTime = 0; @@ -256,9 +255,7 @@ describe('TestAsyncDecrypt', function () { it('test async decrypt FAKE address', async function () { if (network.name !== 'hardhat') { // only in fhevm mode - const txObject = await this.contract - .connect(this.signers.carol) - .requestFakeAddress.populateTransaction({ gasLimit: 5_000_000 }); + const txObject = await this.contract.requestFakeAddress.populateTransaction({ gasLimit: 5_000_000 }); const tx = await this.signers.carol.sendTransaction(txObject); let receipt = null; let waitTime = 0;