1

I am new to ink and trying to run a smartcontract that gets built and deployed correctly but on executing the deposit() method from the contract, it terminates with Contract.Out.Of.Gasafter doing some computation in insert() method given below.

In debug logs, I cannot find any reason why the contract limit gets exhausted. I did try to set the gas limit to the max value it can accept but it just did a few more computations and exhausted the gas limit.

I am not sure where should I start to look for the root cause of the problem.

This is Mixer contract which has 2 ContractRef PoseidonRef and MixerVerifierRef, following are the structure details about smartcontract for reference:

#[ink(storage)]
    #[derive(SpreadAllocate)]
    pub struct Mixer {
        deposit_size: Balance,
        merkle_tree: merkle_tree::MerkleTree,
        used_nullifiers: Mapping<[u8; 32], bool>,
        poseidon: PoseidonRef,
        verifier: MixerVerifierRef,
    }

#[ink(message, payable)]
pub fn deposit(&mut self, commitment: [u8; 32]) -> Result<u32> {
    assert!(
        self.env().transferred_value() == self.deposit_size,
        "Deposit size is not correct"
    );

    self.merkle_tree.insert(self.poseidon.clone(), commitment)
}

// merkle_tree.insert
pub fn insert(&mut self, hasher: PoseidonRef, leaf: [u8; 32]) -> Result<u32> {
    ...
    for i in 0..self.levels {
        if current_index % 2 == 0 {
            left = current_level_hash;
            right = zeroes::zeroes(i);
            self.filled_subtrees.insert(i, &current_level_hash);
        } else {
            left = self.filled_subtrees.get(&i).unwrap_or_default();
            right = current_level_hash;
        }

        current_level_hash = self.hash_left_right(hasher.clone(), left, right)?;
        current_index = current_index / 2;
     }
   ....
}

// hash_left_right
fn hash_left_right(
        &self,
        hasher: PoseidonRef,
        left: [u8; 32],
        right: [u8; 32],
    ) -> Result<[u8; 32]> {
        let inputs = vec![left, right];
        hasher.hash(inputs).map_err(|_| mixer::Error::HashError)
}

Any advice or help is much appreciated. Thank you!

I am using ink! v3.0.0-rc9 and redspot for testing

1 Answer 1

2

Did you end up figuring it out?

An approach to debugging this could be with a local instance of the substrate-contracts-node.

This node comes with the typical Alice, Bob, etc. accounts that are endowed with a huge amount of tokens. In the Contracts UI or polkadot-js you can then submit the transaction from e.g. Alice and the UI displays the amount of gas used.

So this should give you an idea if the gas costs are in general in a reasonable domain. If this already fails it's likely that you're logic is unbound in some way.

In order to debug this you could then create a Rust unit test (like here) and see if that finishes.

1
  • yeah we, started using the local instance of the substrate-contract-node.
    – salman01z
    Jul 28, 2022 at 12:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.