diff --git a/.circleci/config.yml b/.circleci/config.yml index 59a135e..88cc60b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,7 @@ version: 2.1 executors: buildpack: docker: - - image: circleci/buildpack-deps:trusty + - image: circleci/buildpack-deps:xenial working_directory: ~/src commands: @@ -13,6 +13,13 @@ commands: min_exit_period: type: integer description: "The value used for plasma contracts deployment" + docker_compose_command: + type: string + description: "Which docker compose files should we use?" + vault: + type: string + default: "false" + description: "True/false" steps: - run: name: Get Plasma Deployer image and standup geth and deploy contracts @@ -28,40 +35,33 @@ commands: fi echo 'export TAG='${TAG} >> $BASH_ENV # this docker compose up needs to be above the gcloud login because the credentials are different! - MIN_EXIT_PERIOD=<< parameters.min_exit_period >> IMAGE=${TAG} docker-compose up -d + MIN_EXIT_PERIOD=<< parameters.min_exit_period >> IMAGE=${TAG} << parameters.docker_compose_command >> echo $GCLOUD_SERVICE_KEY | gcloud auth activate-service-account --key-file=- gcloud --quiet config set project ${GOOGLE_PROJECT_ID} gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE} - - run: + - run: name: Docker logs working_directory: ~/project/contracts background: true - command: | - docker-compose logs -f - - run: - name: Wait for contracts + command: | + docker-compose logs -f + - run: + name: Wait for contracts command: | sleep 5m # wait until we're UP - for i in {1..60}; do + for i in {1..160}; do if [ "$(curl localhost:8000/contracts)" ]; then break fi; sleep 1 done - run: - name: Stop nodes - working_directory: ~/project/contracts - command: | - echo "stop geth in docker so that we can snapshot" - docker exec -it $(docker ps -aqf "name=geth") /bin/sh -c "pkill -INT geth" - sudo rm -f data/geth.ipc - - run: - name: Snapshot + name: Extract partial data from the deployment working_directory: ~/project/contracts command: | CONTRACT_SHA=$(cat ../tester/CONTRACT_SHA) - TAR_NAME=$(echo data-${TAG}-MIN_EXIT_PERIOD-<< parameters.min_exit_period >>-PLASMA_CONTRACTS_SHA-${CONTRACT_SHA}.tar.gz | sed 's/:/-/') + TAR_NAME=$(echo data-${TAG}-MIN_EXIT_PERIOD-<< parameters.min_exit_period >>-PLASMA_CONTRACTS_SHA-${CONTRACT_SHA}-VAULT-<< parameters.vault >>.tar.gz | sed 's/:/-/') echo ${TAR_NAME} # for every key in object db.json create a file # where the key is the name of the file and the content of the file is it's value @@ -70,13 +70,37 @@ commands: for i in "${!KEYS[@]}"; do echo $(cat plasma-contracts/build/db.json | jq -r '.contracts' | jq -r '.'${KEYS[i]} | tr -d '"') > plasma-contracts/build/"${KEYS[i]}" done + - run: + name: Has the deployment succeeded? + working_directory: ~/project/contracts + command: | + # "startStandardExitBondSize()" |> ABI.encode([]) |> ExPlasma.Encoding.to_hex() + export PEG=$(cat plasma-contracts/build/payment_exit_game) + response=$(curl -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method": "eth_call", "params": [{"from": "0xd6858A28aA07A1cd8cA285443e80E2b0A031d50d", "to": "'"$PEG"'", "data": "0xfe32a124"}, "latest"], "id": 8}' http://127.0.0.1:8545) + echo $response | jq -r '.' + echo $response | ( ! grep "error" ) + echo $response | ( ! grep "0x0000000000000000000000000000000000000000000000000000000000000000" ) + - run: + name: Stop nodes + working_directory: ~/project/contracts + command: | + echo "stop geth in docker so that we can snapshot" + docker exec -it $(docker ps -aqf "name=geth") /bin/sh -c "pkill -INT geth" + docker stop $(docker ps -aqf "name=vault_server") + sudo rm -f data/geth.ipc + - run: + name: Snapshot + working_directory: ~/project/contracts + command: | + CONTRACT_SHA=$(cat ../tester/CONTRACT_SHA) + TAR_NAME=$(echo data-${TAG}-MIN_EXIT_PERIOD-<< parameters.min_exit_period >>-PLASMA_CONTRACTS_SHA-${CONTRACT_SHA}-VAULT-<< parameters.vault >>.tar.gz | sed 's/:/-/') # at this point we snapshot folders we're interested in - sudo tar czf ${TAR_NAME} data/geth plasma-contracts/contracts/ plasma-contracts/build/* ../tester/CONTRACT_SHA + sudo tar czf ${TAR_NAME} data/geth plasma-contracts/contracts/ plasma-contracts/build/* ../tester/CONTRACT_SHA immutability/config/ export BOTO_CONFIG=/dev/null gsutil cp ${TAR_NAME} gs://circleci-docker-artifacts echo "https://storage.googleapis.com/circleci-docker-artifacts/${TAR_NAME}" PLASMA_CONTRACTS=$(curl localhost:8000/contracts) - DATA=$(echo "Contracts snapshotted with MIN_EXIT_PERIOD for SHA ( ${CONTRACT_SHA} ): << parameters.min_exit_period >>.\r\n Snapshot located at: \r\n https://storage.googleapis.com/circleci-docker-artifacts/${TAR_NAME} \r\n Contract addresses: \r\n ${PLASMA_CONTRACTS} " | jq -Rs '.') + DATA=$(echo "Contracts snapshotted with MIN_EXIT_PERIOD for SHA ( ${CONTRACT_SHA} ): << parameters.min_exit_period >>. Vault: << parameters.vault >> \r\n Snapshot located at: \r\n https://storage.googleapis.com/circleci-docker-artifacts/${TAR_NAME} \r\n Contract addresses: \r\n ${PLASMA_CONTRACTS} " | jq -Rs '.') if [ "$CIRCLE_BRANCH" = "master" ]; then # append the data you would usually post as a comment to a file and create a release out of this file echo ${DATA} >> /tmp/release @@ -85,8 +109,10 @@ commands: curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST -d "{\"body\": ${DATA} }" "https://api.github.com/repos/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/issues/${CIRCLE_PULL_REQUEST##*/}/comments" fi ls data/geth - docker-compose down + docker-compose down sudo rm -rf data/geth/chaindata data/geth/LOCK data/geth/lightchaindata data/geth/nodekey data/geth/nodes data/geth/transactions.rlp + sudo rm -rf immutability/config/data + sudo rm -rf immutability/config/ca.crt immutability/config/ca.key immutability/config/ca.srl immutability/config/my-service.crt immutability/config/my-service.csr immutability/config/my-service.key immutability/config/openssl.cnf immutability/config/unseal.json snapshot_reorg: description: Deploy contracts to Geth via docker-compose with parametrized MIN_EXIT_PERIOD and expose addresses and snapshot URL @@ -97,7 +123,7 @@ commands: steps: - run: name: Get Plasma Deployer image and standup geth and deploy contracts - no_output_timeout: 40m + working_directory: ~/project/contracts_reorg command: | IMAGE_NAME=elixir-omg-tester-plasma-deployer if [ "$CIRCLE_BRANCH" = "master" ]; then @@ -107,34 +133,48 @@ commands: IMAGE_GIT=$(git rev-parse --short HEAD) TAG="$IMAGE_NAME:dev-$IMAGE_GIT" fi - cd contracts_reorg/ - CONTRACT_SHA=$(cat ../tester/CONTRACT_SHA) + echo 'export TAG='${TAG} >> $BASH_ENV + # this docker compose up needs to be above the gcloud login because the credentials are different! MIN_EXIT_PERIOD=<< parameters.min_exit_period >> IMAGE=${TAG} docker-compose up -d - timeout 25m docker-compose logs --follow || true - - ### in the mean time, install gcloud requirements - wget https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-272.0.0-linux-x86_64.tar.gz -O gcloud-sdk.tar.gz - tar zxf gcloud-sdk.tar.gz google-cloud-sdk - mv google-cloud-sdk ~/.google-cloud-sdk - ~/.google-cloud-sdk/install.sh --quiet echo $GCLOUD_SERVICE_KEY | gcloud auth activate-service-account --key-file=- gcloud --quiet config set project ${GOOGLE_PROJECT_ID} gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE} - ### done installing gcloud requirements - ### cleanup - rm -rf ~/.google-cloud-sdk + - run: + working_directory: ~/project/contracts_reorg + command: | + timeout 25m docker-compose logs --follow || true + background: true + - run: + name: Docker logs + working_directory: ~/project/contracts_reorg + background: true + command: | + docker-compose logs -f + - run: + name: Wait for contracts + no_output_timeout: 50m + command: | + sleep 30m # wait until we're UP - for i in {1..60}; do + for i in {1..160}; do if [ "$(curl localhost:8000/contracts)" ]; then break fi; - sleep 1 + sleep 10 done - # stop geth in docker so that we can snapshot + - run: + name: Stop nodes + working_directory: ~/project/contracts_reorg + command: | + echo "stop geth in docker so that we can snapshot" docker exec -it $(docker ps -aqf "name=node-1") /bin/sh -c "pkill -INT geth" - # ipc is not for cp sudo rm -f data/geth.ipc sudo rm -f data/geth/nodekey + - run: + name: Get Plasma Deployer image and standup geth and deploy contracts + no_output_timeout: 40m + working_directory: ~/project/contracts_reorg + command: | TAR_NAME=$(echo data-${TAG}-MIN_EXIT_PERIOD-<< parameters.min_exit_period >>-PLASMA_CONTRACTS_SHA-${CONTRACT_SHA}-reorg.tar.gz | sed 's/:/-/') echo ${TAR_NAME} # for every key in object db.json create a file @@ -158,9 +198,11 @@ commands: curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST -d "{\"body\": ${DATA} }" "https://api.github.com/repos/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/issues/${CIRCLE_PULL_REQUEST##*/}/comments" fi ls data/geth - docker-compose down - sudo rm -rf data/geth/chaindata data/geth/LOCK data/geth/lightchaindata data/geth/nodekey data/geth/nodes data/geth/transactions.rlp - + docker-compose down + sudo rm -rf data/geth/chaindata data/geth/LOCK data/geth/lightchaindata data/geth/nodekey data/geth/nodes data/geth/transactions.rlp + sudo rm -rf immutability/config/data + sudo rm -rf immutability/config/ca.crt immutability/config/ca.key immutability/config/ca.srl immutability/config/my-service.crt immutability/config/my-service.csr immutability/config/my-service.key immutability/config/openssl.cnf immutability/config/unseal.json + docker_import: description: "Load Docker acrhive from the given directory" parameters: @@ -205,10 +247,6 @@ commands: type: string description: "Path to persist Docker archive" default: "~/docker" - build-arg: - type: string - description: "Args to pass into docker file" - default: "" steps: - when: condition: <> @@ -226,11 +264,7 @@ commands: DIRNAME="$(dirname "$DOCKERFILE")" cd "$DIRNAME" || exit 1 - if [ -z "<>" ]; then - docker build . --cache-from "<>" -t "<>" -f "$BASENAME" - else - docker build . --cache-from "<>" -t "<>" -f "$BASENAME" --build-arg <> - fi + docker build . --cache-from "<>" -t "<>" -f "$BASENAME" - when: condition: <> steps: @@ -300,7 +334,8 @@ jobs: build_builder_erlang: executor: buildpack steps: - - setup_remote_docker + - setup_remote_docker: + version: 19.03.13 - attach_workspace: *attach_workspace - docker_build: image: "omisegoimages/elixir-omg-builder-erlang" @@ -314,7 +349,8 @@ jobs: build_builder_elixir: executor: buildpack steps: - - setup_remote_docker + - setup_remote_docker: + version: 19.03.13 - attach_workspace: *attach_workspace - docker_build: image: "omisegoimages/elixir-omg-builder-elixir" @@ -328,7 +364,8 @@ jobs: build_builder_rocksdb: executor: buildpack steps: - - setup_remote_docker + - setup_remote_docker: + version: 19.03.13 - attach_workspace: *attach_workspace - docker_build: image: "omisegoimages/elixir-omg-builder-rocksdb" @@ -342,7 +379,8 @@ jobs: build_builder: executor: buildpack steps: - - setup_remote_docker + - setup_remote_docker: + version: 19.03.13 - attach_workspace: *attach_workspace - docker_build: image: "omisegoimages/elixir-omg-builder" @@ -356,7 +394,8 @@ jobs: build_childchain_builder: executor: buildpack steps: - - setup_remote_docker + - setup_remote_docker: + version: 19.03.13 - attach_workspace: *attach_workspace - docker_build: image: "omisego/childchain-builder" @@ -370,7 +409,8 @@ jobs: build_tester_geth: executor: buildpack steps: - - setup_remote_docker + - setup_remote_docker: + version: 19.03.13 - attach_workspace: *attach_workspace - docker_build: image: "omisegoimages/elixir-omg-tester-geth" @@ -384,13 +424,15 @@ jobs: build_tester_plasma_deployer: executor: buildpack steps: - - setup_remote_docker + - setup_remote_docker: + version: 19.03.13 - attach_workspace: *attach_workspace + - run: | + echo ${GITHUB_TOKEN} | git clone https://omisego-bot@github.com/omgnetwork/$(cat tester/CONTRACT_REPO_NAME).git tester/plasma-contracts - docker_build: image: "omisegoimages/elixir-omg-tester-plasma-deployer" dockerfile: "tester/Dockerfile.plasma_deployer" export: "~/docker/omisegoimages_elixir-omg_tester_plasma_deployer.tar" - build-arg: "GITHUB_TOKEN=${GITHUB_TOKEN}" - persist_to_workspace: <<: *persist_workspace paths: @@ -399,7 +441,8 @@ jobs: build_tester: executor: buildpack steps: - - setup_remote_docker + - setup_remote_docker: + version: 19.03.13 - attach_workspace: *attach_workspace - docker_build: image: "omisegoimages/elixir-omg-tester" @@ -413,7 +456,8 @@ jobs: publish_builder: executor: buildpack steps: - - setup_remote_docker + - setup_remote_docker: + version: 19.03.13 - attach_workspace: *attach_workspace - docker_import: path: "~/docker" @@ -423,7 +467,8 @@ jobs: publish_childchain_builder: executor: buildpack steps: - - setup_remote_docker + - setup_remote_docker: + version: 19.03.13 - attach_workspace: *attach_workspace - docker_import: path: "~/docker" @@ -433,7 +478,8 @@ jobs: publish_tester: executor: buildpack steps: - - setup_remote_docker + - setup_remote_docker: + version: 19.03.13 - attach_workspace: *attach_workspace - docker_import: path: "~/docker" @@ -443,7 +489,8 @@ jobs: publish_plasma_deployer: executor: buildpack steps: - - setup_remote_docker + - setup_remote_docker: + version: 19.03.13 - attach_workspace: *attach_workspace - docker_import: path: "~/docker" @@ -453,7 +500,8 @@ jobs: build_deploy: executor: buildpack steps: - - setup_remote_docker + - setup_remote_docker: + version: 19.03.13 - attach_workspace: *attach_workspace - docker_build: image: "omisegoimages/elixir-omg-deploy" @@ -467,7 +515,8 @@ jobs: publish_deploy: executor: buildpack steps: - - setup_remote_docker + - setup_remote_docker: + version: 19.03.13 - attach_workspace: *attach_workspace - docker_import: path: "~/docker" @@ -490,12 +539,38 @@ jobs: steps: - checkout - attach_workspace: *attach_workspace + - run: + name: Login so that we can pull Vault + command: | + echo $GCLOUD_SERVICE_KEY_VAULT | gcloud auth activate-service-account --key-file=- + gcloud auth configure-docker --quiet + - run: docker login -u $DOCKER_USER -p $DOCKER_PASS + - run: + name: Setup data dir + working_directory: ~/project/contracts + command: | + sudo chmod -R 777 immutability/config/ - snapshot: min_exit_period: 20 + docker_compose_command: "docker-compose -f docker-compose.yml -f docker-compose.vault.yml up -d" + vault: "true" - snapshot: min_exit_period: 120 + docker_compose_command: "docker-compose -f docker-compose.yml -f docker-compose.vault.yml up -d" + vault: "true" + # - snapshot: + # min_exit_period: 240 + # docker_compose_command: "docker-compose -f docker-compose.yml -f docker-compose.vault.yml up -d" + # vault: "true" + - snapshot: + min_exit_period: 20 + docker_compose_command: "docker-compose up -d" - snapshot: - min_exit_period: 240 + min_exit_period: 120 + docker_compose_command: "docker-compose up -d" + # - snapshot: + # min_exit_period: 240 + # docker_compose_command: "docker-compose up -d" - run: name: Gather all the snapshots and publish a release command: | @@ -515,6 +590,17 @@ jobs: steps: - checkout - attach_workspace: *attach_workspace + - run: + name: Login so that we can pull Vault + command: | + echo $GCLOUD_SERVICE_KEY_VAULT | gcloud auth activate-service-account --key-file=- + gcloud auth configure-docker --quiet + - run: docker login -u $DOCKER_USER -p $DOCKER_PASS + - run: + name: Setup data dir + working_directory: ~/project/contracts_reorg + command: | + sudo chmod -R 777 immutability/config/ - snapshot_reorg: min_exit_period: 120 - run: diff --git a/.gitignore b/.gitignore index 3431bf6..a22724c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,23 @@ -contracts/data/geth \ No newline at end of file +contracts/data/geth +contracts/immutability/config/ca.crt +contracts/immutability/config/ca.key +contracts/immutability/config/ca.srl +contracts/immutability/config/my-service.crt +contracts/immutability/config/my-service.csr +contracts/immutability/config/my-service.key +contracts/immutability/config/openssl.cnf +contracts/immutability/config/unseal.json +contracts/plasma-contracts/contracts/ + +contracts_reorg/data/geth +contracts_reorg/immutability/config/ca.crt +contracts_reorg/immutability/config/ca.key +contracts_reorg/immutability/config/ca.srl +contracts_reorg/immutability/config/my-service.crt +contracts_reorg/immutability/config/my-service.csr +contracts_reorg/immutability/config/my-service.key +contracts_reorg/immutability/config/openssl.cnf +contracts_reorg/immutability/config/unseal.json +contracts_reorg/plasma-contracts/contracts/ +contracts_reorg/ethash/ + diff --git a/builder/Dockerfile b/builder/Dockerfile index 055c1ad..0ec5724 100644 --- a/builder/Dockerfile +++ b/builder/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.12 +FROM alpine:3.13 LABEL maintainer="OmiseGO Team " LABEL description="Builder image for OmiseGO elixir-omg" diff --git a/builder/Dockerfile.erlang b/builder/Dockerfile.erlang index 4020488..53274c7 100644 --- a/builder/Dockerfile.erlang +++ b/builder/Dockerfile.erlang @@ -1,4 +1,4 @@ -FROM alpine:3.12 +FROM alpine:3.13 ARG OTP_VERSION="23.1.4" ARG OTP_DOWNLOAD_SHA256="8f6718b82bbca72d7dfe0b0de10b6e043cefe9e5ac08d3f84e18f8522d794967" diff --git a/builder_childchain/Dockerfile b/builder_childchain/Dockerfile index 6b1ad62..2e0fb35 100644 --- a/builder_childchain/Dockerfile +++ b/builder_childchain/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.12 +FROM alpine:3.13 LABEL maintainer="OmiseGO Team " LABEL description="Thin Builder image for OmiseGO Childchain" diff --git a/contracts/data/command b/contracts/data/command new file mode 100755 index 0000000..7fd0628 --- /dev/null +++ b/contracts/data/command @@ -0,0 +1,37 @@ +# don't run --allow-insecure-unlock in production! +apk add --update curl +# Configures geth with the deployer and authority accounts. This includes: +# 1. Configuring the deployer's keystore +# 2. Configuring the authority's keystore +# 3. Configuring the keystores' password +# 4. Unlocking the accounts by their indexes +geth --datadir data/ init data/geth/genesis.json +echo "" > /tmp/geth-blank-password +# Starts geth +geth \ +--nousb \ +--miner.gastarget 7500000 \ +--miner.gasprice "10" \ +--datadir data/ \ +--syncmode 'full' \ +--networkid 1337 \ +--keystore=./data/geth/keystore/ \ +--password /tmp/geth-blank-password \ +--unlock "0,1" \ +--http \ +--http.api personal,web3,eth,net \ +--http.addr 0.0.0.0 \ +--http.vhosts=* \ +--http.port 8545 \ +--ws \ +--ws.addr 0.0.0.0 \ +--ws.origins '*' \ +--ws.api personal,web3,eth,net \ +--rpc.allow-unprotected-txs \ +--mine \ +--allow-insecure-unlock + + +# Since we realize people/tooling issuing unprotected transactions can’t change overnight, +# Geth v1.10.0 supports reverting to the old behavior and accepting non-EIP155 transactions via --rpc.allow-unprotected-txs. +# Be advised that this is a temporary mechanism that will be removed long term. diff --git a/contracts/data/geth/genesis.json b/contracts/data/geth/genesis.json index 7d18627..bc6ef39 100644 --- a/contracts/data/geth/genesis.json +++ b/contracts/data/geth/genesis.json @@ -11,6 +11,7 @@ "petersburgBlock": 6, "istanbulBlock": 7, "muirGlacierBlock": 8, + "berlinBlock": 9, "clique": { "period": 1, "epoch": 30000 diff --git a/contracts/docker-compose.vault.yml b/contracts/docker-compose.vault.yml new file mode 100644 index 0000000..f8ce594 --- /dev/null +++ b/contracts/docker-compose.vault.yml @@ -0,0 +1,7 @@ +version: "2.3" +services: + plasma-contracts: + environment: + - VAULT=true + + diff --git a/contracts/docker-compose.yml b/contracts/docker-compose.yml index aa2f137..ef31e0e 100644 --- a/contracts/docker-compose.yml +++ b/contracts/docker-compose.yml @@ -6,10 +6,15 @@ services: - /bin/sh - -c - | + # deploy the multisig + cd /home/node/plasma-contracts/MultiSigWallet + npx truffle migrate --accounts 0x6De4b3B9C28E9C3e84c2b2d3a875C947a84de68D --confirmations 1 --network remote apk add --update curl cd /home/node/plasma-contracts/plasma_framework # Fix block gas limit issue by retrying truffle migration up to 5 times npx truffle version + export VAULT_TOKEN=$$(cat /tmp/unseal.json | jq -r .root_token) + echo $$VAULT_TOKEN for i in 1 2 3 4 5; do \ echo 'Running truffle migration attempt #$${i}' npx truffle migrate --network remote command && break; \ @@ -24,6 +29,7 @@ services: volumes: - ${PWD}/plasma-contracts/contracts/:/home/node/plasma-contracts/plasma_framework/build/contracts/ - ${PWD}/plasma-contracts/build/db.json:/home/node/plasma-contracts/plasma_framework/build/db.json + - "./immutability/config:/tmp:rw" environment: # DEPLOYER_PRIVATEKEY is the geth dev account initially funded address - DEPLOYER_PRIVATEKEY=d885a307e35738f773d8c9c63c7a3f3977819274638d04aaf934a1e1158513ce # 0x6De4b3B9C28E9C3e84c2b2d3a875C947a84de68D @@ -32,10 +38,18 @@ services: - REMOTE_URL=http://geth:8545 - DEPLOY_TEST_CONTRACTS=true - MIN_EXIT_PERIOD=${MIN_EXIT_PERIOD} + # HEY THIS IS IMPORTANT + - VAULT=false + - VAULT_ADDR=https://vault_server:8200 + - NODE_TLS_REJECT_UNAUTHORIZED=0 + - VAULT_RPC_REMOTE_URL=http://geth:8545 + - CHAIN_ID=1337 env_file: ../tester/CONTRACT_EXPERIMENTAL_FEATURES depends_on: geth: condition: service_healthy + vault_server: + condition: service_healthy restart: always healthcheck: test: curl plasma-contracts:8000/contracts @@ -45,36 +59,8 @@ services: start_period: 5m geth: - image: ethereum/client-go:v1.9.15 - entrypoint: - - /bin/sh - - -c - - | - # don't run --allow-insecure-unlock in production! - apk add --update curl - # Configures geth with the deployer and authority accounts. This includes: - # 1. Configuring the deployer's keystore - # 2. Configuring the authority's keystore - # 3. Configuring the keystores' password - # 4. Unlocking the accounts by their indexes - geth --datadir data/ init data/geth/genesis.json - echo "" > /tmp/geth-blank-password - # Starts geth - - geth --miner.gastarget 7500000 \ - --miner.gasprice "10" \ - --datadir data/ \ - --syncmode 'full' \ - --networkid 1337 \ - --gasprice '1' \ - --keystore=./data/geth/keystore/ \ - --password /tmp/geth-blank-password \ - --unlock "0,1" \ - --rpc --rpcapi personal,web3,eth,net --rpcaddr 0.0.0.0 --rpcvhosts=* --rpcport=8545 \ - --ws --wsaddr 0.0.0.0 --wsorigins='*' \ - --mine \ - --allow-insecure-unlock - + image: ethereum/client-go:v1.10.1 + entrypoint: /bin/sh -c ". data/command" ports: - "8545:8545" - "8546:8546" @@ -88,3 +74,26 @@ services: interval: 5s timeout: 3s retries: 5 + + vault_server: + image: gcr.io/omisego-development/omgnetwork/vault:0.0.7 + entrypoint: > + /bin/sh -c " + sleep 2 + + /vault/config/entrypoint.sh + " + ports: + - "8200:8200" + links: + - "geth" + volumes: + - "./immutability/ca:/vault/ca:rw" + - "./immutability/ca/certs/:/etc/ssl/certs/" + - "./immutability/config:/vault/config:rw" + healthcheck: + test: vault status --tls-skip-verify + interval: 5s + timeout: 3s + retries: 5 + diff --git a/contracts/immutability/config/entrypoint.sh b/contracts/immutability/config/entrypoint.sh new file mode 100755 index 0000000..332dad4 --- /dev/null +++ b/contracts/immutability/config/entrypoint.sh @@ -0,0 +1,174 @@ +#!/bin/bash + +# Vault running in the container must listen on a different port. + +VAULT_CREDENTIALS="/vault/config/unseal.json" + +CONFIG_DIR="/vault/config" + +CA_CERT="$CONFIG_DIR/ca.crt" +CA_KEY="$CONFIG_DIR/ca.key" +TLS_KEY="$CONFIG_DIR/my-service.key" +TLS_CERT="$CONFIG_DIR/my-service.crt" +CONFIG="$CONFIG_DIR/openssl.cnf" +CSR="$CONFIG_DIR/my-service.csr" + +export VAULT_ADDR="https://127.0.0.1:8200" +export VAULT_CACERT="$CA_CERT" + +function create_config { + + cat > "$CONFIG" << EOF + +[req] +default_bits = 2048 +encrypt_key = no +default_md = sha256 +prompt = no +utf8 = yes + +# Speify the DN here so we aren't prompted (along with prompt = no above). +distinguished_name = req_distinguished_name + +# Extensions for SAN IP and SAN DNS +req_extensions = v3_req + +# Be sure to update the subject to match your organization. +[req_distinguished_name] +C = TH +ST = Bangkok +L = Vault +O = omiseGO +CN = localhost + +# Allow client and server auth. You may want to only allow server auth. +# Link to SAN names. +[v3_req] +basicConstraints = CA:FALSE +subjectKeyIdentifier = hash +keyUsage = digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, serverAuth +subjectAltName = @alt_names + +# Alternative names are specified as IP.# and DNS.# for IPs and +# DNS accordingly. +[alt_names] +IP.1 = 127.0.0.1 +IP.2 = 192.168.64.1 +IP.3 = 192.168.122.1 +DNS.1 = localhost +EOF +} + +function gencerts { + + create_config + openssl req \ + -new \ + -sha256 \ + -newkey rsa:2048 \ + -days 120 \ + -nodes \ + -x509 \ + -subj "/C=US/ST=Maryland/L=Vault/O=My Company CA" \ + -keyout "$CA_KEY" \ + -out "$CA_CERT" + + # Generate the private key for the service. Again, you may want to increase + # the bits to 2048. + openssl genrsa -out "$TLS_KEY" 2048 + + # Generate a CSR using the configuration and the key just generated. We will + # give this CSR to our CA to sign. + openssl req \ + -new -key "$TLS_KEY" \ + -out "$CSR" \ + -config "$CONFIG" + + # Sign the CSR with our CA. This will generate a new certificate that is signed + # by our CA. + openssl x509 \ + -req \ + -days 120 \ + -in "$CSR" \ + -CA "$CA_CERT" \ + -CAkey "$CA_KEY" \ + -CAcreateserial \ + -sha256 \ + -extensions v3_req \ + -extfile "$CONFIG" \ + -out "$TLS_CERT" + + openssl x509 -in "$TLS_CERT" -noout -text + + # rm openssl.cnf + +# chown -R nobody:nobody $CONFIG_DIR && chmod -R 777 $CONFIG_DIR +} + +gencerts + +nohup vault server -log-level=debug -config /vault/config/vault.hcl & +VAULT_PID=$! + +function unseal() { + VAULT_INIT=$(cat $VAULT_CREDENTIALS) + UNSEAL_KEY=$(echo $VAULT_INIT | jq -r '.unseal_keys_hex[0]') + ROOT_TOKEN=$(echo $VAULT_INIT | jq -r .root_token) + vault operator unseal $UNSEAL_KEY + export VAULT_TOKEN=$ROOT_TOKEN +} + +function configure_plugin { + plugin_file="immutability-eth-plugin" + + echo "ADDING TO CATALOG: sys/plugins/catalog/secret/${plugin_file}" + + # just testing for now + plugin_file="${plugin_file}" + ls -latr /vault/plugins + sha256sum=`cat /vault/plugins/SHA256SUMS | awk '{print $1}'` + vault write sys/plugins/catalog/secret/${plugin_file} \ + sha_256="$sha256sum" \ + command="$plugin_file --ca-cert=$CA_CERT --client-cert=$TLS_CERT --client-key=$TLS_KEY" + + if [[ $? -eq 2 ]] ; then + echo "Vault Catalog update failed!" + exit 2 + fi + + echo "MOUNTING: ${plugin_file}" + vault secrets enable -path=${plugin_file} -plugin-name=${plugin_file} plugin + if [[ $? -eq 2 ]] ; then + echo "Failed to mount ${plugin_file} plugin for test!" + exit 2 + fi +} + +function test_banner { + echo "************************************************************************************************************************************" +} + + +if [ -f "$VAULT_CREDENTIALS" ]; then + echo "unseal.json exists" + sleep 10 + unseal + vault status + vault secrets list +else + echo "sleeping for 10s and generating unseal.json" + sleep 10 + VAULT_INIT=$(vault operator init -key-shares=1 -key-threshold=1 -format=json | jq .) + echo $VAULT_INIT > $VAULT_CREDENTIALS + unseal + configure_plugin + vault audit enable file file_path=stdout + vault status + vault secrets list + test_banner +fi + +# Don't exit until vault dies + +wait $VAULT_PID diff --git a/contracts/immutability/config/vault.hcl b/contracts/immutability/config/vault.hcl new file mode 100644 index 0000000..219492f --- /dev/null +++ b/contracts/immutability/config/vault.hcl @@ -0,0 +1,19 @@ +default_lease_ttl = "168h" +disable_mlock = "true" +max_lease_ttl = "720h" + +backend "file" { + path = "/vault/config/data" +} + +ui = "false" + +api_addr = "https://localhost:8200" +plugin_directory = "/vault/plugins" +listener "tcp" { + address = "0.0.0.0:8200" + tls_cert_file = "/vault/config/my-service.crt" + tls_client_ca_file = "/vault/config/ca.crt" + tls_key_file = "/vault/config/my-service.key" + tls_require_and_verify_client_cert = "false" +} diff --git a/contracts_reorg/data/geth/command b/contracts_reorg/data/geth/command index 35687ee..86ccff1 100755 --- a/contracts_reorg/data/geth/command +++ b/contracts_reorg/data/geth/command @@ -4,26 +4,35 @@ echo ${ACCOUNT} if ${INIT} then - geth --datadir data init ./data/geth/genesis.json + geth --datadir data/ init ./data/geth/genesis.json fi geth --datadir data/ \ --bootnodes ${BOOTNODES} \ ---keystore=data/geth/keystore/ \ +--keystore data/geth/keystore/ \ --networkid "1337" \ ---gasprice "1" \ --unlock "0,1" \ --password /tmp/geth-password \ ---mine --minerthreads=1 \ ---etherbase ${ACCOUNT} \ ---nat extip:`hostname -i` \ ---syncmode="full" \ ---allow-insecure-unlock \ ---rpc \ ---rpcaddr "0.0.0.0" \ ---rpcapi "personal,eth,web3,net,admin,debug,db" \ ---rpccorsdomain "*" \ ---rpcvhosts=* \ +--mine \ +--miner.threads 1 \ --miner.gastarget 7500000 \ --miner.gasprice "10" \ ---ws --wsaddr 0.0.0.0 --wsorigins='*' \ No newline at end of file +--miner.etherbase ${ACCOUNT} \ +--nat extip:`hostname -i` \ +--syncmode "full" \ +--allow-insecure-unlock \ +--http \ +--http.api personal,web3,eth,net \ +--http.addr 0.0.0.0 \ +--http.vhosts '*' \ +--http.port 8545 \ +--ws \ +--ws.addr 0.0.0.0 \ +--ws.origins '*' \ +--ws.api personal,web3,eth,net \ +--rpc.allow-unprotected-txs + +# Since we realize people/tooling issuing unprotected transactions can’t change overnight, +# Geth v1.10.0 supports reverting to the old behavior and accepting non-EIP155 transactions via --rpc.allow-unprotected-txs. +# Be advised that this is a temporary mechanism that will be removed long term. + diff --git a/contracts_reorg/data/geth/genesis.json b/contracts_reorg/data/geth/genesis.json index 3ba5818..ad21b4d 100644 --- a/contracts_reorg/data/geth/genesis.json +++ b/contracts_reorg/data/geth/genesis.json @@ -10,6 +10,8 @@ "constantinopleBlock": 0, "petersburgBlock": 0, "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, "ethash": {} }, "nonce": "0x0", diff --git a/contracts_reorg/docker-compose.vault.yml b/contracts_reorg/docker-compose.vault.yml new file mode 100644 index 0000000..eb721c4 --- /dev/null +++ b/contracts_reorg/docker-compose.vault.yml @@ -0,0 +1,6 @@ +version: "3" +services: + plasma-contracts: + environment: + - VAULT=true + \ No newline at end of file diff --git a/contracts_reorg/docker-compose.yml b/contracts_reorg/docker-compose.yml index 872210d..ee1731b 100644 --- a/contracts_reorg/docker-compose.yml +++ b/contracts_reorg/docker-compose.yml @@ -1,7 +1,7 @@ version: "3" services: node-1: - image: ethereum/client-go:v1.9.15 + image: ethereum/client-go:v1.10.1 hostname: node-1 environment: - ACCOUNT=0x8404AFE09D770271c935019F9f774CBA2bea291d @@ -24,12 +24,18 @@ services: - /bin/sh - -c - | + # deploy the multisig + cd /home/node/plasma-contracts/MultiSigWallet + npx truffle migrate --accounts 0x6De4b3B9C28E9C3e84c2b2d3a875C947a84de68D --confirmations 1 --network remote + apk add --update curl cd /home/node/plasma-contracts/plasma_framework # Fix block gas limit issue by retrying truffle migration up to 5 times npx truffle version + export VAULT_TOKEN=$$(cat /tmp/unseal.json | jq -r .root_token) + echo $$VAULT_TOKEN for i in 1 2 3 4 5; do \ - echo 'Running truffle migration attempt' - npx truffle migrate --network remote && break; \ + echo 'Running truffle migration attempt #$${i}' + npx truffle migrate --network remote command && break; \ done cd build echo '{"contracts":' > db.json && cat outputs.json >> db.json && echo '}' >> db.json @@ -41,6 +47,7 @@ services: volumes: - ${PWD}/plasma-contracts/contracts/:/home/node/plasma-contracts/plasma_framework/build/contracts/ - ${PWD}/plasma-contracts/build/db.json:/home/node/plasma-contracts/plasma_framework/build/db.json + - "./immutability/config:/tmp:rw" environment: # DEPLOYER_PRIVATEKEY is the geth dev account initially funded address - DEPLOYER_PRIVATEKEY=d885a307e35738f773d8c9c63c7a3f3977819274638d04aaf934a1e1158513ce # 0x6De4b3B9C28E9C3e84c2b2d3a875C947a84de68D @@ -49,6 +56,10 @@ services: - REMOTE_URL=http://172.25.0.102:8545 - DEPLOY_TEST_CONTRACTS=true - MIN_EXIT_PERIOD=120 + - VAULT=false + - VAULT_ADDR=https://172.25.0.155:8200 + - NODE_TLS_REJECT_UNAUTHORIZED=0 + - VAULT_RPC_REMOTE_URL=http://172.25.0.102:8545 env_file: ../tester/CONTRACT_EXPERIMENTAL_FEATURES depends_on: - node-1 @@ -57,6 +68,28 @@ services: chain: ipv4_address: 172.25.0.105 + vault_server: + image: gcr.io/omisego-development/omgnetwork/vault:0.0.7 + entrypoint: > + /bin/sh -c " + sleep 2 + /vault/config/entrypoint.sh + " + ports: + - "8200:8200" + volumes: + - "./immutability/ca:/vault/ca:rw" + - "./immutability/ca/certs/:/etc/ssl/certs/" + - "./immutability/config:/vault/config:rw" + healthcheck: + test: vault status --tls-skip-verify + interval: 5s + timeout: 3s + retries: 5 + networks: + chain: + ipv4_address: 172.25.0.155 + networks: chain: driver: bridge diff --git a/contracts_reorg/immutability/config/entrypoint.sh b/contracts_reorg/immutability/config/entrypoint.sh new file mode 100755 index 0000000..332dad4 --- /dev/null +++ b/contracts_reorg/immutability/config/entrypoint.sh @@ -0,0 +1,174 @@ +#!/bin/bash + +# Vault running in the container must listen on a different port. + +VAULT_CREDENTIALS="/vault/config/unseal.json" + +CONFIG_DIR="/vault/config" + +CA_CERT="$CONFIG_DIR/ca.crt" +CA_KEY="$CONFIG_DIR/ca.key" +TLS_KEY="$CONFIG_DIR/my-service.key" +TLS_CERT="$CONFIG_DIR/my-service.crt" +CONFIG="$CONFIG_DIR/openssl.cnf" +CSR="$CONFIG_DIR/my-service.csr" + +export VAULT_ADDR="https://127.0.0.1:8200" +export VAULT_CACERT="$CA_CERT" + +function create_config { + + cat > "$CONFIG" << EOF + +[req] +default_bits = 2048 +encrypt_key = no +default_md = sha256 +prompt = no +utf8 = yes + +# Speify the DN here so we aren't prompted (along with prompt = no above). +distinguished_name = req_distinguished_name + +# Extensions for SAN IP and SAN DNS +req_extensions = v3_req + +# Be sure to update the subject to match your organization. +[req_distinguished_name] +C = TH +ST = Bangkok +L = Vault +O = omiseGO +CN = localhost + +# Allow client and server auth. You may want to only allow server auth. +# Link to SAN names. +[v3_req] +basicConstraints = CA:FALSE +subjectKeyIdentifier = hash +keyUsage = digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, serverAuth +subjectAltName = @alt_names + +# Alternative names are specified as IP.# and DNS.# for IPs and +# DNS accordingly. +[alt_names] +IP.1 = 127.0.0.1 +IP.2 = 192.168.64.1 +IP.3 = 192.168.122.1 +DNS.1 = localhost +EOF +} + +function gencerts { + + create_config + openssl req \ + -new \ + -sha256 \ + -newkey rsa:2048 \ + -days 120 \ + -nodes \ + -x509 \ + -subj "/C=US/ST=Maryland/L=Vault/O=My Company CA" \ + -keyout "$CA_KEY" \ + -out "$CA_CERT" + + # Generate the private key for the service. Again, you may want to increase + # the bits to 2048. + openssl genrsa -out "$TLS_KEY" 2048 + + # Generate a CSR using the configuration and the key just generated. We will + # give this CSR to our CA to sign. + openssl req \ + -new -key "$TLS_KEY" \ + -out "$CSR" \ + -config "$CONFIG" + + # Sign the CSR with our CA. This will generate a new certificate that is signed + # by our CA. + openssl x509 \ + -req \ + -days 120 \ + -in "$CSR" \ + -CA "$CA_CERT" \ + -CAkey "$CA_KEY" \ + -CAcreateserial \ + -sha256 \ + -extensions v3_req \ + -extfile "$CONFIG" \ + -out "$TLS_CERT" + + openssl x509 -in "$TLS_CERT" -noout -text + + # rm openssl.cnf + +# chown -R nobody:nobody $CONFIG_DIR && chmod -R 777 $CONFIG_DIR +} + +gencerts + +nohup vault server -log-level=debug -config /vault/config/vault.hcl & +VAULT_PID=$! + +function unseal() { + VAULT_INIT=$(cat $VAULT_CREDENTIALS) + UNSEAL_KEY=$(echo $VAULT_INIT | jq -r '.unseal_keys_hex[0]') + ROOT_TOKEN=$(echo $VAULT_INIT | jq -r .root_token) + vault operator unseal $UNSEAL_KEY + export VAULT_TOKEN=$ROOT_TOKEN +} + +function configure_plugin { + plugin_file="immutability-eth-plugin" + + echo "ADDING TO CATALOG: sys/plugins/catalog/secret/${plugin_file}" + + # just testing for now + plugin_file="${plugin_file}" + ls -latr /vault/plugins + sha256sum=`cat /vault/plugins/SHA256SUMS | awk '{print $1}'` + vault write sys/plugins/catalog/secret/${plugin_file} \ + sha_256="$sha256sum" \ + command="$plugin_file --ca-cert=$CA_CERT --client-cert=$TLS_CERT --client-key=$TLS_KEY" + + if [[ $? -eq 2 ]] ; then + echo "Vault Catalog update failed!" + exit 2 + fi + + echo "MOUNTING: ${plugin_file}" + vault secrets enable -path=${plugin_file} -plugin-name=${plugin_file} plugin + if [[ $? -eq 2 ]] ; then + echo "Failed to mount ${plugin_file} plugin for test!" + exit 2 + fi +} + +function test_banner { + echo "************************************************************************************************************************************" +} + + +if [ -f "$VAULT_CREDENTIALS" ]; then + echo "unseal.json exists" + sleep 10 + unseal + vault status + vault secrets list +else + echo "sleeping for 10s and generating unseal.json" + sleep 10 + VAULT_INIT=$(vault operator init -key-shares=1 -key-threshold=1 -format=json | jq .) + echo $VAULT_INIT > $VAULT_CREDENTIALS + unseal + configure_plugin + vault audit enable file file_path=stdout + vault status + vault secrets list + test_banner +fi + +# Don't exit until vault dies + +wait $VAULT_PID diff --git a/contracts_reorg/immutability/config/vault.hcl b/contracts_reorg/immutability/config/vault.hcl new file mode 100644 index 0000000..219492f --- /dev/null +++ b/contracts_reorg/immutability/config/vault.hcl @@ -0,0 +1,19 @@ +default_lease_ttl = "168h" +disable_mlock = "true" +max_lease_ttl = "720h" + +backend "file" { + path = "/vault/config/data" +} + +ui = "false" + +api_addr = "https://localhost:8200" +plugin_directory = "/vault/plugins" +listener "tcp" { + address = "0.0.0.0:8200" + tls_cert_file = "/vault/config/my-service.crt" + tls_client_ca_file = "/vault/config/ca.crt" + tls_key_file = "/vault/config/my-service.key" + tls_require_and_verify_client_cert = "false" +} diff --git a/deploy/Dockerfile b/deploy/Dockerfile index 9bd2996..6aab44e 100644 --- a/deploy/Dockerfile +++ b/deploy/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.12 +FROM alpine:3.13 LABEL maintainer="OmiseGO Team " LABEL description="Deploy image for OmiseGO elixir-omg" diff --git a/tester/CONTRACT_SHA b/tester/CONTRACT_SHA index 3c024dc..d51538c 100644 --- a/tester/CONTRACT_SHA +++ b/tester/CONTRACT_SHA @@ -1 +1 @@ -b3a5c8d5232edfab8617f6939733b08b67863c8a +5d29c432e9b55ae2c7ec7a06a5e66761eca7ab28 diff --git a/tester/Dockerfile b/tester/Dockerfile index 328a463..d1294d7 100644 --- a/tester/Dockerfile +++ b/tester/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.12 +FROM alpine:3.13 LABEL maintainer="OmiseGO Team " LABEL description="Builder image for OmiseGO elixir-omg" diff --git a/tester/Dockerfile.geth b/tester/Dockerfile.geth index 2f23250..1cced31 100644 --- a/tester/Dockerfile.geth +++ b/tester/Dockerfile.geth @@ -1,12 +1,12 @@ -FROM alpine:3.12 +FROM alpine:3.13 -ARG GO_VERSION="1.13.8" +ARG GO_VERSION="1.15" #https://golang.org/dl/ -ARG GO_DOWNLOAD_SHA256="0567734d558aef19112f2b2873caa0c600f1b4a5827930eb5a7f35235219e9d8" +ARG GO_DOWNLOAD_SHA256="2d75848ac606061efe52a8068d0e647b35ce487a15bb52272c427df485193602" -ARG GETH_VERSION="1.9.11" +ARG GETH_VERSION="1.10.1" #this SHA was computed locally! -ARG GETH_DOWNLOAD_SHA256="226cf65cda4eab3e66e8042c3d8bcee8ed07c619ae0ec2421ed4b0abe97bb055" +ARG GETH_DOWNLOAD_SHA256="485ff7b9e5a34457ab424d7e2cb8d377dc571e8daf666e065a0a327b9e413cab" # Geth requires Golang, Golang requires Glibc RUN set -xe \ @@ -20,7 +20,7 @@ RUN set -xe \ && GO_DOWNLOAD_URL="https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" \ && GETH_DOWNLOAD_URL="https://github.com/ethereum/go-ethereum/archive/v${GETH_VERSION}.tar.gz" \ && ALPINE_GLIBC_BASE_URL="https://github.com/sgerrand/alpine-pkg-glibc/releases/download" \ - && ALPINE_GLIBC_PACKAGE_VERSION="2.29-r0" \ + && ALPINE_GLIBC_PACKAGE_VERSION="2.33-r0" \ && ALPINE_GLIBC_BASE_PACKAGE_FILENAME="glibc-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \ && ALPINE_GLIBC_BIN_PACKAGE_FILENAME="glibc-bin-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \ && ALPINE_GLIBC_I18N_PACKAGE_FILENAME="glibc-i18n-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \ diff --git a/tester/Dockerfile.plasma_deployer b/tester/Dockerfile.plasma_deployer index fbadcd4..2ab6adb 100644 --- a/tester/Dockerfile.plasma_deployer +++ b/tester/Dockerfile.plasma_deployer @@ -11,15 +11,20 @@ RUN apk add --update \ python-dev \ py-pip \ build-base \ - git + git \ + jq COPY CONTRACT_SHA /tmp/CONTRACT_SHA COPY CONTRACT_REPO_NAME /tmp/CONTRACT_REPO_NAME - -# pass in token for prompt instead of git clone https://${GITHUB_TOKEN}@github.com... to avoid -# leaving the token data in .git/config -RUN echo ${GITHUB_TOKEN} | git clone https://omisego-bot@github.com/omgnetwork/$(cat /tmp/CONTRACT_REPO_NAME).git plasma-contracts +COPY CONTRACT_SHA /tmp/CONTRACT_SHA +COPY CONTRACT_REPO_NAME /tmp/CONTRACT_REPO_NAME +COPY plasma-contracts /home/node/plasma-contracts RUN cd /home/node/plasma-contracts && git reset --hard $(cat /tmp/CONTRACT_SHA) RUN cd /home/node/plasma-contracts && npm install RUN cd /home/node/plasma-contracts/plasma_framework && rm -Rf ./build RUN cd /home/node/plasma-contracts/plasma_framework && npm install +RUN cd /home/node/plasma-contracts/ && git submodule init +RUN cd /home/node/plasma-contracts/ && git submodule update --remote +RUN cd /home/node/plasma-contracts/MultiSigWalletOverride && make init_multisig +RUN cd /home/node/plasma-contracts/MultiSigWallet && npm install +