|
| 1 | +This document provides a [docker-compose file](https://github.com/0xPolygonZero/eth-pos-devnet-provable/blob/959da56673c25c2094b1a23bc9e1fa9ae9a9db6e/docker-compose.yml) for running a fully-functional, local development network (devnet) for Ethereum with proof-of-stake enabled. |
| 2 | + |
| 3 | +The configuration uses [Prysm](https://github.com/prysmaticlabs/prysm) as a consensus client, with either [geth](https://github.com/ethereum/go-ethereum) or [erigon](https://github.com/ledgerwatch/erigon) as an execution client. |
| 4 | + |
| 5 | +<!-- **It starts from proof-of-stake** and does not go through the Ethereum merge. --> |
| 6 | + |
| 7 | +The setup is a single node devnet with 64 deterministically-generated validators[^1] to drive the creation of blocks in an Ethereum proof-of-stake chain. |
| 8 | + |
| 9 | +The devnet is fully functional and allows for deployment of smart contracts and all features that come with the Prysm consensus client, such as its rich set of APIs for retrieving data from the blockchain. |
| 10 | + |
| 11 | +Running a devnet like this provides the best way to understand Ethereum proof-of-stake under the hood, and gives allowance for devs to tinker with various settings that suit their system design. |
| 12 | + |
| 13 | +# Running the devnet |
| 14 | + |
| 15 | +First, checkout this [repository](https://github.com/0xPolygonZero/eth-pos-devnet-provable/tree/344fff4ee1032a0b095ab0c8d757e0ede72da156) and install docker. |
| 16 | + |
| 17 | +Then run the following command to fire up the devnet containers: |
| 18 | + |
| 19 | +``` bash |
| 20 | +docker compose up -d |
| 21 | +``` |
| 22 | + |
| 23 | +The statuses of the containers will be displayed as shown below: |
| 24 | + |
| 25 | +``` example |
| 26 | +$ docker compose up -d |
| 27 | +[+] Running 7/7 |
| 28 | +[+] Running 10/10 |
| 29 | + ✔ Container eth-pos-devnet-create-beacon-chain-genesis-1 Exited |
| 30 | + ✔ Container eth-pos-devnet-create-beacon-node-keys-1 Exited |
| 31 | + ✔ Container eth-pos-devnet-beacon-chain-2-1 Started |
| 32 | + ✔ Container eth-pos-devnet-beacon-chain-1-1 Started |
| 33 | + ✔ Container eth-pos-devnet-geth-genesis-1 Exited |
| 34 | + ✔ Container eth-pos-devnet-geth-import-1 Exited |
| 35 | + ✔ Container eth-pos-devnet-erigon-genesis-1 Started |
| 36 | + ✔ Container eth-pos-devnet-validator-1 Started |
| 37 | + ✔ Container eth-pos-devnet-erigon-1 Started |
| 38 | + ✔ Container eth-pos-devnet-geth-1 Started |
| 39 | +``` |
| 40 | + |
| 41 | +The containers can be stopped with this command: `docker compose stop`. |
| 42 | + |
| 43 | +It's advisable for each restart to be preceded with wiping old data. Use `make clean` for that. |
| 44 | + |
| 45 | +Logs of launched services can be inspected with this command: |
| 46 | + |
| 47 | +``` bash |
| 48 | +docker logs eth-pos-devnet-geth-1 -f |
| 49 | +``` |
| 50 | + |
| 51 | +# Available features |
| 52 | + |
| 53 | +- Starts from the Capella Ethereum hard fork. |
| 54 | +- The network launches with a [Validator Deposit Contract](https://github.com/ethereum/consensus-specs/blob/dev/solidity_deposit_contract/deposit_contract.sol) deployed at the address `0x4242424242424242424242424242424242424242`. This can be used to onboard new validators into the network by depositing 32 ETH into the contract. |
| 55 | +- The default account used in the go-ethereum node is at the address `0x85da99c8a7c2c95964c8efd687e95e632fc533d6`, which comes seeded with ETH for use in the network. This can be used to send transactions, deploy contracts, and more. |
| 56 | +- The default account at `0x85da99c8a7c2c95964c8efd687e95e632fc533d6` is also set as the fee recipient for transaction fees proposed by validators in Prysm. This address will be receiving the fees of all proposer activity. |
| 57 | +- The go-ethereum JSON-RPC API is available at `http://geth:8545`. |
| 58 | +- The Prysm client's REST APIs are available at `http://beacon-chain:3500`. For more info on what these APIs are, see [here](https://ethereum.github.io/beacon-APIs/) |
| 59 | +- The Prysm client also exposes a gRPC API at `http://beacon-chain:4000`. |
| 60 | + |
| 61 | +# Type 1 prover testing procedure |
| 62 | + |
| 63 | +The aim of this devnet setup is to use Polygon Type-1 Prover to test Erigon state witnesses. |
| 64 | + |
| 65 | +Next is a procedure for creating some test data. |
| 66 | + |
| 67 | +1. Start the devnet up with `docker compose up`. If you had previously run this command, you might want to wipe old data with a `make clean` to avoid running from a previous state. |
| 68 | +2. Wait for blocks to start being produced. This should only take a few seconds. You can use `polycli monitor` to quickly check that blocks are being created. |
| 69 | +3. Generate some load and test transactions, by using a tool like [polycli](https://github.com/maticnetwork/polygon-cli/blob/main/doc/polycli_loadtest.md) to create transactions. |
| 70 | +4. Once the load is done, and if you ran docker in detached mode, you can stop the devnet with `docker compose stop`. |
| 71 | +5. Checkout and build [jerrigon](https://github.com/0xPolygonZero/erigon/tree/feat/zero) from the `feat/zero` branch. You can use `make all` to build everything. |
| 72 | +6. Create a copy of the erigon state directory to avoid corrupting things |
| 73 | + |
| 74 | + ```bash |
| 75 | + sudo cp -r execution/erigon/ execution/erigon.bak |
| 76 | + sudo chown -R $USER:$USER execution/erigon.bak/ |
| 77 | + ``` |
| 78 | + |
| 79 | +7. Now we can start the Jerrigon fork of Erigon. This will give us RPC access to the state that we created in the previous steps. |
| 80 | + |
| 81 | + ```bash |
| 82 | + ~/code/jerrigon/build/bin/erigon \ |
| 83 | + --http \ |
| 84 | + --http.api=eth,net,web3,erigon,engine,debug \ |
| 85 | + --http.addr=0.0.0.0 \ |
| 86 | + --http.corsdomain=* \ |
| 87 | + --http.vhosts any \ |
| 88 | + --ws \ |
| 89 | + --nodiscover=true \ |
| 90 | + --txpool.disable=true \ |
| 91 | + --no-downloader=true \ |
| 92 | + --maxpeers 0 \ |
| 93 | + --datadir=./execution/erigon.bak |
| 94 | + ``` |
| 95 | + |
| 96 | +8. With the RPC running we can retrieve the blocks, witnesses, and use zero-bin to parse them. |
| 97 | + In one particular test case below, about 240 blocks worth of data were generated. |
| 98 | + So, `seq 0 240` was used for generating ranges of block numbers for testing purposes. |
| 99 | + |
| 100 | + ``` bash |
| 101 | + # Create a directory for storing the outputs |
| 102 | + mkdir out |
| 103 | +
|
| 104 | + # Call the zeroTracer to get the traces |
| 105 | + seq 0 240 | awk '{print "curl -o " sprintf("out/wit_%02d", $0) ".json -H '"'"'Content-Type: application/json'"'"' -d '"'"'{\"method\":\"debug_traceBlockByNumber\",\"params\":[\"" sprintf("0x%X", $0) "\", {\"tracer\": \"zeroTracer\"}],\"id\":1,\"jsonrpc\":\"2.0\"}'"'"' http://127.0.0.1:8545"}' | bash |
| 106 | +
|
| 107 | + # download the blocks (this assumes you have foundry/cast installed) |
| 108 | + seq 0 240 | awk '{print "cast block --full -j " $0 " > out/block_" sprintf("%02d", $0) ".json"}' | bash |
| 109 | + ``` |
| 110 | + |
| 111 | +9. At this point, we'll want to checkout and build [zero-bin](https://github.com/0xPolygonZero/zero-bin) in order to test proof generation. |
| 112 | + Make sure to checkout that repo and run `cargo build --release` to compile the application for testing. |
| 113 | +
|
| 114 | + The snippets below assume [zero-bin](https://github.com/0xPolygonZero/zero-bin) has been checked out and compiled in `$HOME/code/zero-bin`. |
| 115 | +
|
| 116 | + After compiling, the `leader` and `rpc` binaries will be created in the `target/release` folder. |
| 117 | +
|
| 118 | + ``` bash |
| 119 | + # use zero-bin to convert witness formats. This is a basic test |
| 120 | + seq 0 240 | awk '{print "~/code/zero-bin/target/release/rpc fetch --rpc-url http://127.0.0.1:8545 --block-number " $0 " > " sprintf("out/zero_%02d", $0) ".json" }' | bash |
| 121 | +
|
| 122 | + # use zero-bin to generate a proof for the genesis block |
| 123 | + ./leader --arithmetic 16..23 --byte-packing 9..21 --cpu 12..25 --keccak 14..20 --keccak-sponge 9..15 --logic 12..18 --memory 17..28 --runtime in-memory -n 1 jerigon --rpc-url http://127.0.0.1:8545 --block-number 1 --proof-output-path 1.json |
| 124 | + seq 2 240 | awk '{print "./leader --arithmetic 16..23 --byte-packing 9..21 --cpu 12..25 --keccak 14..20 --keccak-sponge 9..15 --logic 12..18 --memory 17..28 --runtime in-memory -n 4 jerigon --rpc-url http://127.0.0.1:8545 --block-number " $1 " --proof-output-path " $1 ".json --previous-proof " ($1 - 1) ".json"}' |
| 125 | + ``` |
| 126 | +
|
| 127 | +
|
| 128 | +## Operational notes |
| 129 | +
|
| 130 | +- Pay attention to memory usage on the system running |
| 131 | + `zero-bin`. Certain transactions can consume a lot of memory and |
| 132 | + lead to an out-of-memory (OOM) error. |
| 133 | +- You'll want to run `zero-bin` on a system with at least 32GB of RAM. |
| 134 | +- When you run `zero-bin`, a local file will be created with a name |
| 135 | + like `prover_state_*`. This file needs to be deleted if any of the |
| 136 | + [circuit sizes are changed](https://github.com/0xPolygonZero/zero-bin#leader-usage). |
| 137 | +- There is a [useful script](https://github.com/0xPolygonZero/zero-bin/blob/assorted_fixes/tools/prove_blocks.sh) in `zero-bin` to run a range of proofs. |
| 138 | + |
| 139 | + |
| 140 | +Both the state witness generation and decoding logic are actively being improved. |
| 141 | + |
| 142 | +We expect that the following transaction types or use-cases should to be proved without any issues: |
| 143 | + |
| 144 | +- Empty blocks (important use case) |
| 145 | +- EOA transfers |
| 146 | +- ERC-20 mints & transfers |
| 147 | +- ERC-721 mintes & transfers |
| 148 | + |
| 149 | +### Short cuts |
| 150 | + |
| 151 | +This is a shortcut to create the genesis file allocations for our |
| 152 | +mnemonic. This has already been hard-coded into the genesis file. |
| 153 | + |
| 154 | +But if you want to use a different testing account, you can use the one below. |
| 155 | + |
| 156 | +``` bash |
| 157 | +polycli wallet inspect --mnemonic "code code code code code code code code code code code quality" | jq '.Addresses[] | {"key": .ETHAddress, "value": { "balance": "0x21e19e0c9bab2400000"}}' | jq -s 'from_entries' |
| 158 | +``` |
| 159 | + |
| 160 | +[^1]: See Line# 11 of the docker-compose.yml https://github.com/0xPolygonZero/eth-pos-devnet-provable/blob/959da56673c25c2094b1a23bc9e1fa9ae9a9db6e/docker-compose.yml#L11 |
0 commit comments