diff --git a/README.md b/README.md index 4a7c9bb5..564dd972 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ bind-mounting the runtime state directory (`/serverdir/node`) into your local filesystem. ```bash -docker run --rm -ti -p5432:5432 -p8545:8545 -p8546:8546 -v /tmp/eth-runtime-test:/serverdir/node ghcr.io/oasisprotocol/sapphire-localnet:local -test-mnemonic -n 4 +docker run --rm -ti -80:80 -p5432:5432 -p8544-8547:8544-8547 -v /tmp/eth-runtime-test:/serverdir/node ghcr.io/oasisprotocol/sapphire-localnet:local -test-mnemonic -n 4 ``` If needed, the `oasis-web3-gateway` or `sapphire-paratime` executables could also be @@ -46,7 +46,7 @@ the full gateway & paratime stack together. For running tests, start the docker network without the gateway, by setting the `OASIS_DOCKER_NO_GATEWAY=yes` environment variable: ```bash -docker run --rm -ti -e OASIS_DOCKER_NO_GATEWAY=yes -p5432:5432 -p8544-8546:8544-8546 -v /tmp/eth-runtime-test:/serverdir/node ghcr.io/oasisprotocol/sapphire-localnet:local -test-mnemonic -n 4 +docker run --rm -ti -e OASIS_DOCKER_NO_GATEWAY=yes -p80:80 -p5432:5432 -p8544-8547:8544-8547 -v /tmp/eth-runtime-test:/serverdir/node ghcr.io/oasisprotocol/sapphire-localnet:local -test-mnemonic -n 4 ``` Once bootstrapped, run the tests: diff --git a/docker/common/explorer.env b/docker/common/explorer.env new file mode 100644 index 00000000..d9fc463f --- /dev/null +++ b/docker/common/explorer.env @@ -0,0 +1,16 @@ +REACT_APP_BUILD_DATETIME=0 +REACT_APP_BUILD_SHA=sha0000000000000000000000000000000000000 +REACT_APP_BUILD_VERSION= +REACT_APP_PRIVACY_POLICY=https://oasisprotocol.org/privacy-policy +REACT_APP_ENABLE_OASIS_MATOMO_ANALYTICS=false +REACT_APP_API=http://localhost:8547/v1/ +REACT_APP_TESTNET_API=http://localhost:8547/v1/ +REACT_APP_META_TITLE="Oasis Explorer - Localnet" +REACT_APP_META_IMAGE="Oasis Explorer - OpenGraph Banner.png" +REACT_APP_META_MANIFEST=app.webmanifest +REACT_APP_META_FAVICON=favicon.svg +REACT_APP_META_APPLE_ICON="Icon Blue 192.png" +REACT_APP_META_DESC="Official explorer for the Oasis Network - Localnet" +REACT_APP_SHOW_BUILD_BANNERS=true +REACT_APP_FIXED_NETWORK=testnet +REACT_APP_SHOW_FIAT_VALUES=false diff --git a/docker/common/nexus.yml b/docker/common/nexus.yml new file mode 100644 index 00000000..e3a27cab --- /dev/null +++ b/docker/common/nexus.yml @@ -0,0 +1,72 @@ +analysis: + source: &source_config + custom_chain: + history: + records: + - archive_name: eden + genesis_height: 1 + chain_context: {{CHAIN_CONTEXT}} + runtime_start_rounds: + {{PARATIME_NAME}}: 0 + sdk_network: + chain_context: {{CHAIN_CONTEXT}} + rpc: unix:/serverdir/node/net-runner/network/client-0/internal.sock + domination: + symbol: TEST + decimals: 9 + paratimes: + default: {{PARATIME_NAME}} + all: + {{PARATIME_NAME}}: + id: 8000000000000000000000000000000000000000000000000000000000000000 + denominations: + "_": + symbol: TEST + decimals: 18 + consensus_denomination: "_" + nodes: + eden: + default: + rpc: unix:/serverdir/node/net-runner/network/client-0/internal.sock + ipfs: + gateway: https://ipfs.io + analyzers: + consensus: + from: 1 # Localnet genesis. + {{PARATIME_NAME}}: + from: 1 # Localnet genesis. + consensus_accounts_list: + interval: 30s + evm_tokens_{{PARATIME_NAME}}: + interval: 30s + evm_nfts_{{PARATIME_NAME}}: + interval: 30s + evm_token_balances_{{PARATIME_NAME}}: + interval: 30s + evm_contract_code_{{PARATIME_NAME}}: + interval: 30s + evm_abi_{{PARATIME_NAME}}: + interval: 30s + validator_staking_history: + from: 1 + node_stats: + interval: 1s + layers: + - consensus + - {{PARATIME_NAME}} + aggregate_stats: {} + storage: + backend: postgres + endpoint: postgresql://postgres:postgres@localhost:5432/nexus?sslmode=disable + migrations: file:///nexus-migrations + +server: + source: *source_config + endpoint: 0.0.0.0:8547 + storage: + endpoint: postgresql://postgres:postgres@localhost:5432/nexus?sslmode=disable + backend: postgres + +log: + level: {{LOG_LEVEL}} + format: json diff --git a/docker/common/start.sh b/docker/common/start.sh index 28eec281..aa9a25fa 100755 --- a/docker/common/start.sh +++ b/docker/common/start.sh @@ -13,6 +13,9 @@ # - OASIS_CLI_BINARY (optional): path to oasis binary. If provided, Oasis CLI will be configured for Localnet # - ENVOY_BINARY (optional): path to Envoy binary. If provided, Envoy proxy to Oasis Client node will be started # - ENVOY_CONFIG_FILE: path to Envoy config file. Required if ENVOY_BINARY is provided +# - OASIS_NEXUS_BINARY: path to oasis-nexus binary +# - OASIS_NEXUS_CONFIG_FILE: path to oasis-nexus config file. Required if OASIS_NEXUS_BINARY is provided +# - OASIS_EXPLORER_DIR: path to explorer (nexus frontend) directory rm -f /CONTAINER_READY @@ -26,6 +29,8 @@ export OASIS_DOCKER_DEBUG_DISK_AND_CPU_USAGE=${OASIS_DOCKER_DEBUG_DISK_AND_CPU_U export OASIS_SINGLE_COMPUTE_NODE=${OASIS_SINGLE_COMPUTE_NODE:-1} +export EXPLORER_PORT=${EXPLORER_PORT:-80} + OASIS_WEB3_GATEWAY_VERSION=$(${OASIS_WEB3_GATEWAY_BINARY} -v | head -n1 | cut -d " " -f 3 | sed -r 's/^v//') OASIS_CORE_VERSION=$(${OASIS_NODE_BINARY} -v | head -n1 | cut -d " " -f 3 | sed -r 's/^v//') VERSION=$(cat /VERSION) @@ -41,6 +46,8 @@ OASIS_KM_SOCKET=${OASIS_NODE_DATADIR}/net-runner/network/keymanager-0/internal.s OASIS_WEB3_GATEWAY_PID="" OASIS_NODE_PID="" ENVOY_PID="" +NEXUS_PID="" +EXPLORER_PID="" set -euo pipefail @@ -54,6 +61,12 @@ function cleanup { if [[ -n "${ENVOY_PID}" ]]; then kill -9 ${ENVOY_PID} fi + if [[ -n "${NEXUS_PID}" ]]; then + kill -9 ${NEXUS_PID} + fi + if [[ -n "${EXPLORER_PID}" ]]; then + kill -9 ${EXPLORER_PID} + fi } trap cleanup INT TERM EXIT @@ -226,6 +239,37 @@ else sleep 10 fi +# Once everything is initialized and setup, start Nexus and Explorer. +if [ ! -z "${OASIS_NEXUS_BINARY:-}" ]; then + notice "Creating database 'nexus'\n" + su -c "createdb -h 127.0.0.1 -p 5432 -U postgres nexus" postgres + + notice "Waiting for Nexus to start" + # Configure Nexus config file. + chain_context=$(${OASIS_NODE_BINARY} control status -a unix:${OASIS_NODE_SOCKET} | jq -r .consensus.chain_context) + sed -i 's/{{CHAIN_CONTEXT}}/'"${chain_context}"'/g' ${OASIS_NEXUS_CONFIG_FILE} + sed -i 's/{{LOG_LEVEL}}/'"${OASIS_NODE_LOG_LEVEL}"'/g' ${OASIS_NEXUS_CONFIG_FILE} + sed -i 's/{{PARATIME_NAME}}/'"${PARATIME_NAME}"'/g' ${OASIS_NEXUS_CONFIG_FILE} + + ${OASIS_NEXUS_BINARY} --config ${OASIS_NEXUS_CONFIG_FILE} 2>1 &>/var/log/nexus.log & + NEXUS_PID=$! + + # Wait for Oasis Nexus to start. + while ! curl -s http://localhost:8547/ 2>1 &>/dev/null; do echo -n .; sleep 1; done + echo +fi + +if [ ! -z "${OASIS_EXPLORER_DIR:-}" ]; then + notice "Waiting for Explorer to start" + cd ${OASIS_EXPLORER_DIR} + serve -s ${OASIS_EXPLORER_DIR} -l ${EXPLORER_PORT} > /var/log/explorer.log 2>&1 & + EXPLORER_PID=$! + + # Wait for Explorer to start. + while ! curl -s http://localhost:${EXPLORER_PORT}/ 2>1 &>/dev/null; do echo -n .; sleep 1; done + echo +fi + notice "Populating accounts...\n\n" ${OASIS_DEPOSIT_BINARY} -sock unix:${OASIS_NODE_SOCKET} "$@" @@ -284,6 +328,8 @@ echo printf "${YELLOW}WARNING: The chain is running in ephemeral mode. State will be lost after restart!${OFF}\n\n" notice "GRPC listening on ${CYAN}http://localhost:8544${OFF}.\n" notice "Web3 RPC listening on ${CYAN}http://localhost:8545${OFF} and ${CYAN}ws://localhost:8546${OFF}. Chain ID: ${GATEWAY__CHAIN_ID}.\n" +notice "Nexus API listening on ${CYAN}http://localhost:8547${OFF}.\n" +notice "Localnet Explorer available at ${CYAN}http://localhost:${EXPLORER_PORT}${OFF}.\n" notice "Container start-up took ${CYAN}$((T_END-T_START))${OFF} seconds, node log level is set to ${CYAN}${OASIS_NODE_LOG_LEVEL}${OFF}.\n" touch /CONTAINER_READY diff --git a/docker/emerald-localnet/Dockerfile b/docker/emerald-localnet/Dockerfile index 37d80c9f..2f8547d5 100644 --- a/docker/emerald-localnet/Dockerfile +++ b/docker/emerald-localnet/Dockerfile @@ -4,10 +4,57 @@ FROM golang:1.22.3 AS oasis-web3-gateway COPY . /go/oasis-web3-gateway RUN cd oasis-web3-gateway && make && strip -S -x oasis-web3-gateway docker/common/oasis-deposit/oasis-deposit +FROM ghcr.io/oasisprotocol/oasis-core-dev:stable-24.2.x AS oasis-core-dev + +# ARG NEXUS_VERSION=0.4.0 +# RUN wget https://github.com/oasisprotocol/nexus/releases/download/v${NEXUS_VERSION}/oasis_nexus_${NEXUS_VERSION}_linux_amd64.tar.gz \ +# && tar -zxvf oasis_nexus_${NEXUS_VERSION}_linux_amd64.tar.gz \ +# && strip -S -x /oasis_nexus_${NEXUS_VERSION}_linux_amd64/nexus \ +# && mv /oasis_nexus_${NEXUS_VERSION}_linux_amd64/nexus / \ +# && rm -rf /oasis_nexus_${NEXUS_VERSION}_linux_amd64* && \ +# # We also need to fetch the storage migrations. +# git clone https://github.com/oasisprotocol/nexus.git nexus-git --branch v${NEXUS_VERSION} --depth 1 \ +# && mv /nexus-git/storage/migrations /nexus-migrations \ +# && rm -rf nexus-git +ARG NEXUS_VERSION=main +RUN git clone https://github.com/oasisprotocol/nexus.git nexus-git --depth 1 \ + && cd nexus-git \ + && git fetch --depth 1 origin ${NEXUS_VERSION} \ + && git checkout ${NEXUS_VERSION} \ + && go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.12 \ + && make codegen-go \ + && go build \ + && strip -S -x /nexus-git/nexus \ + && mv /nexus-git/nexus / \ + && mv /nexus-git/storage/migrations /nexus-migrations \ + && rm -rf /nexus-git + +# ARG EXPLORER_REPO=https://github.com/oasisprotocol/explorer.git +# ARG EXPLORER_VERSION=v1.13.0 +# TODO: update once some support for localnet is added: https://github.com/oasisprotocol/explorer/issues/1597 +ARG EXPLORER_REPO=https://github.com/ptrus/explorer.git +ARG EXPLORER_VERSION=1a78782e10fa266707a428c5fd8ba91966d588a1 +COPY docker/common/explorer.env /nexus.env.production +RUN git clone ${EXPLORER_REPO} explorer --depth 1 \ + && cd explorer \ + && git fetch origin ${EXPLORER_VERSION} --depth 1 \ + && git checkout FETCH_HEAD \ + && mv /nexus.env.production .env.production \ + && echo "REACT_APP_LOCALNET_EMERALD=true\nREACT_APP_LOCALNET_SAPPHIRE=false" >> .env.production \ + && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ + && apt install -y nodejs \ + && npm install -g yarn \ + && yarn install \ + && NODE_ENV=production yarn build + + # Build emerald-localnet FROM postgres:16-bookworm RUN apt update && apt install -y bash libseccomp2 unzip jq binutils curl wget && apt clean \ && su -c "POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres /usr/local/bin/docker-entrypoint.sh postgres &" postgres \ + # Explorer frontend deps. + && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ + && apt install -y nodejs && npm install -g serve \ # Install Envoy. && curl -fsSL https://apt.envoyproxy.io/signing.key | gpg --dearmor -o /etc/apt/keyrings/envoy-keyring.gpg \ && echo "deb [signed-by=/etc/apt/keyrings/envoy-keyring.gpg] https://apt.envoyproxy.io bookworm main" | tee /etc/apt/sources.list.d/envoy.list \ @@ -38,6 +85,10 @@ ENV ENVOY_CONFIG_FILE=/envoy.yml ENV PARATIME_BINARY=/runtime.elf ENV KEYMANAGER_BINARY="" ENV OASIS_CLI_BINARY=/oasis +ENV OASIS_NEXUS_BINARY=/nexus +ENV OASIS_NEXUS_CONFIG_FILE=/nexus.yml +ENV OASIS_NEXUS_MIGRATIONS=/nexus-migrations +ENV OASIS_EXPLORER_DIR=/explorer ARG VERSION @@ -45,10 +96,14 @@ ARG VERSION COPY --from=oasis-web3-gateway /go/oasis-web3-gateway/oasis-web3-gateway ${OASIS_WEB3_GATEWAY_BINARY} COPY --from=oasis-web3-gateway /go/oasis-web3-gateway/docker/common/oasis-deposit/oasis-deposit ${OASIS_DEPOSIT_BINARY} COPY docker/common/localnet.yml ${OASIS_WEB3_GATEWAY_CONFIG_FILE} +COPY docker/common/nexus.yml ${OASIS_NEXUS_CONFIG_FILE} COPY docker/common/envoy.yml ${ENVOY_CONFIG_FILE} COPY docker/common/start.sh / COPY docker/common/wait-container-ready.sh / COPY tests/tools/* / +COPY --from=oasis-core-dev /nexus ${OASIS_NEXUS_BINARY} +COPY --from=oasis-core-dev /nexus-migrations ${OASIS_NEXUS_MIGRATIONS} +COPY --from=oasis-core-dev /explorer/build ${OASIS_EXPLORER_DIR} # Create symbolic links for convenience. RUN ln -s ${OASIS_NODE_BINARY} ${OASIS_CLI_BINARY} /usr/local/bin @@ -80,11 +135,15 @@ RUN wget --quiet "https://github.com/oasisprotocol/oasis-core/releases/download/ && echo "${VERSION}" > /VERSION \ && strip -S -x ${OASIS_NET_RUNNER_BINARY} ${OASIS_NODE_BINARY} ${OASIS_CLI_BINARY} +# Explorer port. +EXPOSE 80/tcp # Envoy proxy port. EXPOSE 8544/tcp # Web3 gateway http and ws ports. EXPOSE 8545/tcp EXPOSE 8546/tcp +# Nexus port. +EXPOSE 8547/tcp USER root ENTRYPOINT ["/start.sh"] diff --git a/docker/sapphire-localnet/Dockerfile b/docker/sapphire-localnet/Dockerfile index 7026d3c2..b5a33012 100644 --- a/docker/sapphire-localnet/Dockerfile +++ b/docker/sapphire-localnet/Dockerfile @@ -78,10 +78,54 @@ RUN wget https://github.com/oasisprotocol/${PARATIME_NAME}-paratime/releases/dow # && mv /sapphire-paratime-git/runtime/target/release/sapphire-paratime / \ # && rm -rf sapphire-paratime-git +# ARG NEXUS_VERSION=0.4.0 +# RUN wget https://github.com/oasisprotocol/nexus/releases/download/v${NEXUS_VERSION}/oasis_nexus_${NEXUS_VERSION}_linux_amd64.tar.gz \ +# && tar -zxvf oasis_nexus_${NEXUS_VERSION}_linux_amd64.tar.gz \ +# && strip -S -x /oasis_nexus_${NEXUS_VERSION}_linux_amd64/nexus \ +# && mv /oasis_nexus_${NEXUS_VERSION}_linux_amd64/nexus / \ +# && rm -rf /oasis_nexus_${NEXUS_VERSION}_linux_amd64* && \ +# # We also need to fetch the storage migrations. +# git clone https://github.com/oasisprotocol/nexus.git nexus-git --branch v${NEXUS_VERSION} --depth 1 \ +# && mv /nexus-git/storage/migrations /nexus-migrations \ +# && rm -rf nexus-git +ARG NEXUS_VERSION=main +RUN git clone https://github.com/oasisprotocol/nexus.git nexus-git --depth 1 \ + && cd nexus-git \ + && git fetch --depth 1 origin ${NEXUS_VERSION} \ + && git checkout ${NEXUS_VERSION} \ + && go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.12 \ + && make codegen-go \ + && go build \ + && strip -S -x /nexus-git/nexus \ + && mv /nexus-git/nexus / \ + && mv /nexus-git/storage/migrations /nexus-migrations \ + && rm -rf /nexus-git + +# ARG EXPLORER_REPO=https://github.com/oasisprotocol/explorer.git +# ARG EXPLORER_VERSION=v1.13.0 +# TODO: update once some support for localnet is added: https://github.com/oasisprotocol/explorer/issues/1597 +ARG EXPLORER_REPO=https://github.com/ptrus/explorer.git +ARG EXPLORER_VERSION=1a78782e10fa266707a428c5fd8ba91966d588a1 +COPY docker/common/explorer.env /nexus.env.production +RUN git clone ${EXPLORER_REPO} explorer --depth 1 \ + && cd explorer \ + && git fetch origin ${EXPLORER_VERSION} --depth 1 \ + && git checkout FETCH_HEAD \ + && mv /nexus.env.production .env.production \ + && echo "REACT_APP_LOCALNET_SAPPHIRE=true\nREACT_APP_LOCALNET_EMERALD=false" >> .env.production \ + && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ + && apt install -y nodejs \ + && npm install -g yarn \ + && yarn install \ + && NODE_ENV=production yarn build + # Build sapphire-localnet FROM postgres:16-bookworm -RUN apt update && apt install -y bash libseccomp2 unzip jq binutils curl && apt clean \ +RUN apt update && apt install -y bash libseccomp2 unzip jq binutils curl \ && su -c "POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres /usr/local/bin/docker-entrypoint.sh postgres &" postgres \ + # Explorer frontend deps. + && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ + && apt install -y nodejs && npm install -g serve \ # Install Envoy. && curl -fsSL https://apt.envoyproxy.io/signing.key | gpg --dearmor -o /etc/apt/keyrings/envoy-keyring.gpg \ && echo "deb [signed-by=/etc/apt/keyrings/envoy-keyring.gpg] https://apt.envoyproxy.io bookworm main" | tee /etc/apt/sources.list.d/envoy.list \ @@ -91,7 +135,8 @@ RUN apt update && apt install -y bash libseccomp2 unzip jq binutils curl && apt && apt clean \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ && rm -rf /etc/apt/sources.list.d/envoy.list \ - && rm -f /etc/apt/keyrings/envoy-keyring.gpg + && rm -f /etc/apt/keyrings/envoy-keyring.gpg \ + && rm -rf /root/.npm /root/.node-gyp # Docker-specific variables ARG PARATIME_VERSION @@ -113,6 +158,10 @@ ENV OASIS_WEB3_GATEWAY_CONFIG_FILE=/localnet.yml ENV PARATIME_BINARY=/ronl.elf ENV KEYMANAGER_BINARY=/simple-keymanager ENV OASIS_CLI_BINARY=/oasis +ENV OASIS_NEXUS_BINARY=/nexus +ENV OASIS_NEXUS_CONFIG_FILE=/nexus.yml +ENV OASIS_NEXUS_MIGRATIONS=/nexus-migrations +ENV OASIS_EXPLORER_DIR=/explorer ENV OASIS_UNSAFE_SKIP_AVR_VERIFY=1 ENV OASIS_UNSAFE_ALLOW_DEBUG_ENCLAVES=1 ENV OASIS_UNSAFE_MOCK_SGX=1 @@ -127,11 +176,15 @@ COPY --from=oasis-core-dev /oasis-node ${OASIS_NODE_BINARY} COPY --from=oasis-core-dev /oasis-net-runner ${OASIS_NET_RUNNER_BINARY} COPY --from=oasis-core-dev /oasis ${OASIS_CLI_BINARY} COPY --from=oasis-core-dev /sapphire-paratime ${PARATIME_BINARY} +COPY --from=oasis-core-dev /nexus ${OASIS_NEXUS_BINARY} +COPY --from=oasis-core-dev /nexus-migrations ${OASIS_NEXUS_MIGRATIONS} +COPY --from=oasis-core-dev /explorer/build ${OASIS_EXPLORER_DIR} # Create symbolic links for convenience. RUN ln -s ${OASIS_NODE_BINARY} ${OASIS_CLI_BINARY} /usr/local/bin COPY docker/common/localnet.yml ${OASIS_WEB3_GATEWAY_CONFIG_FILE} +COPY docker/common/nexus.yml ${OASIS_NEXUS_CONFIG_FILE} COPY docker/common/envoy.yml ${ENVOY_CONFIG_FILE} COPY docker/common/start.sh / COPY docker/common/wait-container-ready.sh / @@ -152,11 +205,15 @@ RUN echo "Write VERSION information." \ && ${OASIS_CLI_BINARY} --version \ && echo +# Explorer port. +EXPOSE 80/tcp # Envoy proxy port. EXPOSE 8544/tcp # Web3 gateway http and ws ports. EXPOSE 8545/tcp EXPOSE 8546/tcp +# Nexus port. +EXPOSE 8547/tcp USER root ENTRYPOINT ["/start.sh"]