0xPolygon / polygon-edge

A Framework for Building Ethereum-compatible Blockchain Networks
https://polygon.technology/solutions/polygon-edge/
Apache License 2.0
1.02k stars 534 forks source link

Cannot initialize rootchain contract "CustomSupernetManager" on Mumbai #1881

Closed deepalt92 closed 1 year ago

deepalt92 commented 1 year ago

Description

Hi, When setting up a Supernet and Rootchain (Mumbai), I tried to deploy the Rootchain contracts on Mumbai using my MetaMask wallet address that has Mumbai MATIC tokens (I got some from a faucet). The Rootchain contracts seemed to be deployed fine but the "CustomSupernetManager" rootchain contract failed to initialize.

Please find the screenshot below: image

Your environment

Steps to reproduce

I used all the commands from the bash script: polygon-edge/scripts/cluster. Simply replaced the --private-key value with my MetaMask private key and the --json-rpc value with: https://polygon-mumbai.infura.io/v3/4458cf4d1689497b9a38b1d6bbf05e78. Please find attached the script that I executed to setup the Rootchain as Mumbai. cluster-test.docx

Expected behavior

The Rootchain contracts should initialized successfully

Observed behaviour

The Rootchain contracts fail initializing

Help?

Could you please provide a step-by-step guide to solve this issue and get a Supernet and a Rootchain (Mumbai) working so that I can deposit custom ERC20 tokens from the Rootchain (Mumbai) to my Supernet and vice versa?

begmaroman commented 1 year ago
require(
            newStakeManager != address(0) &&
                newBls != address(0) &&
                newStateSender != address(0) &&
                newMatic != address(0) &&
                newChildValidatorSet != address(0) &&
                newExitHelper != address(0) &&
                bytes(newDomain).length != 0,
            "INVALID_INPUT"
        );

Seems like one (or more) of those addresses is zero. Could you @deepalt92 please share your genesis.json?

deepalt92 commented 1 year ago

Hi @begmaroman These were the root contract addresses on the genesis:

 "bridge": {
                    "stateSenderAddress": "0x1BfAdFDc7554f618665e3EAE7C22DE2B5ab54786",
                    "checkpointManagerAddress": "0x22C246401ed6e52C525644659C5304aed63516C7",
                    "exitHelperAddress": "0xaCB3Eb2f3c167B56410F0351B6C6EBac9256f553",
                    "erc20PredicateAddress": "0xA1DFe8536732EB98BBCA36A7f97C72e3395EaB8E",
                    "erc20ChildMintablePredicateAddress": "0x947a581B2713F58A8145201DA41BCb6aAE90196B",
                    "nativeERC20Address": "0x0000000000000000000000000000000000000000",
                    "erc721PredicateAddress": "0x7e5BB8F3721C594Af6aB04D5bDf5C52742F37403",
                    "erc721ChildMintablePredicateAddress": "0x811068e4106f7A70D443684FF4927eC3940439Ec",
                    "erc1155PredicateAddress": "0x3a050ae9f452d4d0EF0029dEdf790985D133A8bf",
                    "erc1155ChildMintablePredicateAddress": "0x75aA024A2292A3FD3C17d67b54B3d00435437246",
                    "childERC20Address": "0x0e3C79887960455083c5F063035C723c61906811",
                    "childERC721Address": "0x8d83F76FB303d30d35E1A8FAafB69294C8bD4069",
                    "childERC1155Address": "0x0eEBae803F685565492DF1a77793354038D02A3e",
                    "customSupernetManagerAddr": "0x436604426F31A05f905C64edc973E575BdB46471",
                    "stakeManagerAddr": "0x6FE03c2768C9d800AF3Dedf1878b5687FE120a27",
                    "stakeTokenAddr": "0x3d46A809D5767B81a8836f0E79145ba615A2Dd61",
                    "blsAddr": "0x88d3678C1e99Fc0b699fCA4cf2BC1c2C75C7f272",
                    "bn256G2Addr": "0xB3A64e1ffB0867E93665Da1052b3dbAb427A538C",
                    "jsonRPCEndpoint": "http://127.0.0.1:8545",
                    "eventTrackerStartBlocks": {
                        "0x1BfAdFDc7554f618665e3EAE7C22DE2B5ab54786": 7
                    }
                }

The nativeERC20Address was 0x000..... Perhaps I should use a custom erc20 token as the native erc20 token to have a non-zero address? I've seen some people do it that way.

The reason for trying all these versions is to get the bridge to work. I would want to deposit some tokens from the Rootchain (Mumbai) to my Supernet and see those tokens on my MetaMask when I connect my wallet to the Supernet with the receiver address specified in the "./polygon-edge bridge deposit-erc20" commad.

I tried with Polygon-edge v0.8.1 and was able to deploy the Rootchain contracts on Mumbai:


 "bridge": {
                    "stateSenderAddress": "0x1BfAdFDc7554f618665e3EAE7C22DE2B5ab54786",
                    "checkpointManagerAddress": "0x22C246401ed6e52C525644659C5304aed63516C7",
                    "exitHelperAddress": "0xaCB3Eb2f3c167B56410F0351B6C6EBac9256f553",
                    "erc20PredicateAddress": "0xA1DFe8536732EB98BBCA36A7f97C72e3395EaB8E",
                    "erc20ChildMintablePredicateAddress": "0x947a581B2713F58A8145201DA41BCb6aAE90196B",
                    "nativeERC20Address": "0x0000000000000000000000000000000000000000",
                    "erc721PredicateAddress": "0x7e5BB8F3721C594Af6aB04D5bDf5C52742F37403",
                    "erc721ChildMintablePredicateAddress": "0x811068e4106f7A70D443684FF4927eC3940439Ec",
                    "erc1155PredicateAddress": "0x3a050ae9f452d4d0EF0029dEdf790985D133A8bf",
                    "erc1155ChildMintablePredicateAddress": "0x75aA024A2292A3FD3C17d67b54B3d00435437246",
                    "childERC20Address": "0x0e3C79887960455083c5F063035C723c61906811",
                    "childERC721Address": "0x8d83F76FB303d30d35E1A8FAafB69294C8bD4069",
                    "childERC1155Address": "0x0eEBae803F685565492DF1a77793354038D02A3e",
                    "customSupernetManagerAddr": "0x436604426F31A05f905C64edc973E575BdB46471",
                    "stakeManagerAddr": "0x6FE03c2768C9d800AF3Dedf1878b5687FE120a27",
                    "stakeTokenAddr": "0x3d46A809D5767B81a8836f0E79145ba615A2Dd61",
                    "blsAddr": "0x88d3678C1e99Fc0b699fCA4cf2BC1c2C75C7f272",
                    "bn256G2Addr": "0xB3A64e1ffB0867E93665Da1052b3dbAb427A538C",
                    "jsonRPCEndpoint": "http://127.0.0.1:8545",
                    "eventTrackerStartBlocks": {
                        "0x1BfAdFDc7554f618665e3EAE7C22DE2B5ab54786": 7
                    }
                },

However, the problem I have with Polygon-edge v0.81 is that I cannot mint native root tokens to my MetaMask wallet. How would I go about doing that? In other words, how could I perform step: 7 (mint some token to deployer wallet on matic-mumbai, under "rootNativeERC20Address") mentioned in the following issue : https://github.com/0xPolygon/polygon-edge/issues/1367.

The author of issue: https://github.com/0xPolygon/polygon-edge/issues/1367 seem to have been able to observe the tokens reflected on the Supernet once deposited from the Rootchain so I was following his steps after getting the bridge to work in numerous ways.

Stefan-Ethernal commented 1 year ago

Hey @deepalt92, sorry for waiting a bit longer for our response.

As you have already witnessed, the cluster script was not meant to be run against Mumbai acting as a rootchain, although it is doable, but some further accommodations are needed. I have managed to run it on my end after these adaptations and let me explain it one by one:

  1. v1.1.0, contains some issues that were fixed in the meantime (when dealing with setting a gas limit and gas price properly for rootchain transactions), so I suggest performing testing using this branch. It is not yet released, but we are expecting it to happen in the near future.
  2. regarding accommodations necessary in the cluster script, there are a couple of them:
    • the rootchain fund command was missing --json-rpc URL and was trying to get executed against locally running rootchain server (which was not there). Also --amounts flag was too big, as those values are expressed in WEIs, we were trying to distribute 1M tokens to each validator, but the private key you were using had ~97 Mumbai MATICs on its balance. So I have lowered that amount to 0.1 tokens (10^17 WEIs).
    • the stake-manager-deploy command was missing --stake-token value, which represents an address of the stake token on the rootchain.
    • the stake command amount value was too big (again it was trying to stake more than each validator has on the rootchain (tried to stake 1M tokens against 0.1 tokens that belonged to each of them), so I have lowered that also to 10^17 WEIs, namely 0.1 tokens.
    • I've returned back the --relayer flag to the 1st validator node because without that, bridge events originating from Mumbai would not be settled automatically on the Supernets.

P.s. I've spent a bit of Mumbai MATIC tokens from the account you have provided, sorry for that. :slightly_smiling_face:

An altered script is provided in the following snippet:

#!/usr/bin/env bash

dp_error_flag=0

# Check if jq is installed
if [[ "$1" == "polybft" ]] && ! command -v jq >/dev/null 2>&1; then
  echo "jq is not installed."
  echo "Manual installation instructions: Visit https://jqlang.github.io/jq/ for more information."
  dp_error_flag=1
fi

# Check if curl is installed
if [[ "$1" == "polybft" ]] && ! command -v curl >/dev/null 2>&1; then
  echo "curl is not installed."
  echo "Manual installation instructions: Visit https://everything.curl.dev/get/ for more information."
  dp_error_flag=1
fi

# Stop script if any of the dependencies have failed
#if [[ "$dp_error_flag" -eq 1]] then
#  echo "Missing dependencies. Please install them and run the script again."
#  exit 1
#fi 

function initIbftConsensus() {
  echo "Running with ibft consensus"
  ./polygon-edge secrets init --insecure --data-dir test-chain- --num 4

  node1_id=$(./polygon-edge secrets output --data-dir test-chain-1 | grep Node | head -n 1 | awk -F ' ' '{print $4}')
  node2_id=$(./polygon-edge secrets output --data-dir test-chain-2 | grep Node | head -n 1 | awk -F ' ' '{print $4}')

  genesis_params="--consensus ibft --ibft-validators-prefix-path test-chain- \
    --bootnode /ip4/127.0.0.1/tcp/30301/p2p/$node1_id \
    --bootnode /ip4/127.0.0.1/tcp/30302/p2p/$node2_id"
}

function initPolybftConsensus() {
  echo "Running with polybft consensus"
  genesis_params="--consensus polybft"

  address1=$(./polygon-edge polybft-secrets --insecure --data-dir test-chain-1 | grep Public | head -n 1 | awk -F ' ' '{print $5}')
  address2=$(./polygon-edge polybft-secrets --insecure --data-dir test-chain-2 | grep Public | head -n 1 | awk -F ' ' '{print $5}')
  address3=$(./polygon-edge polybft-secrets --insecure --data-dir test-chain-3 | grep Public | head -n 1 | awk -F ' ' '{print $5}')
  address4=$(./polygon-edge polybft-secrets --insecure --data-dir test-chain-4 | grep Public | head -n 1 | awk -F ' ' '{print $5}')
}

function createGenesis() {
  ./polygon-edge genesis $genesis_params \
    --block-gas-limit 10000000 \
    --premine 0x741B72AeB64e0B4d5483dFe2793DbC26e7a1b793:1000000000000000000000 \
    --premine 0x0000000000000000000000000000000000000000 \
    --epoch-size 10 \
    --reward-wallet 0xDEADBEEF:1000000 \
    --native-token-config "Polygon:MATIC:18:true:$address1" \
    --burn-contract 0:0x0000000000000000000000000000000000000000
}

function initRootchain() {
  echo "Initializing rootchain"

  #if [ "$1" == "write-logs" ]; then
  #  echo "Writing rootchain server logs to the file..."
  #  ./polygon-edge rootchain server 2>&1 | tee ./rootchain-server.log &
  #else
  #  ./polygon-edge rootchain server >/dev/null &
  #fi

  #set +e
  #t=1
  #while [ $t -gt 0 ]; do
  #  nc -z 127.0.0.1 8545 </dev/null
  #  t=$?
  #  sleep 1
  #done
  #set -e

  ./polygon-edge polybft stake-manager-deploy \
    --jsonrpc https://polygon-mumbai.infura.io/v3/4458cf4d1689497b9a38b1d6bbf05e78 \
    --private-key bb6bd15999db0b658beeefbe176080e9a6f8f34de9e87e5ad2e2d6ff029b027e \
    --stake-token 0x987ddbb5c565f0d2034c01c520e5d3af805d77c5 \

  stakeManagerAddr=$(cat genesis.json | jq -r '.params.engine.polybft.bridge.stakeManagerAddr')
  stakeToken=$(cat genesis.json | jq -r '.params.engine.polybft.bridge.stakeTokenAddr')
  #echo "stake manager address:" $stakeManagerAddr
  #echo "stake token address:" $stakeToken   

  echo "Deploying to rootchain ......."
  ./polygon-edge rootchain deploy \
    --stake-manager ${stakeManagerAddr} \
    --stake-token ${stakeToken} \
    --deployer-key bb6bd15999db0b658beeefbe176080e9a6f8f34de9e87e5ad2e2d6ff029b027e \
    --json-rpc https://polygon-mumbai.infura.io/v3/4458cf4d1689497b9a38b1d6bbf05e78 \
  echo "Completed......"

  customSupernetManagerAddr=$(cat genesis.json | jq -r '.params.engine.polybft.bridge.customSupernetManagerAddr')
  supernetID=$(cat genesis.json | jq -r '.params.engine.polybft.supernetID')
  echo "Rootchain contracts deployed!"

  ./polygon-edge rootchain fund \
    --stake-token ${stakeToken} \
    --mint \
    --addresses ${address1},${address2},${address3},${address4} \
    --amounts 100000000000000000,100000000000000000,100000000000000000,100000000000000000 \
    --private-key bb6bd15999db0b658beeefbe176080e9a6f8f34de9e87e5ad2e2d6ff029b027e \
    --json-rpc https://polygon-mumbai.infura.io/v3/4458cf4d1689497b9a38b1d6bbf05e78 \
  echo "rootchain funded!!" 

  ./polygon-edge polybft whitelist-validators \
    --addresses ${address1},${address2},${address3},${address4} \
    --supernet-manager ${customSupernetManagerAddr} \
    --private-key bb6bd15999db0b658beeefbe176080e9a6f8f34de9e87e5ad2e2d6ff029b027e \
    --jsonrpc https://polygon-mumbai.infura.io/v3/4458cf4d1689497b9a38b1d6bbf05e78

  counter=1
  while [ $counter -le 4 ]; do
    echo "Registering validator: ${counter}"

    ./polygon-edge polybft register-validator \
      --supernet-manager ${customSupernetManagerAddr} \
      --data-dir test-chain-${counter} \
      --jsonrpc https://polygon-mumbai.infura.io/v3/4458cf4d1689497b9a38b1d6bbf05e78

    ./polygon-edge polybft stake \
      --data-dir test-chain-${counter} \
      --amount 100000000000000000 \
      --supernet-id ${supernetID} \
      --stake-manager ${stakeManagerAddr} \
      --stake-token ${stakeToken} \
      --jsonrpc https://polygon-mumbai.infura.io/v3/4458cf4d1689497b9a38b1d6bbf05e78

    ((counter++))
  done

  ./polygon-edge polybft supernet \
    --private-key bb6bd15999db0b658beeefbe176080e9a6f8f34de9e87e5ad2e2d6ff029b027e \
    --supernet-manager ${customSupernetManagerAddr} \
    --stake-manager ${stakeManagerAddr} \
    --finalize-genesis-set \
    --enable-staking \
    --jsonrpc https://polygon-mumbai.infura.io/v3/4458cf4d1689497b9a38b1d6bbf05e78
}

function startServerFromBinary() {
  if [ "$1" == "write-logs" ]; then
    echo "Writing validators logs to the files..."
    ./polygon-edge server --data-dir ./test-chain-1 --chain genesis.json \
      --grpc-address :10000 --libp2p :30301 --jsonrpc :10002 --relayer \
      --num-block-confirmations 2 --seal --log-level DEBUG 2>&1 | tee ./validator-1.log &
    ./polygon-edge server --data-dir ./test-chain-2 --chain genesis.json \
      --grpc-address :20000 --libp2p :30302 --jsonrpc :20002 \
      --num-block-confirmations 2 --seal --log-level DEBUG 2>&1 | tee ./validator-2.log &
    ./polygon-edge server --data-dir ./test-chain-3 --chain genesis.json \
      --grpc-address :30000 --libp2p :30303 --jsonrpc :30002 \
      --num-block-confirmations 2 --seal --log-level DEBUG 2>&1 | tee ./validator-3.log &
    ./polygon-edge server --data-dir ./test-chain-4 --chain genesis.json \
      --grpc-address :40000 --libp2p :30304 --jsonrpc :40002 \
      --num-block-confirmations 2 --seal --log-level DEBUG 2>&1 | tee ./validator-4.log &
    wait
  else
    ./polygon-edge server --data-dir ./test-chain-1 --chain genesis.json \
      --grpc-address :10000 --libp2p :30301 --jsonrpc :10002 --relayer \
      --num-block-confirmations 2 --seal --log-level DEBUG &
    ./polygon-edge server --data-dir ./test-chain-2 --chain genesis.json \
      --grpc-address :20000 --libp2p :30302 --jsonrpc :20002 \
      --num-block-confirmations 2 --seal --log-level DEBUG &
    ./polygon-edge server --data-dir ./test-chain-3 --chain genesis.json \
      --grpc-address :30000 --libp2p :30303 --jsonrpc :30002 \
      --num-block-confirmations 2 --seal --log-level DEBUG &
    ./polygon-edge server --data-dir ./test-chain-4 --chain genesis.json \
      --grpc-address :40000 --libp2p :30304 --jsonrpc :40002 \
      --num-block-confirmations 2 --seal --log-level DEBUG &
    wait
  fi
}

function startServerFromDockerCompose() {
  if [ "$1" != "polybft" ]
  then
    export EDGE_CONSENSUS="$1"
  fi

  docker-compose -f ./docker/local/docker-compose.yml up -d --build
}

function destroyDockerEnvironment() {
  docker-compose -f ./docker/local/docker-compose.yml down -v
}

function stopDockerEnvironment() {
  docker-compose -f ./docker/local/docker-compose.yml stop
}

set -e

# Reset test-dirs
rm -rf test-chain-*
rm -f genesis.json

# Build binary
go build -o polygon-edge .

# If --docker flag is set run docker environment otherwise run from binary
case "$2" in
"--docker")
  # cluster {consensus} --docker destroy
  if [ "$3" == "destroy" ]; then
    destroyDockerEnvironment
    echo "Docker $1 environment destroyed!"
    exit 0
  # cluster {consensus} --docker stop
  elif [ "$3" == "stop" ]; then
    stopDockerEnvironment
    echo "Docker $1 environment stoped!"
    exit 0
  fi

  # cluster {consensus} --docker
  echo "Running $1 docker environment..."
  startServerFromDockerCompose $1
  echo "Docker $1 environment deployed."
  exit 0
  ;;
# cluster {consensus}
*)
  echo "Running $1 environment from local binary..."
  # Initialize ibft or polybft consensus
  if [ "$1" == "ibft" ]; then
    # Initialize ibft consensus
    initIbftConsensus
    # Create genesis file and start the server from binary
    createGenesis
    startServerFromBinary $2
    exit 0
  elif [ "$1" == "polybft" ]; then
    # Initialize polybft consensus
    initPolybftConsensus
    # Create genesis file and start the server from binary
    createGenesis
    initRootchain $2
    startServerFromBinary $2
    exit 0
  else
    echo "Unsupported consensus mode. Supported modes are: ibft and polybft "
    exit 1
  fi
  ;;
esac
deepalt92 commented 1 year ago

Hi @Stefan-Ethernal Thank you so much for your reply. I'll attempt executing your script and let you know how it goes with the branch you mentioned: https://github.com/0xPolygon/polygon-edge/tree/v1.1.1-alternative. I'll close this issue for now and keep you updated if there's anything else.

deepalt92 commented 1 year ago

Hi @Stefan-Ethernal I attempted your script. When I execute it, I get "transaction underpriced" for either Rootchain contract deployments or Rootchain funding commands. I executed the script multiple times and faced the same issue. Burnt some MATIC mumbai in the process also although I still have sufficient MATIC to send transactions to Mumbai.

I suspect the Gas price in Mumbai increases due to usage and the transactions fail. When executing the script multiple times I get "replacement transactions underpriced". This is naturally because the transaction is sent from the same account and it requires a higher gas fee to replace an existing transaction.

One thing I noticed with the console output was the the Gas Price prints as 0 (screenshot below). image

I digged into the Golang code and noticed that the txn.GasPrice is set by querying the RPC endpoint according to txrelayer/txrelayer.go. The code snippet pertaining to this is:

gasPrice, err := t.Client().Eth().GasPrice()
 if err != nil {
      return ethgo.ZeroHash, fmt.Errorf("failed to get gas price: %w", err)
  }
 txn.GasPrice = gasPrice + (gasPrice * feeIncreasePercentage / 100)

txn.GasPrice seems to be an uint64 value. However, the value fetched from the RPC endpoint is a Big.Int. I maybe wrong but I think the txn.GasPrice value is set to 0 because the Big.Int gets converted (cast) to uint64.

Anyway, should I try to bump the GasPrice in the code by doing something as below?

txn.GasPrice = 5 + gasPrice + (gasPrice * feeIncreasePercentage / 100)

guillermovahi commented 1 year ago

Hi, @deepalt92 do you have any update on this? I am always getting the same error while deploying smart contracts on the rootchain: 'transaction underpriced'. Either I use v1.1.0 or v1.1.1

deepalt92 commented 1 year ago

@guillermovahi It worked with v0.8 and v0.9. Anyway, Polygon has taken down the Supernet docs. Therefore, I did not pursue this further. They now seem to have what is known as a CDK. It's an evolution of the supernet with ZKP.