diff --git a/go.mod b/go.mod index ce1e57942..e038ff803 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/golang/protobuf v1.5.3 github.com/gorilla/mux v1.8.1 github.com/grpc-ecosystem/grpc-gateway v1.16.0 - github.com/osmosis-labs/osmosis/v15 v15.0.0-00010101000000-000000000000 + github.com/osmosis-labs/osmosis/v15 v15.2.1 github.com/rakyll/statik v0.1.7 github.com/spf13/cast v1.5.1 github.com/spf13/cobra v1.8.0 diff --git a/scripts/fraud_proof_poc/Dockerfile.dymd b/scripts/fraud_proof_poc/Dockerfile.dymd new file mode 100644 index 000000000..4bd8825f4 --- /dev/null +++ b/scripts/fraud_proof_poc/Dockerfile.dymd @@ -0,0 +1,13 @@ +FROM golang:1.20.13-alpine + +RUN apk add git alpine-sdk +RUN apk add linux-headers bash +RUN git clone https://github.com/dymensionxyz/dymension.git --branch 'fraud_proof_poc' + +WORKDIR /go/dymension +RUN go mod tidy +RUN make install +RUN sh scripts/setup_local.sh +EXPOSE 36657 + +CMD ["dymd", "start"] diff --git a/scripts/fraud_proof_poc/Dockerfile.mock-da b/scripts/fraud_proof_poc/Dockerfile.mock-da new file mode 100644 index 000000000..336d40ad2 --- /dev/null +++ b/scripts/fraud_proof_poc/Dockerfile.mock-da @@ -0,0 +1,12 @@ +FROM golang:1.21.7-alpine AS builder + +RUN apk add git alpine-sdk +RUN apk add linux-headers + +RUN git clone https://github.com/dymensionxyz/dymint.git +WORKDIR /go/dymint/da/grpc/mockserv/cmd +RUN go mod tidy + +EXPOSE 7980 + +ENTRYPOINT ["go", "run", "main.go"] diff --git a/scripts/fraud_proof_poc/Dockerfile.rollapp-evm b/scripts/fraud_proof_poc/Dockerfile.rollapp-evm new file mode 100644 index 000000000..48c1a1702 --- /dev/null +++ b/scripts/fraud_proof_poc/Dockerfile.rollapp-evm @@ -0,0 +1,44 @@ +FROM golang:1.20.13 AS builder + +RUN git clone 'https://github.com/dymensionxyz/rollapp-evm.git' --branch 'feat/fraudproofs' +WORKDIR /go/rollapp-evm +RUN go mod tidy +RUN make install + +WORKDIR /go +RUN apt update && apt install sudo jq -y + +RUN curl -L https://dymensionxyz.github.io/roller/install.sh | bash +RUN git clone https://github.com/dymensionxyz/roller.git +WORKDIR /go/roller +RUN git checkout b4977ec4a6d9231fcd0c1ee1d869d5450665a75c +RUN make build +RUN mv build/roller /usr/local/bin + +WORKDIR /go +COPY ./wait-for-hub.sh . +RUN sudo chmod +x ./wait-for-hub.sh + +RUN rm -rf ./rollapp-evm/ +RUN rm -rf ./roller/ + +FROM builder + +# CACHEBUST invalidates the cache so that a new roller config is created on each build and new wallets are generated +# podman build -f Dockerfile.rollapp-evm --build-arg CACHEBUST=$(date +%s) -t dymension:fraud_proof_poc_rollapp +ARG CACHEBUST=1 + +ENV ROLLAPP_NAME "dummy" +ENV ROLLAPP_DENOM "dum" +ENV ROLLAPP_BINARY "/go/bin/rollapp-evm" + +RUN ls -la /usr/local/bin +RUN roller config init ${ROLLAPP_NAME} ${ROLLAPP_DENOM} --hub local --da local --rollapp-binary ${ROLLAPP_BINARY} > rollapp_init +RUN sed -i 's/^batch_submit_max_time.*/batch_submit_max_time = "10s"/' ~/.roller/rollapp/config/dymint.toml +RUN sed -i 's/^da_layer.*/da_layer = "grpc"/' ~/.roller/rollapp/config/dymint.toml +RUN sed -i 's/^.*"min_gas_price".*/"min_gas_price": "0.0",/' ~/.roller/rollapp/config/genesis.json +RUN sed -i 's/^empty_blocks_max_time.*/empty_blocks_max_time = "2s"/' ~/.roller/rollapp/config/dymint.toml +RUN sed -i 's/^da_config.*/da_config = "{\\\"host\\\": \\\"mock-da\\\", \\\"port\\\": 7980}"/' ~/.roller/rollapp/config/dymint.toml +RUN roller config set hub-rpc "http://hub:36657" + +CMD [ "sleep", "infinity" ] diff --git a/scripts/fraud_proof_poc/Dockerfile.rollepp-evm-fullnode b/scripts/fraud_proof_poc/Dockerfile.rollepp-evm-fullnode new file mode 100644 index 000000000..596345098 --- /dev/null +++ b/scripts/fraud_proof_poc/Dockerfile.rollepp-evm-fullnode @@ -0,0 +1,48 @@ +FROM golang:1.20.13 AS builder + +RUN apt update && apt install sudo dnsutils jq -y +RUN git clone 'https://github.com/dymensionxyz/rollapp-evm.git' --branch 'feat/fraudproofs' +WORKDIR /go/rollapp-evm +RUN go mod tidy +RUN make install + +WORKDIR /go + +RUN git clone 'https://github.com/dymensionxyz/dymension.git' --branch 'fraud_proof_poc' + +RUN curl -L https://dymensionxyz.github.io/roller/install.sh | bash +RUN git clone https://github.com/dymensionxyz/roller.git +WORKDIR /go/roller +RUN git checkout b4977ec4a6d9231fcd0c1ee1d869d5450665a75c +RUN make build +RUN mv build/roller /usr/local/bin + +WORKDIR /go +COPY ./wait-for-hub.sh . +RUN sudo chmod +x ./wait-for-hub.sh + +# RUN rm -rf ./rollapp-evm/ +# RUN rm -rf ./roller/ + +FROM builder + +# CACHEBUST invalidates the cache so that a new roller config is created on each build and new wallets are generated +# podman build -f Dockerfile.rollapp-evm --build-arg CACHEBUST=$(date +%s) -t dymension:fraud_proof_poc_rollapp +ARG CACHEBUST=1 + +ENV ROLLAPP_NAME "dummy" +ENV ROLLAPP_DENOM "dum" +ENV ROLLAPP_BINARY "/go/bin/rollapp-evm" + +RUN roller config init ${ROLLAPP_NAME} ${ROLLAPP_DENOM} --hub local --da local --rollapp-binary ${ROLLAPP_BINARY} > rollapp_init +RUN sed -i 's/^da_layer.*/da_layer = "grpc"/' ~/.roller/rollapp/config/dymint.toml +RUN sed -i 's/^da_config.*/da_config = "{\\\"host\\\": \\\"mock-da\\\", \\\"port\\\": 7980}"/' ~/.roller/rollapp/config/dymint.toml +RUN sed -i 's/^aggregator.*/aggregator = "false"/' ~/.roller/rollapp/config/dymint.toml +RUN sed -i 's/^settlement_layer.*/settlement_layer = "dymension"/' ~/.roller/rollapp/config/dymint.toml +RUN sed -i 's/^node_address.*/node_address = \"http:\/\/hub:36657\"/' ~/.roller/rollapp/config/dymint.toml +RUN sed -i 's/^gas_limit.*/gas_limit = 0/' ~/.roller/rollapp/config/dymint.toml +RUN sed -i 's/^gas_prices.*/gas_prices = "100000000adym"/' ~/.roller/rollapp/config/dymint.toml +RUN sed -i 's/^gas_fees.*/gas_fees = ""/' ~/.roller/rollapp/config/dymint.toml +RUN roller config set hub-rpc "http://hub:36657" + +CMD [ "sleep", "infinity" ] diff --git a/scripts/fraud_proof_poc/README.md b/scripts/fraud_proof_poc/README.md new file mode 100644 index 000000000..1990dc44a --- /dev/null +++ b/scripts/fraud_proof_poc/README.md @@ -0,0 +1,111 @@ +# Demo + +This demo will set up the hub with a DA layer, a light node, and a full node. The nodes use a modified EVM rollapp. +The full node will misbehave with some probability. +The light node will check every block for fraud and submit generate a proof if fraud is detected. +We manually submit any such proof to the hub. + +## Steps + +this example can be executed using `podman` or `docker` + +1. run `podman compose up`, this will spin up all the necessary infrastructure that includes a local hub, mock da layer, sequencer with `fraud proof` feature enabled and a full node + +2. once you see `hub is ready with latest_block_height: 1` in the compose logs, you can attach to the nodes +and proceed with the following steps + +### hub + +``` +# fund the wallets that were generated during rollapp initialization +# extract the addresses to fund: you can find the generated wallets inside /go/rollapp_init file on the rollapp-evm and rollapp-evm-fullnode containers +for container in fraud_proof_poc-rollapp-evm-1 fraud_proof_poc-rollapp-evm-fullnode-1; do + podman exec -it "$container" /bin/bash -c 'grep -Po "(dym[a-zA-Z0-9]+)" /go/rollapp_init' | grep -v 'dymension' +done +``` + +`podman exec -it fraud_proof_poc-hub-1 /bin/bash` + +the following commands are executed inside the hub container + +```sh +wallets=("dym19230y5hrang2qte9cgvvsn0jgtpqwfde9v37tf" "dym1d7fha6gnle77erxkv7z8h3cutfa5gudw928n4d" "dym1trt53uzqyavltgz3msf6xnd5zhgstsgam70232" "dym1v5pme26uk94zkycy3y943djl94s7h0u3drwcys") + +for wallet in "${wallets[@]}"; do + echo "funding ${wallet}" + dymd tx bank send local-user $wallet \ + 10dym --gas-prices 100000000adym --yes -b block --keyring-backend test +done +``` + +### Sequencer + +`podman exec -it fraud_proof_poc-rollapp-evm-1 /bin/bash` + +the following commands are executed inside the sequencer container + +```sh +# after funding the wallets from the hub node +# register the rollapp +roller tx register +# ! note down the rollapp-id +# ! note down the node-id +rollapp-evm dymint show-node-id --home ~/.roller/rollapp + +# start the sequencer with fraud_proof enabled +# '&' starts the rollapp in the background, remove if you want +rollapp-evm --home ~/.roller/rollapp start --dymint.simulate_fraud --log_level debug & + +# ! start the full node before generating transactions +# generate transactions to create fraud with 0.5% probability +rollapp-evm --home ~/.roller/rollapp/ tx bank send \ + rollapp_sequencer ethm1wss9w8e89ntkn73n25lm6c7ul36u282c4sq5qm 100000adum \ + --keyring-backend test --broadcast-mode block -y --keyring-backend test +``` + +### Full Node +copy the `genesis.json` file from the sequencer to the full node + +```sh +podman cp fraud_proof_poc-rollapp-evm-1:/root/.roller/rollapp/config/genesis.json \ + fraud_proof_poc-rollapp-evm-fullnode-1:/root/.roller/rollapp/config/genesis.json +``` + +`podman exec -it fraud_proof_poc-rollapp-evm-fullnode-1 /bin/sh` + +the following commands are executed inside the fullnode container + +```sh +# noted in the sequencer steps +export ROLLAPP_CHAIN_ID="dummy_9361346-1" +# noted in the sequencer steps +export SEQUENCER_NODE_ID="12D3KooWQrNRe8ejp13aQauGze9UZw1kmgYR73K5iyzsKxVirLjz" +``` + +```sh +sed -i "s/^rollapp_id.*/rollapp_id = \"${ROLLAPP_CHAIN_ID}\"/" ~/.roller/rollapp/config/dymint.toml +sed -i "s/^seeds =.*/seeds = \"tcp:\/\/${SEQUENCER_NODE_ID}@$(dig +short rollapp-evm):26656\/\"/" ~/.roller/rollapp/config/config.toml + +rollapp-evm --home ~/.roller/rollapp start +# once a fraud is created - the node will panic and generate a fraud proof file +# named `fraudProof_rollapp_with_tx.json` +``` + +outside the container, run + +```sh +# copy and submit the fraud proof +podman cp fraud_proof_poc-rollapp-evm-fullnode-1:/go/fraudProof_rollapp_with_tx.json \ + fraud_proof_poc-hub-1:/go/fraudProof_rollapp_with_tx.json +``` + +inside the hub container, run the following command to submit the fraud + +```sh +# from hub node +dymd tx rollapp submit-fraud ${ROLLAPP_CHAIN_ID} \ + /go/fraudProof_rollapp_with_tx.json --from local-user \ + --gas 50000000 -b block +``` + +if everything went through fine, hub log will show `fraud proof verified` \ No newline at end of file diff --git a/scripts/fraud_proof_poc/docker-compose.yaml b/scripts/fraud_proof_poc/docker-compose.yaml new file mode 100644 index 000000000..5dca8f3f2 --- /dev/null +++ b/scripts/fraud_proof_poc/docker-compose.yaml @@ -0,0 +1,38 @@ +version: '3.8' + +services: + mock-da: + build: + context: . + dockerfile: Dockerfile.mock-da + ports: + - "7980:7980" + + hub: + build: + context: . + dockerfile: Dockerfile.dymd + ports: + - "36657:36657" + + rollapp-evm: + build: + context: . + dockerfile: Dockerfile.rollapp-evm + args: + CACHEBUST: ${CACHEBUST} + depends_on: + - mock-da + - hub + command: [ "/go/wait-for-hub.sh", "sleep", "infinity" ] + + rollapp-evm-fullnode: + build: + context: . + dockerfile: Dockerfile.rollepp-evm-fullnode + args: + CACHEBUST: ${CACHEBUST} + depends_on: + - mock-da + - hub + command: [ "/go/wait-for-hub.sh", "sleep", "infinity" ] diff --git a/scripts/fraud_proof_poc/wait-for-hub.sh b/scripts/fraud_proof_poc/wait-for-hub.sh new file mode 100644 index 000000000..d6dd3c9f3 --- /dev/null +++ b/scripts/fraud_proof_poc/wait-for-hub.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Target URL +URL="http://hub:36657/status" + +# Wait for the /status endpoint to be available and the latest_block_height to be present +while true; do + # Use curl to fetch the status endpoint and jq to parse the JSON response + HEIGHT=$(curl -s $URL | jq -r '.result.sync_info.latest_block_height') + + # Check if HEIGHT is a number and greater than 0 (modify this check as needed) + if [[ "$HEIGHT" =~ ^[0-9]+$ ]] && [ "$HEIGHT" -gt 0 ]; then + echo "hub is ready with latest_block_height: $HEIGHT" + break + else + echo "Waiting for hub to be ready..." + fi + + sleep 5 # Wait for 5 seconds before trying again +done + +# Proceed with the rest of your script or command to start the service +exec "$@" \ No newline at end of file