ChainSafe / ChainBridge

🌉 Modular Multi-Directional Blockchain Bridge to interact with Multiple Networks; Ethereum, Ethereum Classic, Substrate, based chains. Stay tuned for ChainBridge Hub!
GNU Lesser General Public License v3.0
475 stars 300 forks source link

ERC721 from Substrate to Polygon-Edge, "insufficient funds" and panics #797

Closed peterwht closed 2 years ago

peterwht commented 2 years ago

The goal was to setup a bridge between a local Polygon-Edge node and a Substrate node (chainbridge-substrate-chain). Transferring an ERC721 from the Polygon node to Substrate works as expected; the ERC721 is burned from the Polygon side and minted into the desired account on Substrate. However, transferring an ERC721 from Substrate to Polygon causes an "insufficient funds" error, followed by a ChainBridge panic and shutdown.

The Polygon-Edge node premines a large balance to the admin account, and the relayer account.

The following guides were followed / referenced:

Expected Behavior

Expected behavior is that an ERC721 would be successfully transferred from Substrate to the Polygon-Edge node. Substrate will burn the asset, start cross-chain transfer, bridge handles this transfer and initiates asset minting on the Polygon node.

If the relayer does not have enough funds, it seems that a panic should not happen.

Current Behavior

Transferring ERC721 from Substrate to Polygon causes the following error in the relayer:

WARN[06-22|14:55:37] Voting failed                            chain=polygon-edge source=1 dest=70 depositNonce=8 gasLimit=8000000 gasPrice=2514619659 err="insufficient funds for gas * price + value"
WARN[06-22|14:55:39] Voting failed                            chain=polygon-edge source=1 dest=70 depositNonce=8 gasLimit=8000000 gasPrice=2514619659 err="insufficient funds for gas * price + value"
... 
EROR[06-22|14:55:57] Submission of Vote transaction failed    chain=polygon-edge source=1 dest=70 depositNonce=8
EROR[06-22|14:55:57] FATAL ERROR. Shutting down.              system=core err="submission of transaction failed"

Possible Solution

At first, I believed this was due to my configurations being incorrect. So, I increased the premine amount to the admin and relayer account. I also increased the gasLimit and maxGasPrice in the ChainBridge config.json, as well as the block-gas-limit for the Polygon node.

Steps to Reproduce (for bugs)

  1. Setup local Polygon-Edge node

Prebuilt release v0.4.1 was used for darwin_amd64 architecture.

When generating the genesis config, premine amounts were specified for the admin account and the relayer account, as shown here:

./polygon-edge genesis --consensus ibft --ibft-validators-prefix-path test-chain- \
    --bootnode /ip4/127.0.0.1/tcp/10001/p2p/16Uiu2HAkwwPeUNpN8HowsELJ3eDzkSXLCgjdDakcMLHhv262uyfg \
    --premine 0x0D39a7185771653E1e01d25975551bFa9462a677:1000000000000000000000 \
    --premine 0x1E5CbE897FA43B49bc772125cb1d2EcB2674Da2E:1000000000000000000000 \
    --block-gas-limit 1000000000

where 0x0D39a7185771653E1e01d25975551bFa9462a677 is the admin account (and validator), and 0x1E5CbE897FA43B49bc772125cb1d2EcB2674Da2E is the relayer account. The block-gas-limit was also increased to 1000000000.

After following the guide, and generating the genesis config, the node is started. The genesis config is as follows:

{
    "name": "polygon-edge",
    "genesis": {
        "nonce": "0x0000000000000000",
        "timestamp": "0x0",
        "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000d8d5940d39a7185771653e1e01d25975551bfa9462a67780c0",
        "gasLimit": "0x48c27395000",
        "difficulty": "0x1",
        "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
        "coinbase": "0x0000000000000000000000000000000000000000",
        "alloc": {
            "0x0D39a7185771653E1e01d25975551bFa9462a677": {
                "balance": "0x3635c9adc5dea00000"
            },
            "0x1E5CbE897FA43B49bc772125cb1d2EcB2674Da2E": {
                "balance": "0x3635c9adc5dea00000"
            }
        },
        "number": "0x0",
        "gasUsed": "0x70000",
        "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
    },
    "params": {
        "forks": {
            "homestead": 0,
            "byzantium": 0,
            "constantinople": 0,
            "petersburg": 0,
            "istanbul": 0,
            "EIP150": 0,
            "EIP158": 0,
            "EIP155": 0
        },
        "chainID": 100,
        "engine": {
            "ibft": {
                "epochSize": 100000,
                "type": "PoA"
            }
        },
        "blockGasTarget": 0
    },
    "bootnodes": [
        "/ip4/127.0.0.1/tcp/10001/p2p/16Uiu2HAkwwPeUNpN8HowsELJ3eDzkSXLCgjdDakcMLHhv262uyfg"
    ]
}
  1. Build and Start chainbridge-substrate-chain

build

cargo build --release

run

cargo run --release -- --dev
  1. Deploy contracts on Polygon-Edge node, and specify relayer account

    cb-sol-cli deploy --all --chainId 70 \
    --url http://localhost:10002 \
    --privateKey 0x2a264f9056ed138affcee2b0e6c50dab906c1eeb22bff7975bfdd1719c648823 \
    --relayers 0x1E5CbE897FA43B49bc772125cb1d2EcB2674Da2E \
    --relayerThreshold 1 \
    --gasPrice 5000000000

    The privateKey is of the admin account: 0x0D39a7185771653E1e01d25975551bFa9462a677 (just a local test account, so it does not matter if privateKey is public). The url is of the polygon-edge node. And the chainId is (arbitrarily) set to 70.

  2. Register resource for ERC721 (using deployed contract addresses)

Polygon

cb-sol-cli bridge register-resource \
  --url http://localhost:10002 \
  --privateKey 0x2a264f9056ed138affcee2b0e6c50dab906c1eeb22bff7975bfdd1719c648823 \
  --resourceId "0x000000000000000000000000000000e389d61c11e5fe32ec1735b3cd38c69501" \
  --bridge "0x3a9e78f5cC876345F2824D15f8e8F6b75cBa1658" \
  --handler "0x6D0e1d3238c831A2dc815fB01869EC7e21379DCc" \
  --targetContract "0xD4Fe45ff74fb4C03E4232791e9e62Be640DB8B8E"

Substrate On https://polkadot.js.org/apps, on the sudo page, Alice was added a relayer account. The resource was registered using the following parameters:

Id: 0x000000000000000000000000000000e389d61c11e5fe32ec1735b3cd38c69501
Method: 0x4578616d706c652e6d696e745f657263373231

And lastly, the polygon chain was whitelisted using the chainId of 70.

  1. Configure ERC721 handler contract to mint / burn
    
    cb-sol-cli bridge set-burn \
    --url http://localhost:10002 \
    --privateKey 0x2a264f9056ed138affcee2b0e6c50dab906c1eeb22bff7975bfdd1719c648823 \
    --bridge "0x3a9e78f5cC876345F2824D15f8e8F6b75cBa1658" \
    --handler "0x6D0e1d3238c831A2dc815fB01869EC7e21379DCc" \
    --tokenContract "0xD4Fe45ff74fb4C03E4232791e9e62Be640DB8B8E"

cb-sol-cli erc721 add-minter \ --url http://localhost:10002 \ --privateKey 0x2a264f9056ed138affcee2b0e6c50dab906c1eeb22bff7975bfdd1719c648823 \ --erc721Address "0xD4Fe45ff74fb4C03E4232791e9e62Be640DB8B8E" \ --minter "0x6D0e1d3238c831A2dc815fB01869EC7e21379DCc"


7. Setup ChainBridge relayer
The relay account's (`0x1E5CbE897FA43B49bc772125cb1d2EcB2674Da2E`) private key is added to the ChainBridge keystore

chainbridge accounts import --privateKey 0x6b5df9abc6a93671769dc45490ed430b70423cfa5e414b452dd278f4959eaae7


The config file is setup as shown:
```json
{
  "chains": [
    {
      "name": "polygon-edge",
      "type": "ethereum",
      "id": "70",
      "endpoint": "http://localhost:10002",
      "from": "0x1E5CbE897FA43B49bc772125cb1d2EcB2674Da2E",
      "opts": {
        "bridge": "0xA903129F5a3554BB3B7CDcCD07b813A74429459f",
        "erc20Handler": "0xCfFBd3f4b4bC3f6640E0BbC5BD81d697769E1202",
        "erc721Handler": "0xC692023573bb7d4c2cff1Ac2C2f5bF303df2953D",
        "genericHandler": "0x717a0Ba02f3b6582C2034790852BCE15DE3fC66C",
        "gasLimit": "8000000",
        "maxGasPrice": "20000000000"
      }
    },
    {
      "name": "sub",
      "type": "substrate",
      "id": "1",
      "endpoint": "ws://localhost:9944",
      "from": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
      "opts": {
        "useExtendedCall": "true"
      }
    }
  ]
}

The bridge is then started with the following command:

./chainbridge --config config.json --testkey alice --latest
  1. Minting and transferring from Substrate to Polygon On the Polkadot UI, in the sudo page, using the erc721.mint extrinsic, an ERC721 is minted into Alice's account with the id of 1 (as an example), and metadata of "".

On the Extrinisics page, with Alice as the caller, using example.transferErc721 specified with the following parameters:

recipient: 0x0D39a7185771653E1e01d25975551bFa9462a677 // polygon-validator & admin account tokenId: 1 destId: 70

The asset is burned from Substrate, and a chainBridge.NonFungibleTransfer event is emitted.

The bridge terminal output then shows:

INFO[06-22|14:55:37] Got non-fungible transfer event!         chain=sub destination=70 resourceId="[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 227 137 214 28 17 229 254 50 236 23 53 179 205 56 198 149 1]"
INFO[06-22|14:55:37] Attempting to resolve message            chain=polygon-edge type=NonFungibleTransfer src=1 dst=70 nonce=8 rId=000000000000000000000000000000e389d61c11e5fe32ec1735b3cd38c69501
INFO[06-22|14:55:37] Creating erc721 proposal                 chain=polygon-edge src=1 nonce=8
INFO[06-22|14:55:37] Watching for finalization event          chain=polygon-edge src=1 nonce=8
WARN[06-22|14:55:37] Voting failed                            chain=polygon-edge source=1 dest=70 depositNonce=8 gasLimit=8000000 gasPrice=2514619659 err="insufficient funds for gas * price + value"
WARN[06-22|14:55:39] Voting failed                            chain=polygon-edge source=1 dest=70 depositNonce=8 gasLimit=8000000 gasPrice=2514619659 err="insufficient funds for gas * price + value"
WARN[06-22|14:55:41] Voting failed                            chain=polygon-edge source=1 dest=70 depositNonce=8 gasLimit=8000000 gasPrice=2514619659 err="insufficient funds for gas * price + value"
WARN[06-22|14:55:43] Voting failed                            chain=polygon-edge source=1 dest=70 depositNonce=8 gasLimit=8000000 gasPrice=2514619659 err="insufficient funds for gas * price + value"
WARN[06-22|14:55:45] Voting failed                            chain=polygon-edge source=1 dest=70 depositNonce=8 gasLimit=8000000 gasPrice=2514619659 err="insufficient funds for gas * price + value"
WARN[06-22|14:55:47] Voting failed                            chain=polygon-edge source=1 dest=70 depositNonce=8 gasLimit=8000000 gasPrice=2514619659 err="insufficient funds for gas * price + value"
WARN[06-22|14:55:49] Voting failed                            chain=polygon-edge source=1 dest=70 depositNonce=8 gasLimit=8000000 gasPrice=2514619659 err="insufficient funds for gas * price + value"
WARN[06-22|14:55:51] Voting failed                            chain=polygon-edge source=1 dest=70 depositNonce=8 gasLimit=8000000 gasPrice=2514619659 err="insufficient funds for gas * price + value"
WARN[06-22|14:55:53] Voting failed                            chain=polygon-edge source=1 dest=70 depositNonce=8 gasLimit=8000000 gasPrice=2514619659 err="insufficient funds for gas * price + value"
WARN[06-22|14:55:55] Voting failed                            chain=polygon-edge source=1 dest=70 depositNonce=8 gasLimit=8000000 gasPrice=2514619659 err="insufficient funds for gas * price + value"
EROR[06-22|14:55:57] Submission of Vote transaction failed    chain=polygon-edge source=1 dest=70 depositNonce=8
EROR[06-22|14:55:57] FATAL ERROR. Shutting down.              system=core err="submission of transaction failed"

Versions

ChainBridge commit (or docker tag): built from source: 8cee3ff157224d18ccc214002548aa5bd75f52ef chainbridge-solidity version: included with chainbridge-deploy chainbridge-substrate version: built from source, sha: c89d5afea87f502e349aafad4e404f1e4a03b9bb Go version: go1.17.6 darwin/amd64