Various errors while trying to communicate with smart contract

Hello, I’ve been working on fhevm and have created a few smart contracts that perform homomorphic calculations but I usually run into the following errors while trying to communicate with the smart contracts.

error: { code: -32002, message: ‘request timed out’ },
error: {
code: -32000,
message: ‘invalid nonce; got 725, expected 727: invalid sequence: invalid sequence’
}

error: {
code: -32000,
message: ‘rpc error: code = DeadlineExceeded desc = context deadline exceeded’
}

I haven’t been able to figure out what the problem is. Can anyone help me figure out the cause and how to fix these errors. Are these errors related to specific versions of libraries? I’m sharing one of the scripts that I’m trying to run. this program sorts the elements of an array

// SPDX-License-Identifier: UNLICENSED
pragma solidity >0.7.0 <0.9.0;

import “./TFHE.sol”;

contract Sorting{
address public manager;
euint32 initialSequence;

constructor() {
    manager = msg.sender; //For contract developer specific functionalities.
}

function initializeVariables() public {
    if(initialSequence.length > 0){
        delete initialSequence;
    }
}

function setData(bytes[] calldata encryptedSequence) public {
    for(uint i=0; i<encryptedSequence.length; i++){
        initialSequence.push(TFHE.asEuint32(encryptedSequence[i]));
    }
}

function sortData() public {
    for(uint i=0; i<initialSequence.length -1; i++){
        for (uint j = 0; j < initialSequence.length - i - 1; j++) {
            if (TFHE.decrypt(TFHE.gt(initialSequence[j], initialSequence[j + 1]))) {
                (initialSequence[j], initialSequence[j + 1]) = (initialSequence[j + 1], initialSequence[j]);
            }

        }
    }
}

function returnSortedArray(bytes32 publicKey) public view returns (bytes[] memory) {
    bytes[] memory finalResultArray = new bytes[](initialSequence.length);
    if (initialSequence.length > 0) {
        for (uint32 i = 0; i < initialSequence.length; i++) {
            finalResultArray[i] = TFHE.reencrypt(initialSequence[i], publicKey, 0);
        }
    }
    return finalResultArray;
}

}

const {getInstance} = require(“./instance.js”);
const { Wallet, JsonRpcProvider, Contract } = require(“ethers”);
const ethers = require(“ethers”);
const provider = new JsonRpcProvider(https://devnet.zama.ai/);
const CONTRACT_ADDRESS = “mycontractaddress”;
const signer = new Wallet(“privatekeyofmywallet”, provider);

const abi = ;

const initializeVariables = async (contract) => {
const transactionOne = await contract.initializeVariables();
await transactionOne.wait();
};

const sendData = async (contract, data) => {
console.log(“sending data”);
const transactionTwo = await contract.setData(data);
await transactionTwo.wait();
};

const sortData = async (contract) => {
console.log(“sorting data”);
const transactionTwo = await contract.sortData();
await transactionTwo.wait();
}

const get_sorted_array = async (contract, public_key, instance) => {
console.log(“reencrypting sorted array and getting result”);
const enc_sorted_array = await contract.returnSortedArray(public_key);
console.log(enc_sorted_array);
enc_sorted_array.forEach((element, index) => {
console.log(instance.decrypt(CONTRACT_ADDRESS, element));
});

};

const interact = async () => {
// Initialize contract with ethers
const contract = new Contract(CONTRACT_ADDRESS, abi, signer);

// Get instance to encrypt amount parameter
const instance = await getInstance();
const generatedToken = instance.generatePublicKey({
verifyingContract: CONTRACT_ADDRESS,
});
await instance.setSignature(CONTRACT_ADDRESS, ethers.Signature)

try{
await initializeVariables(contract);
try{
const data_set = [instance.encrypt32(25), instance.encrypt32(22), instance.encrypt32(28), instance.encrypt32(20)];
await sendData(contract, data_set);
try{
await sortData(contract);
try{
await get_sorted_array(contract, generatedToken.publicKey, instance);
} catch (error) {
console.log(“Could not get result”, error);
}
} catch(error) {
console.log(“could not sort data”, error);
}
} catch(error){
console.log(“could not send data”, error);
}
} catch(error) {
console.log("could not initialize ", error);
}
};

interact()
.then(successful => {console.log(“success”); process.exit(0); })
.catch(wrong => {console.log(“something went wrong”, wrong); process.exit(0); });

I’m using 0.8.24 compiler
node js version 18.18.0
ethers@6.10.0
fhevm@0.3.0
fhevmjs@0.3.2

Hello!
The 2 common causes for your problem are:

  • The deadline exceeded occurs when a transaction takes too much time. In your code, you’re doing two loops over initialSequences, and for each loop, you’re doing a decrypt and a gt. If you have 5 items, it means 25 gt and 25 decrypt, so more than 10Millions gas. Even if you are below 10Millions gas, you can exceed the 7sec per block. We tried to put operation gas prices according to real time of operations, but these times are different on a Macbook M1 and AMD Ryzen with 96 cores.
    Two things regarding this: you should avoid decrypt, especially because we plan to deprecate it. Instead, you should use cmux operation. Second, sorting array is a known challenge with no efficient solution at the moment.
  • invalid nonce; got 725, expected 727: invalid sequence: invalid sequence is a known issue when you push a transaction which costs more than 10Millions. You can solve that by forcing the usage of the previous nonce. You can refer to https://docs.zama.ai/fhevm/how-to/gas#gas-limit

Since you import ./TFHE.sol, it seems you cloned the fhevm project. We don’t recommend that. Instead, you should use the template provided with all correct package ready to use GitHub - zama-ai/fhevm-hardhat-template: fhEVM hardhat template

Hope it helps!

1 Like