Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Technical Support Required - FxPortal Implementation Fail with error ‘Leaf index is too big’ (Goerli/Mumbai) #28

Closed
c194 opened this issue Jan 25, 2022 · 7 comments

Comments

@c194
Copy link

c194 commented Jan 25, 2022

Hello! I'm the Lead Developer working on integrating GoldHunt Game (thegame.gold) with the Polygon network. I intend to build a custom implementation of the FxPortal Root & Child Contracts (https://github.com/fx-portal/contracts) to enable our community to move tokens between Ethereum <-> Polygon.

I need technical support on implementing this bridge on the Test networks (Goerli, Mumbai).

The problem: when I call function receiveMessage(bytes memory inputData) public virtual on my implementation of the Root contract, I am getting a Fail with error 'Leaf index is too big' error on the transaction.

Failed Transactions (same error):

I generate the burn proof as such:


const execute = async () => {

  const posClient = await getPOSClient();

  const proof = await posClient.exitUtil.buildPayloadForExit(

    "0x76bd13760e3dbea702450f8741b405bf528be0078570d94c405a9183a8911ef9", // Withdraw transaction hash

    "0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036"  // MESSAGE_SENT_EVENT_SIG: Do not change this

  )

  console.log(" ----- BURN PROOF -----")

  console.log(proof)

}

Where https://mumbai.polygonscan.com/tx/0x76bd13760e3dbea702450f8741b405bf528be0078570d94c405a9183a8911ef9 is the Withdraw transaction I submitted on the Mumbai network.

My implementation of the FxMintableERC20RootTunnel is deployed at https://goerli.etherscan.io/address/0xC0Af0b1a10F2417D62EE044BC99dB1b40b4DC82e - you'll notice a number of failed transactions all throwing the same error.

My implementation of the FxMintableERC20ChildTunnel is deployed at https://mumbai.polygonscan.com/address/0x38530B465C2937b6f3fB7559a796156D2a0A9f02 - I submitted the Withdraw transaction on Mumbai to this contract (see above) over 24 hours ago.

I am attempting to send GGold (ERC20) back and forth across my tunnel, and am unable to resolve the last step to receive the funds back from the Tunnel on Goerli due to the error above.

GGold (Goerli) - https://goerli.etherscan.io/address/0xbdCDF80D26DDA1ae2F9C0003995d160F4893F20A

pGGold (Polygon) - https://mumbai.polygonscan.com/address/0xC440ddBA14e585fdF395bD74B85797e41fd8317c

I can see that the error is ultimately being thrown by the Merkle library defined as such:

pragma solidity ^0.8.0;

library Merkle {
    function checkMembership(
        bytes32 leaf,
        uint256 index,
        bytes32 rootHash,
        bytes memory proof
    ) internal pure returns (bool) {
        require(proof.length % 32 == 0, "Invalid proof length");
        uint256 proofHeight = proof.length / 32;
        // Proof of size n means, height of the tree is n+1.
        // In a tree of height n+1, max #leafs possible is 2 ^ n
        require(index < 2**proofHeight, "Leaf index is too big");

        bytes32 proofElement;
        bytes32 computedHash = leaf;
        for (uint256 i = 32; i <= proof.length; i += 32) {
            assembly {
                proofElement := mload(add(proof, i))
            }

            if (index % 2 == 0) {
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }

            index = index / 2;
        }
        return computedHash == rootHash;
    }
}

but this entire section of code was defined as part of the FxBaseRootTunnel.sol file defined in the fx-portals repo which I am using an exact copy of so I'm not sure how to debug this issue.


Please advise on how to resolve this issue - I've already read through https://docs.polygon.technology/docs/develop/l1-l2-communication/fx-portal/ and this issue is not covered and I am unable to find any other sources online about how to resolve it.

Any help you can provide would be greatly appreciated, as we're excited about being able to onboard thousands of new users to the Polygon network once we're able to build out this infrastructure!

@c194
Copy link
Author

c194 commented Jan 25, 2022

Hi @QEDK is this something that you can assist with? I'm unable to find any information about how to resolve a Fail with error 'Leaf Index is too big' online and I believe I have followed all of the steps for deposits and withdraws correctly, described here: https://docs.polygon.technology/docs/develop/l1-l2-communication/fx-portal/

@c194
Copy link
Author

c194 commented Jan 25, 2022

Hi @jdkanani is this something that you can assist with? I'm unable to find any information about how to resolve a Fail with error 'Leaf Index is too big' online and I believe I have followed all of the steps for deposits and withdraws correctly, described here: https://docs.polygon.technology/docs/develop/l1-l2-communication/fx-portal/

@c194
Copy link
Author

c194 commented Jan 25, 2022

I'm posting here because I've already taken the following actions to get support for this issue and have not received a response:

Multiple tickets submitted to: https://polygon.technology/contact-us/
Forum Post: https://forum.polygon.technology/t/technical-support-required-fxportal-implementation-fail-with-error-leaf-index-is-too-big/1394
This Support Ticket: https://support.polygon.technology/support/tickets/31130
Github Issue on FX-Portals Repo: #28
Multiple Messages in Polygon Discord Support Channel: https://discord.com/channels/635865020172861441/717384861647896616/935176155298930689

@c194
Copy link
Author

c194 commented Jan 25, 2022

Hi @jdkanani - I wanted to provide some more information about this issue. On Mumbai, you can see I submit a withdraw/burn transaction here: https://mumbai.polygonscan.com/tx/0xae1c8793cc900f22676b348802d020790057ce9fb82cd9d7404ebd3c85b5fea0
which resolves successfully. I then move on to the next step, which is generating the burnproof.

I define a utils.js file that looks like such:

const bn = require('bn.js')
const HDWalletProvider = require('@truffle/hdwallet-provider')
const config = require('./config')
const { POSClient, setProofApi, use } = require('@maticnetwork/maticjs')
const SCALING_FACTOR = new bn(10).pow(new bn(18))
const { Web3ClientPlugin } = require("@maticnetwork/maticjs-web3");

use(Web3ClientPlugin);

if (config.proofApi) {
  setProofApi(config.proofApi);
}

const privateKey = config.user1.privateKey
const userAddress = config.user1.address

const getPOSClient = (network = 'testnet', version = 'mumbai') => {
  const posClient = new POSClient()
  return posClient.init({
    log: true,
    network: network,
    version: version,
    child: {
      provider: new HDWalletProvider(privateKey, config.child.rpc),
      defaultConfig: {
        from: userAddress
      }
    },
    parent: {
      provider: new HDWalletProvider(privateKey, config.parent.rpc),
      defaultConfig: {
        from: userAddress
      }
    }
  });
}

module.exports = {
  SCALING_FACTOR,
  getPOSClient: getPOSClient,
  child: config.child,
  plasma: config.plasma,
  pos: config.pos,
  from: config.user1.address,
  privateKey: config.user1.privateKey,
  proofApi: config.proofApi
}

and a generate_burn_proof.js file that looks like such:

const { getPOSClient, from } = require('../../utils');

const execute = async () => {
  const posClient = await getPOSClient();
  const proof = await posClient.exitUtil.buildPayloadForExit(
    "0xae1c8793cc900f22676b348802d020790057ce9fb82cd9d7404ebd3c85b5fea0", // Withdraw transaction hash
    "0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036"  // MESSAGE_SENT_EVENT_SIG: Do not change this
  )
  console.log(" ----- BURN PROOF -----")
  console.log(proof)
}
execute().then(() => {
}).catch(err => {
  console.error("err", err);
}).finally(_ => {
  process.exit(0);
})

You'll note that I am submitting the 0xae1c8793cc900f22676b348802d020790057ce9fb82cd9d7404ebd3c85b5fea0 transaction hash here to generate the proof. By running generate_burn_proof.js, I'm able to successfully generate the burnproof for the transaction.

I submit this burnproof as input to my Root contract's receiveMessage message function but it fails due to Fail with error 'Leaf index is too big' - Failed Transaction: https://goerli.etherscan.io/tx/0xc5724512db14a1de7631441fc2e26e3da2439862515a2e15db6ef32761ab7fe6

@c194
Copy link
Author

c194 commented Jan 27, 2022

Hi @Raneet10 Thanks for the quick response, and that payload did work!

Successful Transaction: https://goerli.etherscan.io/tx/0x628ce213f9523db782d49e6f882cf2bc2a1bd7d5bce2f746edbebe20d94437a8

I am now wondering if the @maticnetwork/maticjs library needs to be updated to include whatever changes that you made.

I define the following configuration for POSClient:

const { POSClient, setProofApi, use } = require('@maticnetwork/maticjs')
// Irrelevant code excluded from this snippet

setProofApi('https://apis.matic.network/api/v1/');

const privateKey = config.user1.privateKey
const userAddress = config.user1.address

const getPOSClient = (network = 'testnet', version = 'mumbai') => {
  const posClient = new POSClient()
  return posClient.init({
    log: true,
    network: network,
    version: version,
    child: {
      provider: new HDWalletProvider(privateKey, config.child.rpc),
      defaultConfig: {
        from: userAddress
      }
    },
    parent: {
      provider: new HDWalletProvider(privateKey, config.parent.rpc),
      defaultConfig: {
        from: userAddress
      }
    }
  });
}

and generate the burnproof as such:

const execute = async () => {
  const posClient = await getPOSClient();
  const proof = await posClient.exitUtil.buildPayloadForExit(
    "0xae1c8793cc900f22676b348802d020790057ce9fb82cd9d7404ebd3c85b5fea0", // Withdraw transaction hash
    "0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036"  // MESSAGE_SENT_EVENT_SIG: Do not change this
  )
  console.log(" ----- BURN PROOF -----")
  console.log(proof)
}

Where I was sure to reference the same API endpoint as you sent over. However, the library produces a slightly different burnproof than the web request you sent over.

Web Request Burnproof: 0xf90b7b8428adf890b90...
@maticnetwork/maticjs Burnproof: 0xf90a798428adf890808...

I can use the GET web requests to continue with my development work but wanted to make sure I brought this discrepancy to your attention while you are working on the issue.

Second Example
Withdraw Transaction - https://mumbai.polygonscan.com/tx/0xba49d07f88c5bbd00a60428333a374f4fcc58dc60e231ab74986f39886914729
Receive Message Failure (using matijs burnproof 0xf909588428d15f10808401...: https://goerli.etherscan.io/tx/0x2746142e2687b840b3ee295814b7ae99a026712e11911013c55093209fea43d1
Receive Message Success (using GET request burnproof 0xf90a5a8428d15f10b...:
https://apis.matic.network/api/v1/mumbai/exit-payload/0xba49d07f88c5bbd00a60428333a374f4fcc58dc60e231ab74986f39886914729?eventSignature=0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036
https://goerli.etherscan.io/tx/0x6e0cde361d4a47d8df3c9c8c5840f1227be44baff7fd9f79c43819971e6df349

Thanks again for your timely response! I really appreciate your support on this issue.

@QEDK
Copy link
Contributor

QEDK commented Jan 27, 2022

Hi @Raneet10 Thanks for the quick response, and that payload did work!

Successful Transaction: https://goerli.etherscan.io/tx/0x628ce213f9523db782d49e6f882cf2bc2a1bd7d5bce2f746edbebe20d94437a8

I am now wondering if the @maticnetwork/maticjs library needs to be updated to include whatever changes that you made.

I define the following configuration for POSClient:

const { POSClient, setProofApi, use } = require('@maticnetwork/maticjs')
// Irrelevant code excluded from this snippet

setProofApi('https://apis.matic.network/api/v1/');

const privateKey = config.user1.privateKey
const userAddress = config.user1.address

const getPOSClient = (network = 'testnet', version = 'mumbai') => {
  const posClient = new POSClient()
  return posClient.init({
    log: true,
    network: network,
    version: version,
    child: {
      provider: new HDWalletProvider(privateKey, config.child.rpc),
      defaultConfig: {
        from: userAddress
      }
    },
    parent: {
      provider: new HDWalletProvider(privateKey, config.parent.rpc),
      defaultConfig: {
        from: userAddress
      }
    }
  });
}

and generate the burnproof as such:

const execute = async () => {
  const posClient = await getPOSClient();
  const proof = await posClient.exitUtil.buildPayloadForExit(
    "0xae1c8793cc900f22676b348802d020790057ce9fb82cd9d7404ebd3c85b5fea0", // Withdraw transaction hash
    "0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036"  // MESSAGE_SENT_EVENT_SIG: Do not change this
  )
  console.log(" ----- BURN PROOF -----")
  console.log(proof)
}

Where I was sure to reference the same API endpoint as you sent over. However, the library produces a slightly different burnproof than the web request you sent over.

Web Request Burnproof: 0xf90b7b8428adf890b90... @maticnetwork/maticjs Burnproof: 0xf90a798428adf890808...

I can use the GET web requests to continue with my development work but wanted to make sure I brought this discrepancy to your attention while you are working on the issue.

Second Example Withdraw Transaction - https://mumbai.polygonscan.com/tx/0xba49d07f88c5bbd00a60428333a374f4fcc58dc60e231ab74986f39886914729 Receive Message Failure (using matijs burnproof 0xf909588428d15f10808401...: https://goerli.etherscan.io/tx/0x2746142e2687b840b3ee295814b7ae99a026712e11911013c55093209fea43d1 Receive Message Success (using GET request burnproof 0xf90a5a8428d15f10b...: https://apis.matic.network/api/v1/mumbai/exit-payload/0xba49d07f88c5bbd00a60428333a374f4fcc58dc60e231ab74986f39886914729?eventSignature=0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036 https://goerli.etherscan.io/tx/0x6e0cde361d4a47d8df3c9c8c5840f1227be44baff7fd9f79c43819971e6df349

Thanks again for your timely response! I really appreciate your support on this issue.

The likely reason is that the matic.js version used to generate the proof is older. If the issue persists on the latest version, please open an issue at https://github.com/maticnetwork/matic.js/issues with the details you provided above.

@QEDK QEDK closed this as completed Jan 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants