Compare commits

...
Author SHA1 Message Date
telackey d3c26948fc Add eth-api-proxy to mainnet-eth stack. (#514)
* Add eth-api-proxy to mainnet-eth stack.
2023-08-29 16:49:09 -05:00
telackey 7f9b556f9d Update mainnet-eth stack to include auth and metrics. (#492) 2023-08-29 11:32:37 -05:00
Zach 125af19890 add short help text for a deployment (#511) 2023-08-24 08:50:42 -04:00
dboreham 7797185d07 Mainnet laconic setup (#510) 2023-08-23 15:20:28 -06:00
telackey f55a14bd6c Create new base container for pre-compiled webapps. (#507)
* Create new base container for pre-compiled webapps.

* Set the webapp dir appropriately.
2023-08-22 13:32:45 -05:00
dboreham f411590452 Tolerate missing deployment plugin source code files (#508) 2023-08-17 13:49:56 -06:00
dboreham 97dc45549d Update fixturenet eth test (#506) 2023-08-17 13:24:06 -06:00
Zach 8a7622ffa9 bump azimuth version (#502) 2023-08-17 06:37:26 -04:00
dboreham d35bbbab98 Support ChromeOS Debian VM (#503) 2023-08-17 02:02:57 -06:00
dboreham 407571e18d Add debian setup script (#501)
* Adapt install script to Debian

* Update docs for new scipt name

* Add reference to dockerco install doc
2023-08-15 11:49:17 -06:00
nabarun d39e2e959e Add steps in sushiswap-subgraph task to generate events (#500)
* Fix env variable overriding in sushiswap contract deployment containers

* Add steps for generating sushiswap events

* Remove pool swap event
2023-08-14 19:28:38 +05:30
prathamesh0andnabarun ddaddd2a8c Add a sushiswap-subgraph stack (#496)
* Add a sushiswap-graph stack

* Fix shared volume name in fixturenet-lotus

* Export Lotus miner node multiaddr after initialization

* Add deployment scripts for sushiswap contracts

* Skip contracts deployment if already exists

* Rename stack to sushiswap-subgraph

* Fix postgres and use Lotus fixturenet in graph-node stack

* Add sushiswap v3 subgraph stack

* Fixes to deploy sushiswap subgraph to graph-node

* Add graph-node container in sushiswap subgraph stack

---------

Co-authored-by: Nabarun <nabarun@deepstacksoft.com>
2023-08-14 14:17:21 +05:30
prathamesh0 59e0458c74 Restart support for fixturenet-lotus (#499)
* Use ip utility to get the required miner node multiaddr

* Persist lotus node data to support restarts

* Add clean up steps to instructions

* Fix lotus-seed sector-dir arg
2023-08-14 12:46:04 +05:30
89 changed files with 5628 additions and 365 deletions
@@ -0,0 +1,36 @@
name: Fixturenet-Eth-Plugeth-Test
on:
push:
branches: 'ci-test'
# Needed until we can incorporate docker startup into the executor container
env:
DOCKER_HOST: unix:///var/run/dind.sock
jobs:
test:
name: "Run an Ethereum plugeth fixturenet test"
runs-on: ubuntu-latest
steps:
- name: "Clone project repository"
uses: actions/checkout@v3
- name: "Install Python"
uses: cerc-io/setup-python@v4
with:
python-version: '3.8'
- name: "Print Python version"
run: python3 --version
- name: "Install shiv"
run: pip install shiv
- name: "Generate build version file"
run: ./scripts/create_build_tag_file.sh
- name: "Build local shiv package"
run: ./scripts/build_shiv_package.sh
- name: Start dockerd # Also needed until we can incorporate into the executor
run: |
dockerd -H $DOCKER_HOST --userland-proxy=false &
sleep 5
- name: "Run fixturenet-eth tests"
run: ./tests/fixturenet-eth-plugeth/run-test.sh
+10
View File
@@ -4,6 +4,11 @@ on:
push:
branches: 'ci-test'
# Needed until we can incorporate docker startup into the executor container
env:
DOCKER_HOST: unix:///var/run/dind.sock
jobs:
test:
name: "Run an Ethereum fixturenet test"
@@ -23,5 +28,10 @@ jobs:
run: ./scripts/create_build_tag_file.sh
- name: "Build local shiv package"
run: ./scripts/build_shiv_package.sh
- name: Start dockerd # Also needed until we can incorporate into the executor
run: |
dockerd -H $DOCKER_HOST --userland-proxy=false &
sleep 5
- name: "Run fixturenet-eth tests"
run: ./tests/fixturenet-eth/run-test.sh
+1
View File
@@ -37,3 +37,4 @@ jobs:
sleep 5
- name: "Run smoke tests"
run: ./tests/smoke-test/run-smoke-test.sh
+1 -1
View File
@@ -6,7 +6,7 @@ Stack Orchestrator allows building and deployment of a Laconic Stack on a single
## Install
**To get started quickly** on a fresh Ubuntu instance (e.g, Digital Ocean); [try this script](./scripts/quick-install-ubuntu.sh). **WARNING:** always review scripts prior to running them so that you know what is happening on your machine.
**To get started quickly** on a fresh Ubuntu instance (e.g, Digital Ocean); [try this script](./scripts/quick-install-linux.sh). **WARNING:** always review scripts prior to running them so that you know what is happening on your machine.
For any other installation, follow along below and **adapt these instructions based on the specifics of your system.**
+27
View File
@@ -0,0 +1,27 @@
# Copyright © 2023 Cerc
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
from dataclasses import dataclass
@dataclass
class CommandOptions:
stack: str
quiet: bool = False
verbose: bool = False
dry_run: bool = False
local_stack: bool = False
debug: bool = False
continue_on_error: bool = False
@@ -0,0 +1,49 @@
version: '3.2'
services:
# Deploys the core (UniswapV3Factory) contract
sushiswap-v3-core:
image: cerc/sushiswap-v3-core:local
restart: on-failure
env_file:
# Defaults
- ../config/contract-sushiswap/deployment-params.env
environment:
# Overrides
CERC_ETH_RPC_ENDPOINT: ${ETH_RPC_ENDPOINT}
CERC_CHAIN_ID: ${CHAIN_ID}
CERC_ACCOUNT_PRIVATE_KEY: ${ACCOUNT_PRIVATE_KEY}
CERC_DEPLOY: ${DEPLOY}
volumes:
- ../config/network/wait-for-it.sh:/app/wait-for-it.sh
- ../config/contract-sushiswap/deploy-core-contracts.sh:/app/deploy-core-contracts.sh
- sushiswap_core_deployment:/app/deployments/docker
command: ["bash", "-c", "/app/deploy-core-contracts.sh && tail -f"]
extra_hosts:
- "host.docker.internal:host-gateway"
# Deploys the periphery (NFPM, token, etc.) contracts
sushiswap-v3-periphery:
image: cerc/sushiswap-v3-periphery:local
restart: on-failure
env_file:
# Defaults
- ../config/contract-sushiswap/deployment-params.env
environment:
# Overrides
CERC_ETH_RPC_ENDPOINT: ${ETH_RPC_ENDPOINT}
CERC_CHAIN_ID: ${CHAIN_ID}
CERC_ACCOUNT_PRIVATE_KEY: ${ACCOUNT_PRIVATE_KEY}
CERC_DEPLOY: ${DEPLOY}
volumes:
- ../config/network/wait-for-it.sh:/app/wait-for-it.sh
- ../config/contract-sushiswap/deploy-periphery-contracts.sh:/app/deploy-periphery-contracts.sh
- sushiswap_core_deployment:/app/core-deployments/docker
- sushiswap_periphery_deployment:/app/deployments/docker
command: ["bash", "-c", "/app/deploy-periphery-contracts.sh && tail -f"]
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
sushiswap_core_deployment:
sushiswap_periphery_deployment:
@@ -1,6 +1,15 @@
services:
graph-node:
image: cerc/graph-node:local
depends_on:
db:
condition: service_healthy
ipfs:
condition: service_healthy
lotus-node-1:
condition: service_healthy
extra_hosts:
- host.docker.internal:host-gateway
environment:
ipfs: ipfs:5001
postgres_host: db
@@ -8,11 +17,20 @@ services:
postgres_user: graph-node
postgres_pass: password
postgres_db: graph-node
# TODO: Get endpoint from env
ethereum: 'lotus-fixturenet:http://lotus-node-1:1234/rpc/v1'
GRAPH_LOG: info
ports:
- "8000"
- "8001"
- "8020"
- "8030"
healthcheck:
test: ["CMD", "nc", "-vz", "localhost", "8020"]
interval: 30s
timeout: 10s
retries: 10
start_period: 3s
ipfs:
image: ipfs/kubo:master-2023-02-20-714a968
volumes:
@@ -30,6 +48,12 @@ services:
POSTGRES_USER: "graph-node"
POSTGRES_DB: "graph-node"
POSTGRES_PASSWORD: "password"
POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C"
command:
[
"postgres",
"-cshared_preload_libraries=pg_stat_statements"
]
healthcheck:
test: ["CMD", "nc", "-v", "localhost", "5432"]
interval: 30s
@@ -3,6 +3,7 @@ services:
restart: unless-stopped
image: cerc/laconic-console-host:local
environment:
- CERC_WEBAPP_FILES_DIR=${CERC_WEBAPP_FILES_DIR:-/usr/local/share/.config/yarn/global/node_modules/@cerc-io/console-app/dist/production}
- LACONIC_HOSTED_ENDPOINT=${LACONIC_HOSTED_ENDPOINT:-http://localhost}
ports:
- "80"
@@ -10,7 +10,8 @@ services:
- ../config/fixturenet-lotus/setup-miner.sh:/docker-entrypoint-scripts.d/setup-miner.sh
- ../config/fixturenet-lotus/fund-account.sh:/fund-account.sh
- lotus_miner_params:/var/tmp/filecoin-proof-parameters
- lotus-shared:/root/.lotus-shared
- lotus_shared:/root/.lotus-shared
- lotus_miner_data:/root/data
entrypoint: ["sh", "/docker-entrypoint-scripts.d/setup-miner.sh"]
ports:
- "1234"
@@ -29,12 +30,13 @@ services:
volumes:
- ../config/fixturenet-lotus/setup-node.sh:/docker-entrypoint-scripts.d/setup-node.sh
- lotus_node_1_params:/var/tmp/filecoin-proof-parameters
- lotus-shared:/root/.lotus-shared
- lotus_shared:/root/.lotus-shared
- lotus_node_1_data:/root/data
healthcheck:
test: ["CMD", "nc", "-vz", "localhost", "1234"]
interval: 30s
timeout: 10s
retries: 10
retries: 60
start_period: 3s
depends_on:
- lotus-miner
@@ -56,12 +58,13 @@ services:
volumes:
- ../config/fixturenet-lotus/setup-node.sh:/docker-entrypoint-scripts.d/setup-node.sh
- lotus_node_2_params:/var/tmp/filecoin-proof-parameters
- lotus-shared:/root/.lotus-shared
- lotus_shared:/root/.lotus-shared
- lotus_node_2_data:/root/data
healthcheck:
test: ["CMD", "nc", "-vz", "localhost", "1234"]
interval: 30s
timeout: 10s
retries: 10
retries: 60
start_period: 3s
depends_on:
- lotus-miner
@@ -76,4 +79,7 @@ volumes:
lotus_miner_params:
lotus_node_1_params:
lotus_node_2_params:
lotus-shared:
lotus_shared:
lotus_miner_data:
lotus_node_1_data:
lotus_node_2_data:
@@ -0,0 +1,15 @@
version: '3.8'
services:
redis:
hostname: mainnet-eth-api-proxy-redis
image: redis:7-alpine
command: redis-server --save "" --appendonly no --maxmemory-policy allkeys-lru --maxmemory 1G
eth-api-proxy:
hostname: mainnet-eth-api-proxy
image: cerc/eth-api-proxy:local
env_file:
- ../config/mainnet-eth-api-proxy/ethpxy.env
ports:
- 8547
@@ -0,0 +1,51 @@
version: '3.8'
services:
keycloak-db:
image: postgres:14-alpine
env_file:
- ../config/mainnet-eth-keycloak/keycloak.env
healthcheck:
test: ["CMD", "nc", "-v", "localhost", "5432"]
interval: 30s
timeout: 10s
retries: 10
start_period: 3s
volumes:
- mainnet_eth_keycloak_db:/var/lib/postgresql/data
ports:
- 5432
keycloak:
image: cerc/keycloak:local
env_file:
- ../config/mainnet-eth-keycloak/keycloak.env
environment:
JAVA_OPTS_APPEND: "-Dkeycloak.migration.action=import -Dkeycloak.migration.provider=dir -Dkeycloak.migration.dir=/import -Dkeycloak.migration.strategy=IGNORE_EXISTING"
volumes:
- ../config/mainnet-eth-keycloak/import:/import
ports:
- 8080
command: ["start"]
depends_on:
keycloak-db:
condition: service_healthy
keycloak-reg-ui:
image: cerc/keycloak-reg-ui:local
env_file:
- ../config/mainnet-eth-keycloak/keycloak.env
volumes:
- ../config/mainnet-eth-keycloak/ui:/config
ports:
- 80
keycloak-reg-api:
image: cerc/keycloak-reg-api:local
env_file:
- ../config/mainnet-eth-keycloak/keycloak.env
ports:
- 9292
volumes:
mainnet_eth_keycloak_db:
@@ -0,0 +1,25 @@
version: "3.2"
services:
prometheus:
restart: always
image: prom/prometheus
depends_on:
mainnet-eth-geth-1:
condition: service_healthy
env_file:
- ../config/mainnet-eth-metrics/metrics.env
volumes:
- ../config/mainnet-eth-metrics/prometheus/etc:/etc/prometheus
ports:
- "9090"
grafana:
restart: always
image: grafana/grafana
env_file:
- ../config/mainnet-eth-metrics/metrics.env
volumes:
- ../config/mainnet-eth-metrics/grafana/etc/provisioning/dashboards:/etc/grafana/provisioning/dashboards
- ../config/mainnet-eth-metrics/grafana/etc/provisioning/datasources:/etc/grafana/provisioning/datasources
- ../config/mainnet-eth-metrics/grafana/etc/dashboards:/etc/grafana/dashboards
ports:
- "3000"
+25 -10
View File
@@ -6,16 +6,13 @@ services:
hostname: mainnet-eth-geth-1
cap_add:
- SYS_PTRACE
environment:
CERC_REMOTE_DEBUG: "true"
CERC_RUN_STATEDIFF: ${CERC_RUN_STATEDIFF:-detect}
CERC_STATEDIFF_DB_NODE_ID: 1
CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG}
image: cerc/go-ethereum:local
entrypoint: /bin/sh
command: -c "/opt/run-geth.sh"
env_file:
- ../config/mainnet-eth/geth.env
volumes:
- mainnet_eth_geth_1_data:/root/ethdata
- mainnet_eth_geth_1_data:/data
- mainnet_eth_config_data:/etc/mainnet-eth
- ../config/mainnet-eth/scripts/run-geth.sh:/opt/run-geth.sh
healthcheck:
@@ -25,30 +22,48 @@ services:
retries: 10
start_period: 3s
ports:
# http api
- "8545"
# ws api
- "8546"
# ws el
- "8551"
# p2p
- "30303"
- "30303/udp"
# debugging
- "40000"
# metrics
- "6060"
mainnet-eth-lighthouse-1:
restart: always
hostname: mainnet-eth-lighthouse-1
healthcheck:
test: ["CMD", "wget", "--tries=1", "--connect-timeout=1", "--quiet", "-O", "-", "http://localhost:8001/eth/v2/beacon/blocks/head"]
test: ["CMD", "wget", "--tries=1", "--connect-timeout=1", "--quiet", "-O", "-", "http://localhost:5052/eth/v2/beacon/blocks/head"]
interval: 30s
timeout: 10s
retries: 10
start_period: 30s
environment:
EXECUTION_ENDPOINT: "http://mainnet-eth-geth-1:8551"
LIGHTHOUSE_EXECUTION_ENDPOINT: "http://mainnet-eth-geth-1:8551"
env_file:
- ../config/mainnet-eth/lighthouse.env
image: cerc/lighthouse:local
entrypoint: /bin/sh
command: -c "/opt/run-lighthouse.sh"
volumes:
- mainnet_eth_lighthouse_1_data:/var/lighthouse-data-dir
- mainnet_eth_lighthouse_1_data:/data
- mainnet_eth_config_data:/etc/mainnet-eth
- ../config/mainnet-eth/scripts/run-lighthouse.sh:/opt/run-lighthouse.sh
ports:
- "8001"
# api
- "5052"
# metrics
- "5054"
# p2p
- "9000"
- "9000/udp"
volumes:
mainnet_eth_config_data:
@@ -2,14 +2,16 @@ services:
laconicd:
restart: no
image: cerc/laconicd:local
command: ["/bin/sh", "-c", "while :; do sleep 600; done"]
command: ["/bin/sh", "-c", "/opt/run-laconicd.sh"]
volumes:
# The cosmos-sdk node's database directory:
- laconicd-data:/root/.laconicd/data
- laconicd-config:/root/.laconicd/config
- laconicd-keyring:/root/.laconicd/keyring-test
# TODO: look at folding these scripts into the container
- ../config/mainnet-laconicd/create-fixturenet.sh:/docker-entrypoint-scripts.d/create-fixturenet.sh
- ../config/mainnet-laconicd/export-mykey.sh:/docker-entrypoint-scripts.d/export-mykey.sh
- ../config/mainnet-laconicd/export-myaddress.sh:/docker-entrypoint-scripts.d/export-myaddress.sh
- ../config/mainnet-laconicd/scripts/run-laconicd.sh:/opt/run-laconicd.sh
- ../config/mainnet-laconicd/scripts/export-mykey.sh:/docker-entrypoint-scripts.d/export-mykey.sh
- ../config/mainnet-laconicd/scripts/export-myaddress.sh:/docker-entrypoint-scripts.d/export-myaddress.sh
# TODO: determine which of the ports below is really needed
ports:
- "6060"
@@ -28,3 +30,5 @@ services:
volumes:
laconicd-data:
laconicd-config:
laconicd-keyring:
@@ -0,0 +1,26 @@
version: '3.2'
services:
# Deploys the sushiswap v3 subgraph
sushiswap-subgraph-v3:
image: cerc/sushiswap-subgraphs:local
restart: on-failure
depends_on:
graph-node:
condition: service_healthy
environment:
- APP=v3
- NETWORK=lotus-fixturenet
command: ["bash", "-c", "./run-v3.sh"]
working_dir: /app/subgraphs/v3
volumes:
- ../config/sushiswap-subgraph-v3/lotus-fixturenet.js.template:/app/config/lotus-fixturenet.js.template
- ../config/sushiswap-subgraph-v3/run-v3.sh:/app/subgraphs/v3/run-v3.sh
- sushiswap_core_deployment:/app/subgraphs/v3/core-deployments/docker
- sushiswap_periphery_deployment:/app/subgraphs/v3/deployments/docker
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
sushiswap_core_deployment:
sushiswap_periphery_deployment:
@@ -0,0 +1,34 @@
#!/bin/bash
set -e
# Chain config
export ETH_RPC_ENDPOINT="${CERC_ETH_RPC_ENDPOINT:-${CERC_DEFAULT_ETH_RPC_ENDPOINT}}"
export CHAIN_ID="${CERC_CHAIN_ID:-${CERC_DEFAULT_CHAIN_ID}}"
export ACCOUNT_PRIVATE_KEY="${CERC_ACCOUNT_PRIVATE_KEY:-${CERC_DEFAULT_ACCOUNT_PRIVATE_KEY}}"
# Option
DEPLOY="${CERC_DEPLOY:-${CERC_DEFAULT_DEPLOY}}"
# Create a .env file
echo "ETH_RPC_ENDPOINT=$ETH_RPC_ENDPOINT" > .env
echo "CHAIN_ID=$CHAIN_ID" >> .env
echo "ACCOUNT_PRIVATE_KEY=$ACCOUNT_PRIVATE_KEY" >> .env
echo "Using RPC endpoint ${ETH_RPC_ENDPOINT}"
# Wait for the RPC endpoint to be up
endpoint=${ETH_RPC_ENDPOINT#http://}
endpoint=${endpoint#https://}
RPC_HOST=$(echo "$endpoint" | awk -F'[:/]' '{print $1}')
RPC_PORT=$(echo "$endpoint" | awk -F'[:/]' '{print $2}')
./wait-for-it.sh -h "${RPC_HOST}" -p "${RPC_PORT}" -s -t 0
if [ "$DEPLOY" = true ] && [ ! -e "/app/deployments/docker/UniswapV3Factory.json" ]; then
echo "Performing core contract deployments..."
pnpm hardhat --network docker deploy --tags UniswapV3Factory
else
echo "Skipping contract deployments"
fi
echo "Done"
@@ -0,0 +1,46 @@
#!/bin/bash
set -e
# Chain config
ETH_RPC_ENDPOINT="${CERC_ETH_RPC_ENDPOINT:-${CERC_DEFAULT_ETH_RPC_ENDPOINT}}"
CHAIN_ID="${CERC_CHAIN_ID:-${CERC_DEFAULT_CHAIN_ID}}"
ACCOUNT_PRIVATE_KEY="${CERC_ACCOUNT_PRIVATE_KEY:-${CERC_DEFAULT_ACCOUNT_PRIVATE_KEY}}"
# Option
DEPLOY="${CERC_DEPLOY:-${CERC_DEFAULT_DEPLOY}}"
# Create a .env file
echo "ETH_RPC_ENDPOINT=$ETH_RPC_ENDPOINT" > .env
echo "CHAIN_ID=$CHAIN_ID" >> .env
echo "ACCOUNT_PRIVATE_KEY=$ACCOUNT_PRIVATE_KEY" >> .env
echo "Using RPC endpoint $ETH_RPC_ENDPOINT"
# Wait for the RPC endpoint to be up
endpoint=${ETH_RPC_ENDPOINT#http://}
endpoint=${endpoint#https://}
RPC_HOST=$(echo "$endpoint" | awk -F'[:/]' '{print $1}')
RPC_PORT=$(echo "$endpoint" | awk -F'[:/]' '{print $2}')
./wait-for-it.sh -h "${RPC_HOST}" -p "${RPC_PORT}" -s -t 0
if [ "$DEPLOY" = true ] && [ ! -e "/app/deployments/docker/NonfungiblePositionManager.json" ]; then
# Loop until the factory deployment is detected
echo "Waiting for core deployments to occur"
while [ ! -f /app/core-deployments/docker/UniswapV3Factory.json ]; do
sleep 5
done
echo "Reading factory address from core deployments"
FACTORY_ADDRESS=$(jq -r '.address' /app/core-deployments/docker/UniswapV3Factory.json)
echo "Using UniswapV3Factory at $FACTORY_ADDRESS"
echo "FACTORY_ADDRESS=$FACTORY_ADDRESS" >> .env
echo "Performing periphery contract deployments..."
yarn hardhat --network docker deploy --tags NonfungiblePositionManager
else
echo "Skipping contract deployments"
fi
echo "Done"
@@ -0,0 +1,11 @@
# Chain config
CERC_DEFAULT_ETH_RPC_ENDPOINT="http://lotus-node-1:1234/rpc/v1"
CERC_DEFAULT_CHAIN_ID=31415926
# From app/data/config/fixturenet-lotus/fund-account.sh
CERC_DEFAULT_ACCOUNT_PRIVATE_KEY="0xc05fd3613bcd62a4f25e5eba1f464d0b76d74c3f771a7c2f13e26ad6439444b3"
# Options
CERC_DEFAULT_DEPLOY=true
@@ -1,5 +1,5 @@
LOTUS_PATH=/root/.lotus-local-net
LOTUS_MINER_PATH=/root/.lotus-miner-local-net
LOTUS_PATH=/root/data/.lotus-local-net
LOTUS_MINER_PATH=/root/data/.lotus-miner-local-net
LOTUS_SKIP_GENESIS_CHECK=_yes_
LOTUS_FEVM_ENABLEETHRPC=true
CGO_CFLAGS_ALLOW="-D__BLST_PORTABLE__"
+13 -10
View File
@@ -15,12 +15,16 @@ else
echo "Existing proof params found"
fi
lotus-seed pre-seal --sector-size 2KiB --num-sectors 2
lotus-seed genesis new localnet.json
lotus-seed genesis add-miner localnet.json ~/.genesis-sectors/pre-seal-t01000.json
# if genesis is not already setup
if [ ! -f /root/data/localnet.json ]; then
lotus-seed --sector-dir /root/data/.genesis-sectors pre-seal --sector-size 2KiB --num-sectors 2
lotus-seed --sector-dir /root/data/.genesis-sectors genesis new /root/data/localnet.json
lotus-seed --sector-dir /root/data/.genesis-sectors genesis add-miner /root/data/localnet.json /root/data/.genesis-sectors/pre-seal-t01000.json
fi
# start daemon
nohup lotus daemon --lotus-make-genesis=devgen.car --profile=bootstrapper --genesis-template=localnet.json --bootstrap=false > /var/log/lotus.log 2>&1 &
# /root/.lotus-shared/devgen.car path
nohup lotus daemon --lotus-make-genesis=/root/.lotus-shared/devgen.car --profile=bootstrapper --genesis-template=/root/data/localnet.json --bootstrap=false > /var/log/lotus.log 2>&1 &
# Loop until the daemon is started
echo "Waiting for daemon to start..."
@@ -32,21 +36,20 @@ echo "Daemon started."
# copy genesis file to shared volume
cp /devgen.car /root/.lotus-shared
# publish bootnode peer info to shared volume
# TODO: Improve exporting public address to shared volume
lotus net listen | awk 'NR==4{print}' > /root/.lotus-shared/miner.addr
# if miner not already initialized
if [ ! -d $LOTUS_MINER_PATH ]; then
# initialize miner
lotus wallet import --as-default ~/.genesis-sectors/pre-seal-t01000.key
lotus wallet import --as-default /root/data/.genesis-sectors/pre-seal-t01000.key
# fund a known account for usage
/fund-account.sh
lotus-miner init --genesis-miner --actor=t01000 --sector-size=2KiB --pre-sealed-sectors=~/.genesis-sectors --pre-sealed-metadata=~/.genesis-sectors/pre-seal-t01000.json --nosync
lotus-miner init --genesis-miner --actor=t01000 --sector-size=2KiB --pre-sealed-sectors=/root/data/.genesis-sectors --pre-sealed-metadata=/root/data/.genesis-sectors/pre-seal-t01000.json --nosync
fi
# publish bootnode peer info to shared volume
lotus net listen | grep "$(ip addr | grep inet | grep -v '127.0.0.1' | sort | head -1 | awk '{print $2}' | cut -d '/' -f1)" | head -1 > /root/.lotus-shared/miner.addr
# start miner
nohup lotus-miner run --nosync &
+10 -13
View File
@@ -9,20 +9,17 @@ while [ ! -f /root/.lotus-shared/miner.addr ]; do
done
echo "Resuming..."
# if not already initialized
if [ ! -f $LOTUS_PATH/config.toml ]; then
# init node config
mkdir $LOTUS_PATH
lotus config default > $LOTUS_PATH/config.toml
# init node config
mkdir -p $LOTUS_PATH
lotus config default > $LOTUS_PATH/config.toml
# add bootstrap peer info if available
if [ -f /root/.lotus-shared/miner.addr ]; then
MINER_ADDR=\"$(cat /root/.lotus-shared/miner.addr)\"
# add bootstrap peer id to config file
sed -i "/^\[Libp2p\]/a \ \ BootstrapPeers = [$MINER_ADDR]" $LOTUS_PATH/config.toml
else
echo "Bootstrap peer info not found, unable to configure. Manual peering will be required."
fi
# add bootstrap peer info if available
if [ -f /root/.lotus-shared/miner.addr ]; then
MINER_ADDR=\"$(cat /root/.lotus-shared/miner.addr)\"
# add bootstrap peer id to config file
sed -i "/^\[Libp2p\]/a \ \ BootstrapPeers = [$MINER_ADDR]" $LOTUS_PATH/config.toml
else
echo "Bootstrap peer info not found, unable to configure. Manual peering will be required."
fi
# start node
@@ -0,0 +1,6 @@
CERC_ETHPXY_LISTEN_PORT=8547
CERC_ETHPXY_LISTEN_ADDR='0.0.0.0'
CERC_ETHPXY_REDIS_URL='redis://mainnet-eth-api-proxy-redis:6379'
CERC_ETHPXY_REDIS_MAX_AGE=120000
CERC_ETHPXY_GETH_WS_URL='ws://mainnet-eth-geth-1:8546'
CERC_ETHPXY_GETH_HTTP_URL='http://mainnet-eth-geth-1:8545'
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,29 @@
POSTGRES_DB=keycloak
POSTGRES_USER=keycloak
POSTGRES_PASSWORD=keycloak
KC_DB=postgres
KC_DB_URL_HOST=keycloak-db
KC_DB_URL_DATABASE=${POSTGRES_DB}
KC_DB_USERNAME=${POSTGRES_USER}
KC_DB_PASSWORD=${POSTGRES_PASSWORD}
KC_DB_SCHEMA=public
KC_HOSTNAME=localhost
KC_HTTP_ENABLED="true"
KC_HTTP_RELATIVE_PATH="/auth"
KC_HOSTNAME_STRICT_HTTPS="false"
KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=admin
X_API_CHECK_REALM=cerc
X_API_CHECK_CLIENT_ID="%user_id%"
# keycloak-reg-api
CERC_KCUSERREG_LISTEN_PORT=9292
CERC_KCUSERREG_LISTEN_ADDR='0.0.0.0'
CERC_KCUSERREG_API_URL='http://keycloak:8080/auth'
CERC_KCUSERREG_REG_USER="${KEYCLOAK_ADMIN}"
CERC_KCUSERREG_REG_PW="${KEYCLOAK_ADMIN_PASSWORD}"
CERC_KCUSERREG_REG_CLIENT_ID='admin-cli'
CERC_KCUSERREG_TARGET_REALM=cerc
CERC_KCUSERREG_TARGET_GROUPS=eth
CERC_KCUSERREG_CREATE_ENABLED=true
@@ -0,0 +1,107 @@
server {
listen 80;
server_name my.example.com;
# See: https://github.com/acmesh-official/acme.sh/wiki/Stateless-Mode
# and https://datatracker.ietf.org/doc/html/rfc8555
location ~ ^/\.well-known/acme-challenge/([-_a-zA-Z0-9]+)$ {
default_type text/plain;
return 200 "$1.MY_ACCOUNT_THUMBPRINT_GOES_HERE";
}
location / {
return 301 https://$host$request_uri;
}
}
upstream geth-pool {
keepalive 100;
hash $user_id consistent;
server server-a:8545;
server server-b:8545;
server server-c:8545;
}
# self-reg happens on one server for clarity
upstream reg-ui-pool {
keepalive 100;
server server-a:8085;
}
upstream reg-api-pool {
keepalive 100;
server server-a:8086;
}
# auth uses server-a if available
upstream auth-pool {
keepalive 100;
server server-a:8080;
server server-b:8080 backup;
server server-c:8080 backup;
}
log_format upstreamlog '[$time_local] $remote_addr $user_id - $server_name $host to: $upstream_addr: $request $status upstream_response_time $upstream_response_time msec $msec request_time $request_time';
proxy_cache_path /var/cache/nginx/auth_cache levels=1 keys_zone=auth_cache:1m max_size=5m inactive=60m;
server {
listen 443 ssl http2;
server_name my.example.com;
access_log /var/log/nginx/my.example.com-access.log upstreamlog;
error_log /var/log/nginx/my.example.com-error.log;
ssl_certificate /etc/nginx/ssl/my.example.com/cert.pem;
ssl_certificate_key /etc/nginx/ssl/my.example.com/key.pem;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
#rewrite ^/?$ /newuser/;
rewrite ^/?$ https://www.example.com/;
# geth-pool ETH API
location ~ ^/v1/eth/?([^/]*)$ {
set $apiKey $1;
if ($apiKey = '') {
set $apiKey $http_X_API_KEY;
}
auth_request /auth;
auth_request_set $user_id $sent_http_x_user_id;
rewrite /.*$ / break;
client_max_body_size 3m;
client_body_buffer_size 3m;
proxy_buffer_size 32k;
proxy_buffers 16 32k;
proxy_busy_buffers_size 96k;
proxy_pass http://geth-pool;
proxy_set_header X-Original-Remote-Addr $remote_addr;
proxy_set_header X-User-Id $user_id;
}
# keycloak
location = /auth {
internal;
proxy_cache auth_cache;
proxy_cache_key "$apiKey";
proxy_cache_valid 200 300s;
proxy_cache_valid 401 30s;
proxy_pass http://auth-pool/auth/realms/cerc/check?memberOf=eth&apiKey=$apiKey;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Original-Remote-Addr $remote_addr;
proxy_set_header X-Original-Host $host;
}
location /newuser/ {
proxy_pass http://reg-ui-pool/;
}
location /user-api/ {
proxy_pass http://reg-api-pool/;
}
}
@@ -0,0 +1,138 @@
#!/usr/bin/env python3
import argparse
import os
import sys
import psycopg
import random
from subprocess import Popen
from fabric import Connection
def dump_src_db_to_file(db_host, db_port, db_user, db_password, db_name, file_name):
command = f"pg_dump -h {db_host} -p {db_port} -U {db_user} -d {db_name} -c --inserts -f {file_name}"
my_env = os.environ.copy()
my_env["PGPASSWORD"] = db_password
print(f"Exporting from {db_host}:{db_port}/{db_name} to {file_name}... ", end="")
ret = Popen(command, shell=True, env=my_env).wait()
print("DONE")
return ret
def establish_ssh_tunnel(ssh_host, ssh_port, ssh_user, db_host, db_port):
local_port = random.randint(11000, 12000)
conn = Connection(host=ssh_host, port=ssh_port, user=ssh_user)
fw = conn.forward_local(
local_port=local_port, remote_port=db_port, remote_host=db_host
)
return conn, fw, local_port
def load_db_from_file(db_host, db_port, db_user, db_password, db_name, file_name):
connstr = "host=%s port=%s user=%s password=%s sslmode=disable dbname=%s" % (
db_host,
db_port,
db_user,
db_password,
db_name,
)
with psycopg.connect(connstr) as conn:
with conn.cursor() as cur:
print(
f"Importing from {file_name} to {db_host}:{db_port}/{db_name}... ",
end="",
)
cur.execute(open(file_name, "rt").read())
print("DONE")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--src-dbhost", help="DB hostname", default="localhost")
parser.add_argument("--src-dbport", help="DB port", default=5432, type=int)
parser.add_argument("--src-dbuser", help="DB username", default="keycloak")
parser.add_argument("--src-dbpw", help="DB password", required=True)
parser.add_argument("--src-dbname", help="dbname", default="keycloak")
parser.add_argument(
"--dst-file", help="Destination filename", default="keycloak-mirror.sql"
)
parser.add_argument("--live-import", help="run the import", action="store_true")
parser.add_argument("--dst-dbhost", help="DB hostname", default="localhost")
parser.add_argument("--dst-dbport", help="DB port", default=5432, type=int)
parser.add_argument("--dst-dbuser", help="DB username", default="keycloak")
parser.add_argument("--dst-dbpw", help="DB password")
parser.add_argument("--dst-dbname", help="dbname", default="keycloak")
parser.add_argument("--ssh-host", help="SSH hostname")
parser.add_argument("--ssh-port", help="SSH port", default=22, type=int)
parser.add_argument("--ssh-user", help="SSH user")
args = parser.parse_args()
if args.live_import and not args.dst_dbpw:
print("--dst-dbpw is required if importing", file=sys.stderr)
sys.exit(2)
remove_sql_file = False
if args.dst_dbhost and not args.dst_file:
remove_sql_file = True
dst_file = args.dst_file
if not dst_file:
dst_file = "keycloak-mirror.sql"
dump_src_db_to_file(
args.src_dbhost,
args.src_dbport,
args.src_dbuser,
args.src_dbpw,
args.src_dbname,
dst_file,
)
if args.live_import:
try:
if args.ssh_host:
dst_dbport = random.randint(11000, 12000)
print(
f"Establishing SSH tunnel from 127.0.0.1:{dst_dbport} to {args.ssh_host}->{args.dst_dbhost}:{args.dst_dbport}... ",
end="",
)
with Connection(
host=args.ssh_host, port=args.ssh_port, user=args.ssh_user
).forward_local(
local_port=dst_dbport,
remote_port=args.dst_dbport,
remote_host=args.dst_dbhost,
):
print("DONE")
load_db_from_file(
args.dst_dbhost,
args.dst_dbport,
args.dst_dbuser,
args.dst_dbpw,
args.dst_dbname,
dst_file,
)
else:
load_db_from_file(
args.dst_dbhost,
args.dst_dbport,
args.dst_dbuser,
args.dst_dbpw,
args.dst_dbname,
dst_file,
)
finally:
if args.live_import:
print(f"Removing {dst_file}... ", end="")
os.remove(dst_file)
print("DONE")
@@ -0,0 +1,3 @@
fabric
psycopg~=3.1.8
psycopg_binary
@@ -0,0 +1,4 @@
web:
path: ''
api:
url: 'http://keycloak-reg-api:9292'
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,9 @@
apiVersion: 1
providers:
- name: dashboards
type: file
updateIntervalSeconds: 10
options:
path: /etc/grafana/dashboards
foldersFromFilesStructure: true
@@ -0,0 +1,19 @@
apiVersion: 1
datasources:
- id: 1
uid: jZUuGao4k
orgId: 1
name: Prometheus
type: prometheus
typeName: Prometheus
typeLogoUrl: public/app/plugins/datasource/prometheus/img/prometheus_logo.svg
access: proxy
url: http://prometheus:9090
user: ""
database: ""
basicAuth: false
isDefault: true
jsonData:
httpMethod: POST
readOnly: false
@@ -0,0 +1,2 @@
# grafana
GF_SECURITY_ADMIN_PASSWORD=changeme6325
@@ -0,0 +1,19 @@
global:
scrape_interval: 5s
evaluation_interval: 15s
scrape_configs:
# geth
- job_name: 'geth'
metrics_path: /debug/metrics/prometheus
scheme: http
static_configs:
- targets: ['mainnet-eth-geth-1:6060']
# keycloak
- job_name: 'keycloak'
scrape_interval: 5s
metrics_path: /auth/realms/cerc/metrics
scheme: http
static_configs:
- targets: ['keycloak:8080']
+57
View File
@@ -0,0 +1,57 @@
# Enable remote debugging using dlv
CERC_REMOTE_DEBUG=false
# Enable startup script debug output.
CERC_SCRIPT_DEBUG=false
# Simple toggle to choose either a 'full' node or an 'archive' node
# (controls the values of --syncmode --gcmode --snapshot)
CERC_GETH_MODE_QUICK_SET=full
# Optional custom node name.
# GETH_NODE_NAME=""
# Specify any other geth CLI options.
GETH_OPTS=""
# --cache
GETH_CACHE=1024
# --cache.database
GETH_CACHE_DB=50
# --cache.gc
GETH_CACHE_GC=25
# --cache.trie
GETH_CACHE_TRIE=15
j
# --datadir
GETH_DATADIR="/data"
# --http.api
GETH_HTTP_API="eth,web3,net"
# --authrpc.jwtsecret
GETH_JWTSECRET="/etc/mainnet-eth/jwtsecret"
# --maxpeers
GETH_MAX_PEERS=100
# --rpc.evmtimeout
GETH_RPC_EVMTIMEOUT=0
# --rpc.gascap
GETH_RPC_GASCAP=0
# --txlookuplimit
GETH_TXLOOKUPLIMIT=0
# --verbosity
GETH_VERBOSITY=3
# --log.vmodule
GETH_VMODULE="rpc/*=4"
# --ws.api
GETH_WS_API="eth,web3,net"
@@ -0,0 +1,33 @@
# Enable startup script debug output.
CERC_SCRIPT_DEBUG=false
# Specify any other lighthouse CLI options.
LIGHTHOUSE_OPTS=""
# Override the advertised public IP (optional)
# --enr-address
#LIGHTHOUSE_ENR_ADDRESS=""
# --checkpoint-sync-url
LIGHTHOUSE_CHECKPOINT_SYNC_URL="https://beaconstate.ethstaker.cc"
# --checkpoint-sync-url-timeout
LIGHTHOUSE_CHECKPOINT_SYNC_URL_TIMEOUT=300
# --datadir
LIGHTHOUSE_DATADIR=/data
# --debug-level
LIGHTHOUSE_DEBUG_LEVEL=info
# --http-port
LIGHTHOUSE_HTTP_PORT=5052
# --execution-jwt
LIGHTHOUSE_JWTSECRET=/etc/mainnet-eth/jwtsecret
# --metrics-port
LIGHTHOUSE_METRICS_PORT=5054
# --port --enr-udp-port --enr-tcp-port
LIGHTHOUSE_NETWORK_PORT=9000
+35 -22
View File
@@ -1,12 +1,10 @@
#!/bin/sh
if [[ -n "$CERC_SCRIPT_DEBUG" ]]; then
if [[ "true" == "$CERC_SCRIPT_DEBUG" ]]; then
set -x
fi
CERC_ETH_DATADIR=/root/ethdata
START_CMD="geth"
if [ "true" == "$CERC_REMOTE_DEBUG" ] && [ -x "/usr/local/bin/dlv" ]; then
if [[ "true" == "$CERC_REMOTE_DEBUG" ]] && [[ -x "/usr/local/bin/dlv" ]]; then
START_CMD="/usr/local/bin/dlv --listen=:40000 --headless=true --api-version=2 --accept-multiclient exec /usr/local/bin/geth --continue --"
fi
@@ -22,29 +20,44 @@ cleanup() {
wait
echo "Done"
}
trap 'cleanup' SIGINT SIGTERM
MODE_FLAGS=""
if [[ "$CERC_GETH_MODE_QUICK_SET" = "archive" ]]; then
MODE_FLAGS="--syncmode=${GETH_SYNC_MODE:-full} --gcmode=${GETH_GC_MODE:-archive} --snapshot=${GETH_SNAPSHOT:-false}"
else
MODE_FLAGS="--syncmode=${GETH_SYNC_MODE:-snap} --gcmode=${GETH_GC_MODE:-full} --snapshot=${GETH_SNAPSHOT:-true}"
fi
$START_CMD \
--datadir="${CERC_ETH_DATADIR}" \
--authrpc.addr="0.0.0.0" \
--authrpc.port 8551 \
--authrpc.vhosts="*" \
--authrpc.jwtsecret="/etc/mainnet-eth/jwtsecret" \
--ws \
--ws.addr="0.0.0.0" \
--ws.origins="*" \
--ws.api="${CERC_GETH_WS_APIS:-eth,web3,net,admin,personal,debug,statediff}" \
--http.corsdomain="*" \
--gcmode full \
--txlookuplimit=0 \
--cache.preimages \
--syncmode=snap \
&
$MODE_FLAGS \
--datadir="${GETH_DATADIR}"\
--identity="${GETH_NODE_NAME}" \
--maxpeers=${GETH_MAX_PEERS} \
--cache=${GETH_CACHE} \
--cache.gc=${GETH_CACHE_GC} \
--cache.database=${GETH_CACHE_DB} \
--cache.trie=${GETH_CACHE_TRIE} \
--authrpc.addr='0.0.0.0' \
--authrpc.vhosts='*' \
--authrpc.jwtsecret="${GETH_JWTSECRET}" \
--http \
--http.addr='0.0.0.0' \
--http.api="${GETH_HTTP_API}" \
--http.vhosts='*' \
--metrics \
--metrics.addr='0.0.0.0' \
--ws \
--ws.addr='0.0.0.0' \
--ws.api="${GETH_WS_API}" \
--rpc.gascap=${GETH_RPC_GASCAP} \
--rpc.evmtimeout=${GETH_RPC_EVMTIMEOUT} \
--txlookuplimit=${GETH_TXLOOKUPLIMIT} \
--verbosity=${GETH_VERBOSITY} \
--log.vmodule="${GETH_VMODULE}" \
${GETH_OPTS} &
geth_pid=$!
wait $geth_pid
if [ "true" == "$CERC_KEEP_RUNNING_AFTER_GETH_EXIT" ]; then
@@ -1,22 +1,30 @@
#!/bin/bash
if [[ -n "$CERC_SCRIPT_DEBUG" ]]; then
if [[ "true" == "$CERC_SCRIPT_DEBUG" ]]; then
set -x
fi
DEBUG_LEVEL=${CERC_LIGHTHOUSE_DEBUG_LEVEL:-info}
ENR_OPTS=""
if [[ -n "$LIGHTHOUSE_ENR_ADDRESS" ]]; then
ENR_OPTS="--enr-address $LIGHTHOUSE_ENR_ADDRESS"
fi
data_dir=/var/lighthouse-data-dir
network_port=9001
http_port=8001
authrpc_port=8551
exec lighthouse \
bn \
--debug-level $DEBUG_LEVEL \
--datadir $data_dir \
--network mainnet \
--execution-endpoint $EXECUTION_ENDPOINT \
--execution-jwt /etc/mainnet-eth/jwtsecret \
exec lighthouse bn \
--checkpoint-sync-url "$LIGHTHOUSE_CHECKPOINT_SYNC_URL" \
--checkpoint-sync-url-timeout ${LIGHTHOUSE_CHECKPOINT_SYNC_URL_TIMEOUT} \
--datadir "$LIGHTHOUSE_DATADIR" \
--debug-level $LIGHTHOUSE_DEBUG_LEVEL \
--disable-deposit-contract-sync \
--checkpoint-sync-url https://beaconstate.ethstaker.cc
--disable-upnp \
--enr-tcp-port $LIGHTHOUSE_NETWORK_PORT \
--enr-udp-port $LIGHTHOUSE_NETWORK_PORT \
--execution-endpoint "$LIGHTHOUSE_EXECUTION_ENDPOINT" \
--execution-jwt /etc/mainnet-eth/jwtsecret \
--http \
--http-address 0.0.0.0 \
--http-port $LIGHTHOUSE_HTTP_PORT \
--metrics \
--metrics-address=0.0.0.0 \
--metrics-port $LIGHTHOUSE_METRICS_PORT \
--network mainnet \
--port $LIGHTHOUSE_NETWORK_PORT \
$ENR_OPTS $LIGHTHOUSE_OPTS
@@ -1,118 +0,0 @@
#!/bin/bash
# TODO: this file is now an unmodified copy of cerc-io/laconicd/init.sh
# so we should have a mechanism to bundle it inside the container rather than link from here
# at deploy time.
KEY="mykey"
CHAINID="laconic_9000-1"
MONIKER="localtestnet"
KEYRING="test"
KEYALGO="eth_secp256k1"
LOGLEVEL="info"
# trace evm
TRACE="--trace"
# TRACE=""
# validate dependencies are installed
command -v jq > /dev/null 2>&1 || { echo >&2 "jq not installed. More info: https://stedolan.github.io/jq/download/"; exit 1; }
# remove existing daemon and client
rm -rf ~/.laconic*
make install
laconicd config keyring-backend $KEYRING
laconicd config chain-id $CHAINID
# if $KEY exists it should be deleted
laconicd keys add $KEY --keyring-backend $KEYRING --algo $KEYALGO
# Set moniker and chain-id for Ethermint (Moniker can be anything, chain-id must be an integer)
laconicd init $MONIKER --chain-id $CHAINID
# Change parameter token denominations to aphoton
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["staking"]["params"]["bond_denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["crisis"]["constant_fee"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["gov"]["deposit_params"]["min_deposit"][0]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["mint"]["params"]["mint_denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
# Custom modules
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["record_rent"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_rent"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_commit_fee"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_reveal_fee"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_minimum_bid"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
if [[ "$TEST_REGISTRY_EXPIRY" == "true" ]]; then
echo "Setting timers for expiry tests."
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["record_rent_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_grace_period"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_rent_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
fi
if [[ "$TEST_AUCTION_ENABLED" == "true" ]]; then
echo "Enabling auction and setting timers."
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_enabled"]=true' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_rent_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_grace_period"]="300s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_commits_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_reveals_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
fi
# increase block time (?)
cat $HOME/.laconicd/config/genesis.json | jq '.consensus_params["block"]["time_iota_ms"]="1000"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
# Set gas limit in genesis
cat $HOME/.laconicd/config/genesis.json | jq '.consensus_params["block"]["max_gas"]="10000000"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
# disable produce empty block
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' 's/create_empty_blocks = true/create_empty_blocks = false/g' $HOME/.laconicd/config/config.toml
else
sed -i 's/create_empty_blocks = true/create_empty_blocks = false/g' $HOME/.laconicd/config/config.toml
fi
if [[ $1 == "pending" ]]; then
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' 's/create_empty_blocks_interval = "0s"/create_empty_blocks_interval = "30s"/g' $HOME/.laconicd/config/config.toml
sed -i '' 's/timeout_propose = "3s"/timeout_propose = "30s"/g' $HOME/.laconicd/config/config.toml
sed -i '' 's/timeout_propose_delta = "500ms"/timeout_propose_delta = "5s"/g' $HOME/.laconicd/config/config.toml
sed -i '' 's/timeout_prevote = "1s"/timeout_prevote = "10s"/g' $HOME/.laconicd/config/config.toml
sed -i '' 's/timeout_prevote_delta = "500ms"/timeout_prevote_delta = "5s"/g' $HOME/.laconicd/config/config.toml
sed -i '' 's/timeout_precommit = "1s"/timeout_precommit = "10s"/g' $HOME/.laconicd/config/config.toml
sed -i '' 's/timeout_precommit_delta = "500ms"/timeout_precommit_delta = "5s"/g' $HOME/.laconicd/config/config.toml
sed -i '' 's/timeout_commit = "5s"/timeout_commit = "150s"/g' $HOME/.laconicd/config/config.toml
sed -i '' 's/timeout_broadcast_tx_commit = "10s"/timeout_broadcast_tx_commit = "150s"/g' $HOME/.laconicd/config/config.toml
else
sed -i 's/create_empty_blocks_interval = "0s"/create_empty_blocks_interval = "30s"/g' $HOME/.laconicd/config/config.toml
sed -i 's/timeout_propose = "3s"/timeout_propose = "30s"/g' $HOME/.laconicd/config/config.toml
sed -i 's/timeout_propose_delta = "500ms"/timeout_propose_delta = "5s"/g' $HOME/.laconicd/config/config.toml
sed -i 's/timeout_prevote = "1s"/timeout_prevote = "10s"/g' $HOME/.laconicd/config/config.toml
sed -i 's/timeout_prevote_delta = "500ms"/timeout_prevote_delta = "5s"/g' $HOME/.laconicd/config/config.toml
sed -i 's/timeout_precommit = "1s"/timeout_precommit = "10s"/g' $HOME/.laconicd/config/config.toml
sed -i 's/timeout_precommit_delta = "500ms"/timeout_precommit_delta = "5s"/g' $HOME/.laconicd/config/config.toml
sed -i 's/timeout_commit = "5s"/timeout_commit = "150s"/g' $HOME/.laconicd/config/config.toml
sed -i 's/timeout_broadcast_tx_commit = "10s"/timeout_broadcast_tx_commit = "150s"/g' $HOME/.laconicd/config/config.toml
fi
fi
# Allocate genesis accounts (cosmos formatted addresses)
laconicd add-genesis-account $KEY 100000000000000000000000000aphoton --keyring-backend $KEYRING
# Sign genesis transaction
laconicd gentx $KEY 1000000000000000000000aphoton --keyring-backend $KEYRING --chain-id $CHAINID
# Collect genesis tx
laconicd collect-gentxs
# Run this to ensure everything worked and that the genesis file is setup correctly
laconicd validate-genesis
if [[ $1 == "pending" ]]; then
echo "pending mode is on, please wait for the first block committed."
fi
# Start the node (remove the --pruning=nothing flag if historical queries are not needed)
laconicd start --pruning=nothing --evm.tracer=json $TRACE --log_level $LOGLEVEL --minimum-gas-prices=0.0001aphoton --json-rpc.api eth,txpool,personal,net,debug,web3,miner --api.enable --gql-server --gql-playground
+18
View File
@@ -0,0 +1,18 @@
#!/bin/sh
if [[ -n "$CERC_SCRIPT_DEBUG" ]]; then
set -x
fi
#TODO: pass these in from the caller
TRACE="--trace"
LOGLEVEL="info"
laconicd start \
--pruning=nothing \
--evm.tracer=json $TRACE \
--log_level $LOGLEVEL \
--minimum-gas-prices=0.0001aphoton \
--json-rpc.api eth,txpool,personal,net,debug,web3,miner \
--api.enable \
--gql-server \
--gql-playground
@@ -0,0 +1,20 @@
module.exports = {
network: 'lotus-fixturenet',
v3: {
factory: {
address: 'FACTORY_ADDRESS',
startBlock: FACTORY_BLOCK
},
positionManager: {
address: 'NFPM_ADDRESS',
startBlock: NFPM_BLOCK
},
native: { address: 'NATIVE_ADDRESS' },
whitelistedTokenAddresses: [
'NATIVE_ADDRESS',
],
stableTokenAddresses: [
],
minimumEthLocked: 1.5
}
}
+39
View File
@@ -0,0 +1,39 @@
#!/bin/bash
set -e
# Loop until the NFPM deployment is detected
echo "Waiting for sushiswap-periphery deployments to occur"
while [ ! -f ./deployments/docker/NonfungiblePositionManager.json ]; do
sleep 5
done
echo "Reading contract addresses and block numbers from deployments"
FACTORY_ADDRESS=$(jq -r '.address' ./core-deployments/docker/UniswapV3Factory.json)
FACTORY_BLOCK=$(jq -r '.receipt.blockNumber' ./core-deployments/docker/UniswapV3Factory.json)
NATIVE_ADDRESS=$(jq -r '.address' ./deployments/docker/WFIL.json)
NFPM_ADDRESS=$(jq -r '.address' ./deployments/docker/NonfungiblePositionManager.json)
NFPM_BLOCK=$(jq -r '.receipt.blockNumber' ./deployments/docker/NonfungiblePositionManager.json)
# Read the JavaScript file content
file_content=$(</app/config/lotus-fixturenet.js.template)
# Replace uppercase words with environment variables
echo "Reading values in lotus-fixturenet config"
replaced_content=$(echo "$file_content" | sed -e "s/FACTORY_ADDRESS/$FACTORY_ADDRESS/g" \
-e "s/FACTORY_BLOCK/$FACTORY_BLOCK/g" \
-e "s/NFPM_ADDRESS/$NFPM_ADDRESS/g" \
-e "s/NFPM_BLOCK/$NFPM_BLOCK/g" \
-e "s/NATIVE_ADDRESS/$NATIVE_ADDRESS/g")
# Write the replaced content back to the JavaScript file
echo "$replaced_content" > /app/config/lotus-fixturenet.js
echo "Building subgraph and deploying to graph-node..."
pnpm run generate
pnpm run build
pnpm exec graph create --node http://graph-node:8020/ sushiswap/v3-lotus
pnpm exec graph deploy --node http://graph-node:8020/ --ipfs http://ipfs:5001 --version-label 0.1.0 sushiswap/v3-lotus
echo "Done"
+9
View File
@@ -0,0 +1,9 @@
#!/usr/bin/env bash
# Build cerc/eth-api-proxy
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
# See: https://stackoverflow.com/a/246128/1701505
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
docker build -t cerc/eth-api-proxy:local ${build_command_args} ${CERC_REPO_BASE_DIR}/eth-api-proxy
+9
View File
@@ -0,0 +1,9 @@
#!/usr/bin/env bash
# Build cerc/keycloak-reg-api
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
# See: https://stackoverflow.com/a/246128/1701505
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
docker build -t cerc/keycloak-reg-api:local ${build_command_args} ${CERC_REPO_BASE_DIR}/keycloak-reg-api
+9
View File
@@ -0,0 +1,9 @@
#!/usr/bin/env bash
# Build cerc/keycloak-reg-ui
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
# See: https://stackoverflow.com/a/246128/1701505
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
docker build -t cerc/keycloak-reg-ui:local ${build_command_args} ${CERC_REPO_BASE_DIR}/keycloak-reg-ui
@@ -1,69 +1,15 @@
# Originally from: https://github.com/devcontainers/images/blob/main/src/javascript-node/.devcontainer/Dockerfile
# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster
ARG VARIANT=18-bullseye
FROM node:${VARIANT}
ARG USERNAME=node
ARG NPM_GLOBAL=/usr/local/share/npm-global
FROM cerc/webapp-base:local
# This container pulls npm packages from a local registry configured via these env vars
ARG CERC_NPM_REGISTRY_URL
ARG CERC_NPM_AUTH_TOKEN
# Add NPM global to PATH.
ENV PATH=${NPM_GLOBAL}/bin:${PATH}
# Prevents npm from printing version warnings
ENV NPM_CONFIG_UPDATE_NOTIFIER=false
RUN \
# Configure global npm install location, use group to adapt to UID/GID changes
if ! cat /etc/group | grep -e "^npm:" > /dev/null 2>&1; then groupadd -r npm; fi \
&& usermod -a -G npm ${USERNAME} \
&& umask 0002 \
&& mkdir -p ${NPM_GLOBAL} \
&& touch /usr/local/etc/npmrc \
&& chown ${USERNAME}:npm ${NPM_GLOBAL} /usr/local/etc/npmrc \
&& chmod g+s ${NPM_GLOBAL} \
&& npm config -g set prefix ${NPM_GLOBAL} \
&& su ${USERNAME} -c "npm config -g set prefix ${NPM_GLOBAL}" \
# Install eslint
&& su ${USERNAME} -c "umask 0002 && npm install -g eslint" \
&& npm cache clean --force > /dev/null 2>&1
# [Optional] Uncomment this section to install additional OS packages.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends jq
# [Optional] Uncomment if you want to install an additional version of node using nvm
# ARG EXTRA_NODE_VERSION=10
# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"
# We do this to get a yq binary from the published container, for the correct architecture we're building here
COPY --from=docker.io/mikefarah/yq:latest /usr/bin/yq /usr/local/bin/yq
RUN mkdir -p /scripts
COPY ./apply-webapp-config.sh /scripts
COPY ./start-serving-app.sh /scripts
# [Optional] Uncomment if you want to install more global node modules
# RUN su node -c "npm install -g <your-package-list-here>"
# Configure the local npm registry
RUN npm config set @cerc-io:registry ${CERC_NPM_REGISTRY_URL} \
&& npm config set @lirewine:registry ${CERC_NPM_REGISTRY_URL} \
&& npm config set -- ${CERC_NPM_REGISTRY_URL}:_authToken ${CERC_NPM_AUTH_TOKEN}
RUN mkdir -p /config
COPY ./config.yml /config
# Install simple web server for now (use nginx perhaps later)
RUN yarn global add http-server
# Globally install the payload web app package
RUN yarn global add @cerc-io/console-app
# Expose port for http
EXPOSE 80
# Default command sleeps forever so docker doesn't kill it
CMD ["/scripts/start-serving-app.sh"]
COPY ./config.yml /config
@@ -1,8 +0,0 @@
#!/usr/bin/env bash
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
# TODO: Don't hard wire this:
webapp_files_dir=/usr/local/share/.config/yarn/global/node_modules/@cerc-io/console-app/dist/production
/scripts/apply-webapp-config.sh /config/config.yml ${webapp_files_dir}
http-server -p 80 ${webapp_files_dir}
@@ -6,4 +6,4 @@ source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
# See: https://stackoverflow.com/a/246128/1701505
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
docker build -t cerc/lighthouse:local ${build_command_args} ${SCRIPT_DIR}
docker build -t cerc/lighthouse:local ${build_command_args} --build-arg TAG_SUFFIX="" ${SCRIPT_DIR}
@@ -99,7 +99,7 @@ CMD ["-help"]
FROM lotus-base AS lotus-all-in-one
# Install netcat for healthcheck
RUN apt-get update && apt-get install -y netcat
RUN apt-get update && apt-get install -y netcat && apt-get install -y iproute2
ENV FILECOIN_PARAMETER_CACHE /var/tmp/filecoin-proof-parameters
ENV LOTUS_MINER_PATH /var/lib/lotus-miner
@@ -0,0 +1,11 @@
FROM node:18.15.0-alpine3.16
RUN apk --update --no-cache add git alpine-sdk bash jq
RUN curl -L https://unpkg.com/@pnpm/self-installer | node
WORKDIR /app
COPY . .
RUN echo "Installing dependencies..." && \
pnpm install
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
# Build cerc/sushiswap-subgraphs
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
docker build -t cerc/sushiswap-subgraphs:local -f ${SCRIPT_DIR}/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/subgraphs
@@ -1,6 +1,6 @@
FROM node:18.15.0-alpine3.16
RUN apk --update --no-cache add git python3 alpine-sdk bash
RUN apk --update --no-cache add git python3 alpine-sdk bash jq
RUN curl -L https://unpkg.com/@pnpm/self-installer | node
WORKDIR /app
@@ -1,6 +1,6 @@
FROM node:18.15.0-alpine3.16
RUN apk --update --no-cache add git python3 alpine-sdk bash
RUN apk --update --no-cache add git python3 alpine-sdk bash jq
WORKDIR /app
@@ -0,0 +1,57 @@
# Originally from: https://github.com/devcontainers/images/blob/main/src/javascript-node/.devcontainer/Dockerfile
# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster
ARG VARIANT=18-bullseye
FROM node:${VARIANT}
ARG USERNAME=node
ARG NPM_GLOBAL=/usr/local/share/npm-global
# Add NPM global to PATH.
ENV PATH=${NPM_GLOBAL}/bin:${PATH}
# Prevents npm from printing version warnings
ENV NPM_CONFIG_UPDATE_NOTIFIER=false
RUN \
# Configure global npm install location, use group to adapt to UID/GID changes
if ! cat /etc/group | grep -e "^npm:" > /dev/null 2>&1; then groupadd -r npm; fi \
&& usermod -a -G npm ${USERNAME} \
&& umask 0002 \
&& mkdir -p ${NPM_GLOBAL} \
&& touch /usr/local/etc/npmrc \
&& chown ${USERNAME}:npm ${NPM_GLOBAL} /usr/local/etc/npmrc \
&& chmod g+s ${NPM_GLOBAL} \
&& npm config -g set prefix ${NPM_GLOBAL} \
&& su ${USERNAME} -c "npm config -g set prefix ${NPM_GLOBAL}" \
# Install eslint
&& su ${USERNAME} -c "umask 0002 && npm install -g eslint" \
&& npm cache clean --force > /dev/null 2>&1
# [Optional] Uncomment this section to install additional OS packages.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends jq
# [Optional] Uncomment if you want to install an additional version of node using nvm
# ARG EXTRA_NODE_VERSION=10
# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"
# We do this to get a yq binary from the published container, for the correct architecture we're building here
COPY --from=docker.io/mikefarah/yq:latest /usr/bin/yq /usr/local/bin/yq
RUN mkdir -p /scripts
COPY ./apply-webapp-config.sh /scripts
COPY ./start-serving-app.sh /scripts
# [Optional] Uncomment if you want to install more global node modules
# RUN su node -c "npm install -g <your-package-list-here>"
RUN mkdir -p /config
COPY ./config.yml /config
# Install simple web server for now (use nginx perhaps later)
RUN yarn global add http-server
# Expose port for http
EXPOSE 80
# Default command sleeps forever so docker doesn't kill it
CMD ["/scripts/start-serving-app.sh"]
@@ -18,7 +18,7 @@ if ! [[ -d ${webapp_files_dir} ]]; then
fi
# First some magic using yq to translate our yaml config file into an array of key value pairs like:
# LACONIC_HOSTED_CONFIG_<path-through-objects>=<value>
readarray -t config_kv_pair_array < <( yq '.. | select(length > 2) | ([path | join("_"), .] | join("=") )' ${config_file_name} | sed 's/^/LACONIC_HOSTED_CONFIG_/' )
readarray -t config_kv_pair_array < <( yq '.. | ([path | join("_"), .] | join("=") )' ${config_file_name} | sort -r | sed -e '$ d' | sed 's/^/LACONIC_HOSTED_CONFIG_/' )
declare -p config_kv_pair_array
# Then iterate over that kv array making the template substitution in our web app files
for kv_pair_string in "${config_kv_pair_array[@]}"
+9
View File
@@ -0,0 +1,9 @@
#!/usr/bin/env bash
# Build cerc/laconic-registry-cli
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
# See: https://stackoverflow.com/a/246128/1701505
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
docker build -t cerc/webapp-base:local ${build_command_args} -f ${SCRIPT_DIR}/Dockerfile ${SCRIPT_DIR}
@@ -0,0 +1 @@
# Put config here.
@@ -0,0 +1,9 @@
#!/usr/bin/env bash
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
CERC_WEBAPP_FILES_DIR="${CERC_WEBAPP_FILES_DIR:-/data}"
/scripts/apply-webapp-config.sh /config/config.yml ${CERC_WEBAPP_FILES_DIR}
http-server -p 80 ${CERC_WEBAPP_FILES_DIR}
+2
View File
@@ -48,3 +48,5 @@ cerc/sushiswap-v3-core
cerc/sushiswap-v3-periphery
cerc/watcher-sushiswap
cerc/graph-node
cerc/sushiswap-subgraphs
cerc/webapp-base
+1
View File
@@ -31,3 +31,4 @@ mainnet-go-opera
lasso
reth
watcher-sushiswap
contract-sushiswap
+1
View File
@@ -42,3 +42,4 @@ git.vdb.to/cerc-io/plugeth-statediff
github.com/cerc-io/sushiswap-v3-core
github.com/cerc-io/sushiswap-v3-periphery
github.com/graphprotocol/graph-node
github.com/sushiswap/subgraphs
+1 -1
View File
@@ -55,7 +55,7 @@ This should create the required docker images in the local image registry.
## Clean up
Stop all the services running in background run:
Stop all the services running in background:
```bash
laconic-so --stack azimuth deploy-system down
+1 -1
View File
@@ -1,7 +1,7 @@
version: "1.0"
name: azimuth
repos:
- github.com/cerc-io/azimuth-watcher-ts
- github.com/cerc-io/azimuth-watcher-ts@v0.1.1
containers:
- cerc/watcher-azimuth
pods:
@@ -2,9 +2,11 @@ version: "1.0"
name: fixturenet-graph-node
description: "A graph-node fixturenet"
repos:
- github.com/filecoin-project/lotus
- github.com/graphprotocol/graph-node
containers:
- cerc/lotus
- cerc/graph-node
pods:
- fixturenet-lotus
- fixturenet-graph-node
@@ -21,6 +21,7 @@ npms:
containers:
- cerc/laconicd
- cerc/laconic-registry-cli
- cerc/webapp-base
- cerc/laconic-console-host
pods:
- fixturenet-laconicd
@@ -14,6 +14,9 @@ $ laconic-so --stack fixturenet-lotus build-containers
```
$ laconic-so --stack fixturenet-lotus deploy --cluster lotus up
```
Note: When running for the first time (or after clean up), the services will take some time to start properly as the Lotus nodes download the proof params (which are persisted to volumes)
Correct operation should be verified by checking the container logs with:
```
$ laconic-so --stack fixturenet-lotus deploy --cluster lotus logs lotus-miner
@@ -26,3 +29,19 @@ $ laconic-so --stack fixturenet-lotus deploy --cluster lotus exec lotus-miner "l
$ laconic-so --stack fixturenet-lotus deploy --cluster lotus exec lotus-node-1 "lotus status"
$ laconic-so --stack fixturenet-lotus deploy --cluster lotus exec lotus-node-2 "lotus status"
```
## 4. Clean up
Stop all the services running in background:
```
$ laconic-so --stack fixturenet-lotus deploy --cluster lotus down
```
Clear volumes created by this stack:
```
# List all relevant volumes
$ docker volume ls -q --filter "name=lotus"
# Remove all the listed volumes
$ docker volume rm $(docker volume ls -q --filter "name=lotus")
```
@@ -23,7 +23,7 @@ def setup(ctx):
return None
def create(ctx):
def create(ctx, extra_args):
# Generate the JWT secret and save to its config file
secret = token_hex(32)
jwt_file_path = ctx.deployment_dir.joinpath("data", "mainnet_eth_config_data", "jwtsecret")
+11
View File
@@ -5,11 +5,22 @@ repos:
- github.com/cerc-io/go-ethereum
- github.com/cerc-io/lighthouse
- github.com/dboreham/foundry
- git.vdb.to/cerc-io/keycloak-reg-api
- git.vdb.to/cerc-io/keycloak-reg-ui
- github.com/vulcanize/eth-api-proxy
containers:
- cerc/go-ethereum
- cerc/lighthouse
- cerc/lighthouse-cli
- cerc/foundry
- cerc/keycloak
- cerc/webapp-base
- cerc/keycloak-reg-api
- cerc/keycloak-reg-ui
- cerc/eth-api-proxy
pods:
- mainnet-eth
- mainnet-eth-keycloak
- mainnet-eth-metrics
- mainnet-eth-api-proxy
- foundry
@@ -14,9 +14,18 @@
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
from app.util import get_yaml
from app.deploy_types import DeployCommandContext, DeploymentContext
from app.deploy_types import DeployCommandContext, LaconicStackSetupCommand
from app.stack_state import State
from app.deploy_util import VolumeMapping, run_container_command
from app.command_types import CommandOptions
from enum import Enum
from pathlib import Path
from shutil import copyfile, copytree
import json
import os
import sys
import tomli
import re
default_spec_file_content = """config:
node_moniker: my-node-name
@@ -27,13 +36,242 @@ init_help_text = """Add helpful text here on setting config variables.
"""
def setup(command_context: DeployCommandContext):
node_moniker = "dbdb-node"
chain_id = "laconic_81337-1"
class SetupPhase(Enum):
INITIALIZE = 1
JOIN = 2
CREATE = 3
ILLEGAL = 3
def _client_toml_path(network_dir: Path):
return network_dir.joinpath("config", "client.toml")
def _config_toml_path(network_dir: Path):
return network_dir.joinpath("config", "config.toml")
def _get_chain_id_from_config(network_dir: Path):
chain_id = None
with open(_client_toml_path(network_dir), "rb") as f:
toml_dict = tomli.load(f)
chain_id = toml_dict["chain-id"]
return chain_id
def _get_node_moniker_from_config(network_dir: Path):
moniker = None
with open(_client_toml_path(network_dir), "rb") as f:
toml_dict = tomli.load(f)
moniker = toml_dict["moniker"]
return moniker
def _get_node_key_from_gentx(options: CommandOptions, gentx_file_name: str):
gentx_file_path = Path(gentx_file_name)
if gentx_file_path.exists():
with open(Path(gentx_file_name), "rb") as f:
parsed_json = json.load(f)
return parsed_json['body']['messages'][0]['delegator_address']
else:
print(f"Error: gentx file: {gentx_file_name} does not exist")
sys.exit(1)
def _comma_delimited_to_list(list_str: str):
return list_str.split(",") if list_str else []
def _get_node_keys_from_gentx_files(options: CommandOptions, gentx_file_list: str):
node_keys = []
gentx_files = _comma_delimited_to_list(gentx_file_list)
for gentx_file in gentx_files:
node_key = _get_node_key_from_gentx(options, gentx_file)
if node_key:
node_keys.append(node_key)
return node_keys
def _copy_gentx_files(options: CommandOptions, network_dir: Path, gentx_file_list: str):
gentx_files = _comma_delimited_to_list(gentx_file_list)
for gentx_file in gentx_files:
gentx_file_path = Path(gentx_file)
copyfile(gentx_file_path, os.path.join(network_dir, "config", "gentx", os.path.basename(gentx_file_path)))
def _remove_persistent_peers(options: CommandOptions, network_dir: Path):
config_file_path = _config_toml_path(network_dir)
if not config_file_path.exists():
print("Error: config.toml not found")
sys.exit(1)
with open(config_file_path, "r") as input_file:
config_file_content = input_file.read()
persistent_peers_pattern = '^persistent_peers = "(.+?)"'
replace_with = "persistent_peers = \"\""
config_file_content = re.sub(persistent_peers_pattern, replace_with, config_file_content, flags=re.MULTILINE)
with open(config_file_path, "w") as output_file:
output_file.write(config_file_content)
def setup(command_context: DeployCommandContext, parameters: LaconicStackSetupCommand, extra_args):
options = command_context.cluster_context.options
currency = "stake" # Does this need to be a parameter?
if options.debug:
print(f"parameters: {parameters}")
phase = SetupPhase.ILLEGAL
if parameters.initialize_network:
if parameters.join_network or parameters.create_network:
print("Can't supply --join-network or --create-network with --initialize-network")
sys.exit(1)
if not parameters.chain_id:
print("--chain-id is required")
sys.exit(1)
# node_moniker must be supplied
if not parameters.node_moniker:
print("Error: --node-moniker is required")
sys.exit(1)
phase = SetupPhase.INITIALIZE
elif parameters.join_network:
if parameters.initialize_network or parameters.create_network:
print("Can't supply --initialize-network or --create-network with --join-network")
sys.exit(1)
phase = SetupPhase.JOIN
elif parameters.create_network:
if parameters.initialize_network or parameters.join_network:
print("Can't supply --initialize-network or --join-network with --create-network")
sys.exit(1)
phase = SetupPhase.CREATE
network_dir = Path(parameters.network_dir).absolute()
laconicd_home_path_in_container = "/laconicd-home"
mounts = [
VolumeMapping("./path", "~/.laconicd")
VolumeMapping(network_dir, laconicd_home_path_in_container)
]
output, status = run_container_command(command_context.cluster_context, "laconicd", f"laconicd init {node_moniker} --chain-id {chain_id}", mounts)
if phase == SetupPhase.INITIALIZE:
# We want to create the directory so if it exists that's an error
if os.path.exists(network_dir):
print(f"Error: network directory {network_dir} already exists")
sys.exit(1)
os.mkdir(network_dir)
output, status = run_container_command(
command_context,
"laconicd", f"laconicd init {parameters.node_moniker} --home {laconicd_home_path_in_container}\
--chain-id {parameters.chain_id}", mounts)
if options.debug:
print(f"Command output: {output}")
elif phase == SetupPhase.JOIN:
if not os.path.exists(network_dir):
print(f"Error: network directory {network_dir} doesn't exist")
sys.exit(1)
# Get the chain_id from the config file created in the INITIALIZE phase
chain_id = _get_chain_id_from_config(network_dir)
output1, status1 = run_container_command(
command_context, "laconicd", f"laconicd keys add {parameters.key_name} --home {laconicd_home_path_in_container}\
--keyring-backend test", mounts)
if options.debug:
print(f"Command output: {output1}")
output2, status2 = run_container_command(
command_context,
"laconicd",
f"laconicd add-genesis-account {parameters.key_name} 12900000000000000000000{currency}\
--home {laconicd_home_path_in_container} --keyring-backend test",
mounts)
print(f"Command output: {output2}")
output3, status3 = run_container_command(
command_context,
"laconicd",
f"laconicd gentx {parameters.key_name} 90000000000{currency} --home {laconicd_home_path_in_container}\
--chain-id {chain_id} --keyring-backend test",
mounts)
print(f"Command output: {output3}")
output4, status4 = run_container_command(
command_context,
"laconicd",
f"laconicd keys show {parameters.key_name} -a --home {laconicd_home_path_in_container} --keyring-backend test",
mounts)
print(f"Command output: {output4}")
elif phase == SetupPhase.CREATE:
if not os.path.exists(network_dir):
print(f"Error: network directory {network_dir} doesn't exist")
sys.exit(1)
# In the CREATE phase, we are either a "coordinator" node, generating the genesis.json file ourselves
# OR we are a "not-coordinator" node, consuming a genesis file we got from the coordinator node.
if parameters.genesis_file:
# We got the genesis file from elsewhere
# Copy it into our network dir
genesis_file_path = Path(parameters.genesis_file)
if not os.path.exists(genesis_file_path):
print(f"Error: supplied genesis file: {parameters.genesis_file} does not exist.")
sys.exit(1)
copyfile(genesis_file_path, os.path.join(network_dir, "config", os.path.basename(genesis_file_path)))
else:
# We're generating the genesis file
# First look in the supplied gentx files for the other nodes' keys
other_node_keys = _get_node_keys_from_gentx_files(options, parameters.gentx_file_list)
# Add those keys to our genesis, with balances we determine here (why?)
for other_node_key in other_node_keys:
outputk, statusk = run_container_command(
command_context, "laconicd", f"laconicd add-genesis-account {other_node_key} 12900000000000000000000{currency}\
--home {laconicd_home_path_in_container} --keyring-backend test", mounts)
print(f"Command output: {outputk}")
# Copy the gentx json files into our network dir
_copy_gentx_files(options, network_dir, parameters.gentx_file_list)
# Now we can run collect-gentxs
output1, status1 = run_container_command(
command_context, "laconicd", f"laconicd collect-gentxs --home {laconicd_home_path_in_container}", mounts)
print(f"Command output: {output1}")
print(f"Generated genesis file, please copy to other nodes as required: \
{os.path.join(network_dir, 'config', 'genesis.json')}")
# Last thing, collect-gentxs puts a likely bogus set of persistent_peers in config.toml so we remove that now
_remove_persistent_peers(options, network_dir)
# In both cases we validate the genesis file now
output2, status1 = run_container_command(
command_context, "laconicd", f"laconicd validate-genesis --home {laconicd_home_path_in_container}", mounts)
print(f"Command output: {output2}")
else:
print("Illegal parameters supplied")
sys.exit(1)
def create(command_context: DeployCommandContext, extra_args):
network_dir = extra_args
if network_dir is None:
print("Error: --network-dir must be supplied")
sys.exit(1)
network_dir_path = Path(network_dir)
if not (network_dir_path.exists() and network_dir_path.is_dir()):
print(f"Error: supplied network directory does not exist: {network_dir}")
sys.exit(1)
config_dir_path = network_dir_path.joinpath("config")
if not (config_dir_path.exists() and config_dir_path.is_dir()):
print(f"Error: supplied network directory does not contain a config directory: {config_dir_path}")
sys.exit(1)
data_dir_path = network_dir_path.joinpath("data")
if not (data_dir_path.exists() and data_dir_path.is_dir()):
print(f"Error: supplied network directory does not contain a data directory: {data_dir_path}")
sys.exit(1)
# Copy the network directory contents into our deployment
# TODO: change this to work with non local paths
deployment_config_dir = command_context.deployment_dir.joinpath("data", "laconicd-config")
copytree(config_dir_path, deployment_config_dir, dirs_exist_ok=True)
# Copy the data directory contents into our deployment
# TODO: change this to work with non local paths
deployment_data_dir = command_context.deployment_dir.joinpath("data", "laconicd-data")
copytree(data_dir_path, deployment_data_dir, dirs_exist_ok=True)
def init(command_context: DeployCommandContext):
@@ -21,6 +21,7 @@ npms:
containers:
- cerc/laconicd
- cerc/laconic-registry-cli
- cerc/webapp-base
- cerc/laconic-console-host
pods:
- mainnet-laconicd
+1 -1
View File
@@ -93,7 +93,7 @@ Follow the [demo](./demo.md) to try out the MobyMask app with L2 chain
## Clean up
Stop all the services running in background run:
Stop all the services running in background:
```bash
laconic-so --stack mobymask-v2 deploy --cluster mobymask_v2 down 30
@@ -0,0 +1,111 @@
# SushiSwap Graph
## Setup
Clone required repositories:
```bash
laconic-so --stack sushiswap-subgraph setup-repositories
```
Build the container images:
```bash
laconic-so --stack sushiswap-subgraph build-containers
```
## Deploy
Deploy the stack:
```bash
laconic-so --stack sushiswap-subgraph deploy --cluster sushigraph up
```
After all services have started, wait and check that the subgraph has been deployed to graph-node
```bash
laconic-so --stack sushiswap-subgraph deploy --cluster sushigraph logs -f sushiswap-subgraph-v3
# Expected end output
# ...
# sushigraph-sushiswap-subgraph-v3-1 | - Deploying to Graph node http://graph-node:8020/
# sushigraph-sushiswap-subgraph-v3-1 | Deployed to http://graph-node:8000/subgraphs/name/sushiswap/v3-lotus/graphql
# sushigraph-sushiswap-subgraph-v3-1 |
# sushigraph-sushiswap-subgraph-v3-1 | Subgraph endpoints:
# sushigraph-sushiswap-subgraph-v3-1 | Queries (HTTP): http://graph-node:8000/subgraphs/name/sushiswap/v3-lotus
# sushigraph-sushiswap-subgraph-v3-1 |
# sushigraph-sushiswap-subgraph-v3-1 | Done
```
## Run
To check graph-node logs:
```bash
laconic-so --stack sushiswap-subgraph deploy --cluster sushigraph logs -f graph-node
```
To deploy tokens run:
```bash
docker exec -it sushigraph-sushiswap-v3-periphery-1 yarn hardhat --network docker deploy --tags TestERC20
```
This can be run multiple times to deploy ERC20 tokens
Take note of the deployed token addresses to use later
Get contract address of factory deployed:
```bash
docker exec -it sushigraph-sushiswap-v3-core-1 jq -r '.address' /app/deployments/docker/UniswapV3Factory.json
```
Set it to environment variable `FACTORY_ADDRESS` to use later
To create a pool:
```bash
docker exec -it sushigraph-sushiswap-v3-core-1 pnpm run pool:create:docker --factory $FACTORY_ADDRESS --token0 $TOKEN1_ADDRESS --token1 $TOKEN2_ADDRESS --fee 500
```
Set the created pool address to environment variable `POOL_ADDRESS` to use later
To initialize pool:
```bash
docker exec -it sushigraph-sushiswap-v3-core-1 pnpm run pool:initialize:docker --sqrt-price 4295128939 --pool $POOL_ADDRESS
```
Set the recipient address to the contract deployer:
```bash
export RECIPIENT=0xD375B03bd3A2434A9f675bEC4Ccd68aC5e67C743
```
Trigger pool mint event:
```bash
docker exec -it sushigraph-sushiswap-v3-core-1 pnpm run pool:mint:docker --pool $POOL_ADDRESS --recipient $RECIPIENT --amount 10
```
Trigger pool burn event:
```bash
docker exec -it sushigraph-sushiswap-v3-core-1 pnpm run pool:burn:docker --pool $POOL_ADDRESS --amount 10
```
## Clean up
Stop all the services running in background run:
```bash
laconic-so --stack sushiswap-subgraph deploy --cluster sushigraph down
```
Clear volumes created by this stack:
```bash
# List all relevant volumes
docker volume ls -q --filter "name=sushigraph"
# Remove all the listed volumes
docker volume rm $(docker volume ls -q --filter "name=sushigraph")
# WARNING: After removing volumes with Lotus params
# They will be downloaded again on restart
# To remove volumes that do not contain Lotus params
docker volume rm $(docker volume ls -q --filter "name=sushigraph" | grep -v "params$")
```
@@ -0,0 +1,28 @@
version: "1.0"
name: sushiswap-subgraph
description: "An end-to-end SushiSwap Subgraph stack"
repos:
## fixturenet-lotus repo
- github.com/filecoin-project/lotus
## graph-node repo
- github.com/graphprotocol/graph-node
## sushiswap repos
- github.com/cerc-io/sushiswap-v3-core@watcher-ts
- github.com/cerc-io/sushiswap-v3-periphery@watcher-ts
## subgraph repo
- github.com/sushiswap/subgraphs
containers:
## fixturenet-lotus image
- cerc/lotus
## fixturenet-graph-node image
- cerc/graph-node
## sushiswap contract deployment images
- cerc/sushiswap-v3-core
- cerc/sushiswap-v3-periphery
## sushiswap subgraphs image
- cerc/sushiswap-subgraphs
pods:
- fixturenet-lotus
- fixturenet-graph-node
- contract-sushiswap
- sushiswap-subgraph-v3
+3 -1
View File
@@ -22,13 +22,15 @@ Deploy the stack:
laconic-so --stack sushiswap deploy --cluster sushiswap up
```
Note: When running for the first time (or after clean up), the services will take some time to start as Lotus nodes in the fixturenet download the proof params
## Tests
Follow [smoke-tests.md](./smoke-tests.md) to run smoke tests
## Clean up
Stop all the services running in background run:
Stop all the services running in background:
```bash
laconic-so --stack sushiswap deploy --cluster sushiswap down
+4 -4
View File
@@ -14,10 +14,9 @@
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
from app.util import get_yaml
from app.deploy_types import DeployCommandContext, DeploymentContext
from app.deploy_types import DeployCommandContext
from app.stack_state import State
from app.deploy_util import VolumeMapping, run_container_command
import os
from pathlib import Path
default_spec_file_content = """config:
@@ -27,9 +26,10 @@ default_spec_file_content = """config:
init_help_text = """Add helpful text here on setting config variables.
"""
# Output a known string to a know file in the bind mounted directory ./container-output-dir
# for test purposes -- test checks that the file was written.
def setup(command_context: DeployCommandContext, extra_args):
def setup(command_context: DeployCommandContext, parameters, extra_args):
host_directory = "./container-output-dir"
host_directory_absolute = Path(extra_args[0]).absolute().joinpath(host_directory)
host_directory_absolute.mkdir(parents=True, exist_ok=True)
@@ -45,7 +45,7 @@ def init(command_context: DeployCommandContext):
return yaml.load(default_spec_file_content)
def create(command_context: DeployCommandContext):
def create(command_context: DeployCommandContext, extra_args):
data = "create-command-output-data"
output_file_path = command_context.deployment_dir.joinpath("create-file")
with open(output_file_path, 'w+') as output_file:
+1 -1
View File
@@ -312,7 +312,7 @@ def _make_cluster_context(ctx, stack, include, exclude, cluster, env_file):
if ctx.verbose:
print(f"files: {compose_files}")
return ClusterContext(cluster, compose_files, pre_start_commands, post_start_commands, cluster_config, env_file)
return ClusterContext(ctx, cluster, compose_files, pre_start_commands, post_start_commands, cluster_config, env_file)
def _convert_to_new_format(old_pod_array):
+20
View File
@@ -17,9 +17,11 @@ from typing import List
from dataclasses import dataclass
from pathlib import Path
from python_on_whales import DockerClient
from app.command_types import CommandOptions
@dataclass
class ClusterContext:
options: CommandOptions # TODO: this should be in its own object not stuffed in here
cluster: str
compose_files: List[str]
pre_start_commands: List[str]
@@ -45,3 +47,21 @@ class DeploymentContext:
class VolumeMapping:
host_path: str
container_path: str
@dataclass
class LaconicStackSetupCommand:
chain_id: str
node_moniker: str
key_name: str
initialize_network: bool
join_network: bool
create_network: bool
gentx_file_list: str
genesis_file: str
network_dir: str
@dataclass
class LaconicStackCreateCommand:
network_dir: str
+10 -4
View File
@@ -15,12 +15,11 @@
import os
from typing import List
from dataclasses import dataclass
from app.deploy_types import DeployCommandContext, VolumeMapping
from app.util import get_parsed_stack_config, get_yaml, get_compose_file_dir
def _container_image_from_service(stack:str, service: str):
def _container_image_from_service(stack :str, service: str):
# Parse the compose files looking for the image name of the specified service
image_name = None
parsed_stack = get_parsed_stack_config(stack)
@@ -39,7 +38,7 @@ def _container_image_from_service(stack:str, service: str):
def _volumes_to_docker(mounts: List[VolumeMapping]):
# Example from doc: [("/", "/host"), ("/etc/hosts", "/etc/hosts", "rw")]
# Example from doc: [("/", "/host"), ("/etc/hosts", "/etc/hosts", "rw")]
result = []
for mount in mounts:
docker_volume = (mount.host_path, mount.container_path)
@@ -51,6 +50,13 @@ def run_container_command(ctx: DeployCommandContext, service: str, command: str,
docker = ctx.docker
container_image = _container_image_from_service(ctx.stack, service)
docker_volumes = _volumes_to_docker(mounts)
docker_output = docker.run(container_image, ["-c", command], entrypoint="bash", volumes=docker_volumes)
if ctx.cluster_context.options.debug:
print(f"Running this command in {service} container: {command}")
docker_output = docker.run(
container_image,
["-c", command], entrypoint="sh",
user=f"{os.getuid()}:{os.getgid()}",
volumes=docker_volumes
)
# There doesn't seem to be a way to get an exit code from docker.run()
return (docker_output, 0)
+2
View File
@@ -30,6 +30,8 @@ class DeploymentContext:
@click.option("--dir", required=True, help="path to deployment directory")
@click.pass_context
def command(ctx, dir):
'''create a deployment'''
# Check that --stack wasn't supplied
if ctx.parent.obj.stack:
print("Error: --stack can't be supplied with the deployment command")
+69 -46
View File
@@ -14,19 +14,20 @@
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
import click
from dataclasses import dataclass
from importlib import util
import os
from pathlib import Path
from shutil import copyfile, copytree
import sys
from app.util import get_stack_file_path, get_parsed_deployment_spec, get_parsed_stack_config, global_options, get_yaml, get_compose_file_dir
from app.deploy_types import DeploymentContext, DeployCommandContext
from app.util import get_stack_file_path, get_parsed_deployment_spec, get_parsed_stack_config, global_options, get_yaml
from app.util import get_compose_file_dir
from app.deploy_types import DeploymentContext, LaconicStackSetupCommand
def _make_default_deployment_dir():
return "deployment-001"
def _get_ports(stack):
ports = {}
parsed_stack = get_parsed_stack_config(stack)
@@ -42,6 +43,7 @@ def _get_ports(stack):
ports[svc_name] = [ str(x) for x in svc["ports"] ]
return ports
def _get_named_volumes(stack):
# Parse the compose files looking for named volumes
named_volumes = []
@@ -76,30 +78,30 @@ def _create_bind_dir_if_relative(volume, path_string, compose_dir):
# See: https://stackoverflow.com/questions/45699189/editing-docker-compose-yml-with-pyyaml
def _fixup_pod_file(pod, spec, compose_dir):
# Fix up volumes
if "volumes" in spec:
spec_volumes = spec["volumes"]
if "volumes" in pod:
pod_volumes = pod["volumes"]
for volume in pod_volumes.keys():
if volume in spec_volumes:
volume_spec = spec_volumes[volume]
volume_spec_fixedup = volume_spec if Path(volume_spec).is_absolute() else f".{volume_spec}"
_create_bind_dir_if_relative(volume, volume_spec, compose_dir)
new_volume_spec = {"driver": "local",
"driver_opts": {
# Fix up volumes
if "volumes" in spec:
spec_volumes = spec["volumes"]
if "volumes" in pod:
pod_volumes = pod["volumes"]
for volume in pod_volumes.keys():
if volume in spec_volumes:
volume_spec = spec_volumes[volume]
volume_spec_fixedup = volume_spec if Path(volume_spec).is_absolute() else f".{volume_spec}"
_create_bind_dir_if_relative(volume, volume_spec, compose_dir)
new_volume_spec = {"driver": "local",
"driver_opts": {
"type": "none",
"device": volume_spec_fixedup,
"o": "bind"
}
}
pod["volumes"][volume] = new_volume_spec
# Fix up ports
if "ports" in spec:
spec_ports = spec["ports"]
for container_name, container_ports in spec_ports.items():
if container_name in pod["services"]:
pod["services"][container_name]["ports"] = container_ports
}
pod["volumes"][volume] = new_volume_spec
# Fix up ports
if "ports" in spec:
spec_ports = spec["ports"]
for container_name, container_ports in spec_ports.items():
if container_name in pod["services"]:
pod["services"][container_name]["ports"] = container_ports
def call_stack_deploy_init(deploy_command_context):
@@ -107,34 +109,43 @@ def call_stack_deploy_init(deploy_command_context):
# Call a function in it
# If no function found, return None
python_file_path = get_stack_file_path(deploy_command_context.stack).parent.joinpath("deploy", "commands.py")
spec = util.spec_from_file_location("commands", python_file_path)
imported_stack = util.module_from_spec(spec)
spec.loader.exec_module(imported_stack)
return imported_stack.init(deploy_command_context)
if python_file_path.exists():
spec = util.spec_from_file_location("commands", python_file_path)
imported_stack = util.module_from_spec(spec)
spec.loader.exec_module(imported_stack)
return imported_stack.init(deploy_command_context)
else:
return None
# TODO: fold this with function above
def call_stack_deploy_setup(deploy_command_context, extra_args):
def call_stack_deploy_setup(deploy_command_context, parameters: LaconicStackSetupCommand, extra_args):
# Link with the python file in the stack
# Call a function in it
# If no function found, return None
python_file_path = get_stack_file_path(deploy_command_context.stack).parent.joinpath("deploy", "commands.py")
spec = util.spec_from_file_location("commands", python_file_path)
imported_stack = util.module_from_spec(spec)
spec.loader.exec_module(imported_stack)
return imported_stack.setup(deploy_command_context, extra_args)
if python_file_path.exists():
spec = util.spec_from_file_location("commands", python_file_path)
imported_stack = util.module_from_spec(spec)
spec.loader.exec_module(imported_stack)
return imported_stack.setup(deploy_command_context, parameters, extra_args)
else:
return None
# TODO: fold this with function above
def call_stack_deploy_create(deployment_context):
def call_stack_deploy_create(deployment_context, extra_args):
# Link with the python file in the stack
# Call a function in it
# If no function found, return None
python_file_path = get_stack_file_path(deployment_context.command_context.stack).parent.joinpath("deploy", "commands.py")
spec = util.spec_from_file_location("commands", python_file_path)
imported_stack = util.module_from_spec(spec)
spec.loader.exec_module(imported_stack)
return imported_stack.create(deployment_context)
if python_file_path.exists():
spec = util.spec_from_file_location("commands", python_file_path)
imported_stack = util.module_from_spec(spec)
spec.loader.exec_module(imported_stack)
return imported_stack.create(deployment_context, extra_args)
else:
return None
# Inspect the pod yaml to find config files referenced in subdirectories
@@ -187,8 +198,10 @@ def init(ctx, output):
@click.command()
@click.option("--spec-file", required=True, help="Spec file to use to create this deployment")
@click.option("--deployment-dir", help="Create deployment files in this directory")
# TODO: Hack
@click.option("--network-dir", help="Network configuration supplied in this directory")
@click.pass_context
def create(ctx, spec_file, deployment_dir):
def create(ctx, spec_file, deployment_dir, network_dir):
# This function fails with a useful error message if the file doens't exist
parsed_spec = get_parsed_deployment_spec(spec_file)
stack_name = parsed_spec['stack']
@@ -236,16 +249,26 @@ def create(ctx, spec_file, deployment_dir):
deployment_command_context = ctx.obj
deployment_command_context.stack = stack_name
deployment_context = DeploymentContext(Path(deployment_dir), deployment_command_context)
call_stack_deploy_create(deployment_context)
call_stack_deploy_create(deployment_context, network_dir)
# TODO: this code should be in the stack .py files but
# we haven't yet figured out how to integrate click across
# the plugin boundary
@click.command()
@click.option("--node-moniker", help="Help goes here")
@click.option("--key-name", help="Help goes here")
@click.option("--initialize-network", is_flag=True, default=False, help="Help goes here")
@click.option("--join-network", is_flag=True, default=False, help="Help goes here")
@click.option("--create-network", is_flag=True, default=False, help="Help goes here")
@click.option("--node-moniker", help="Moniker for this node")
@click.option("--chain-id", help="The new chain id")
@click.option("--key-name", help="Name for new node key")
@click.option("--gentx-files", help="List of comma-delimited gentx filenames from other nodes")
@click.option("--genesis-file", help="Genesis file for the network")
@click.option("--initialize-network", is_flag=True, default=False, help="Initialize phase")
@click.option("--join-network", is_flag=True, default=False, help="Join phase")
@click.option("--create-network", is_flag=True, default=False, help="Create phase")
@click.option("--network-dir", help="Directory for network files")
@click.argument('extra_args', nargs=-1)
@click.pass_context
def setup(ctx, node_moniker, key_name, initialize_network, join_network, create_network, extra_args):
call_stack_deploy_setup(ctx.obj, extra_args)
def setup(ctx, node_moniker, chain_id, key_name, gentx_files, genesis_file, initialize_network, join_network, create_network,
network_dir, extra_args):
parmeters = LaconicStackSetupCommand(chain_id, node_moniker, key_name, initialize_network, join_network, create_network,
gentx_files, genesis_file, network_dir)
call_stack_deploy_setup(ctx.obj, parmeters, extra_args)
+1
View File
@@ -15,6 +15,7 @@
from enum import Enum
class State(Enum):
CREATED = 1
CONFIGURED = 2
+2 -12
View File
@@ -16,6 +16,7 @@
import click
from dataclasses import dataclass
from app.command_types import CommandOptions
from app import setup_repositories
from app import build_containers
from app import build_npms
@@ -26,17 +27,6 @@ from app import deployment
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
@dataclass
class Options:
stack: str
quiet: bool = False
verbose: bool = False
dry_run: bool = False
local_stack: bool = False
debug: bool = False
continue_on_error: bool = False
@click.group(context_settings=CONTEXT_SETTINGS)
@click.option('--stack', help="specify a stack to build/deploy")
@click.option('--quiet', is_flag=True, default=False)
@@ -49,7 +39,7 @@ class Options:
@click.pass_context
def cli(ctx, stack, quiet, verbose, dry_run, local_stack, debug, continue_on_error):
"""Laconic Stack Orchestrator"""
ctx.obj = Options(stack, quiet, verbose, dry_run, local_stack, debug, continue_on_error)
ctx.obj = CommandOptions(stack, quiet, verbose, dry_run, local_stack, debug, continue_on_error)
cli.add_command(setup_repositories.command, "setup-repositories")
+1 -1
View File
@@ -23,7 +23,7 @@ ssh root@IP
2. Get the install script, give it executable permissions, and run it:
```
curl -o install.sh https://raw.githubusercontent.com/cerc-io/stack-orchestrator/main/scripts/quick-install-ubuntu.sh
curl -o install.sh https://raw.githubusercontent.com/cerc-io/stack-orchestrator/main/scripts/quick-install-linux.sh
```
```
chmod +x install.sh
+1
View File
@@ -6,3 +6,4 @@ click>=8.1.6
PyYAML>=6.0.1
ruamel.yaml>=0.17.32
pydantic==1.10.9
tomli==2.0.1
@@ -28,12 +28,43 @@ fi
# Check python3 is available
# Check machine resources are sufficient
# Determine if we are on Debian or Ubuntu
linux_distro=$(lsb_release -a 2>/dev/null | grep "^Distributor ID:" | cut -f 2)
# Some systems don't have lsb_release installed (e.g. ChromeOS) and so we try to
# use /etc/os-release instead
if [[ -z "$linux_distro" ]]; then
if [[ -f "/etc/os-release" ]]; then
distro_name_string=$(grep "^NAME=" /etc/os-release | cut -d '=' -f 2)
if [[ $distro_name_string =~ Debian ]]; then
linux_distro="Debian"
elif [[ $distro_name_string =~ Ubuntu ]]; then
linux_distro="Ubuntu"
fi
else
echo "Failed to identify distro: /etc/os-release doesn't exist"
exit 1
fi
fi
case $linux_distro in
Debian)
echo "Installing docker for Debian"
;;
Ubuntu)
echo "Installing docker for Ubuntu"
;;
*)
echo "ERROR: Detected unknown distribution $linux_distro, can't install docker"
exit 1
;;
esac
# dismiss the popups
export DEBIAN_FRONTEND=noninteractive
## https://docs.docker.com/engine/install/ubuntu/
## https://docs.docker.com/engine/install/debian/
## https://superuser.com/questions/518859/ignore-packages-that-are-not-currently-installed-when-using-apt-get-remove1
packages_to_remove="docker docker-engine docker.io containerd runc"
packages_to_remove="docker docker-engine docker.io containerd runc docker-compose docker-doc podman-docker"
installed_packages_to_remove=""
for package_to_remove in $(echo $packages_to_remove); do
$(dpkg --info $package_to_remove &> /dev/null)
@@ -65,10 +96,25 @@ sudo apt -y install curl
sudo apt -y install ca-certificates gnupg
# Add dockerco package repository
sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# For reasons not obvious, the dockerco instructions for installation on
# Debian and Ubuntu are slightly different here
case $linux_distro in
Debian)
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
;;
Ubuntu)
sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
;;
*)
echo "ERROR: Detected unknown distribution $linux_distro, can't install docker"
exit 1
;;
esac
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/${linux_distro,,} \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
+44
View File
@@ -0,0 +1,44 @@
#!/usr/bin/env bash
set -e
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
set -e
echo "Running stack-orchestrator Ethereum plugeth fixturenet test"
# Bit of a hack, test the most recent package
TEST_TARGET_SO=$( ls -t1 ./package/laconic-so* | head -1 )
CERC_STACK_NAME=fixturenet-plugeth-tx
# Set a new unique repo dir
export CERC_REPO_BASE_DIR=$(mktemp -d stack-orchestrator-fixturenet-eth-test.XXXXXXXXXX)
echo "Testing this package: $TEST_TARGET_SO"
echo "Test version command"
reported_version_string=$( $TEST_TARGET_SO version )
echo "Version reported is: ${reported_version_string}"
echo "Cloning repositories into: $CERC_REPO_BASE_DIR"
$TEST_TARGET_SO --stack $CERC_STACK_NAME setup-repositories
echo "Building containers"
$TEST_TARGET_SO --stack $CERC_STACK_NAME build-containers
echo "Images in registry:"
docker image ls
echo "Deploying the cluster"
$TEST_TARGET_SO --stack $CERC_STACK_NAME deploy up
# Verify that the fixturenet is up and running
$TEST_TARGET_SO --stack $CERC_STACK_NAME deploy ps
$TEST_TARGET_SO --stack $CERC_STACK_NAME deploy exec fixturenet-eth-bootnode-lighthouse /scripts/status-internal.sh
initial_block_number=$($TEST_TARGET_SO --stack fixturenet-plugeth-tx deploy exec foundry "cast block-number")
# Check that the block number increases some time later
sleep 12
subsequent_block_number=$($TEST_TARGET_SO --stack $CERC_STACK_NAME deploy exec foundry "cast block-number")
block_number_difference=$((subsequent_block_number - initial_block_number))
# Block height difference should be between 1 and some small number
if [[ $block_number_difference -gt 1 && $block_number_difference -lt 10 ]]; then
echo "Test passed"
test_result=0
else
echo "Test failed: block numbers were ${initial_block_number} and ${subsequent_block_number}"
test_result=1
fi
$TEST_TARGET_SO --stack $CERC_STACK_NAME deploy down
echo "Removing cloned repositories"
rm -rf $CERC_REPO_BASE_DIR
exit $test_result
+19 -10
View File
@@ -4,36 +4,45 @@ if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
echo "Running stack-orchestrator Ethereum fixturenet test"
echo "$(date +"%Y-%m-%d %T"): Running stack-orchestrator Ethereum fixturenet test"
# Bit of a hack, test the most recent package
TEST_TARGET_SO=$( ls -t1 ./package/laconic-so* | head -1 )
# Set a new unique repo dir
export CERC_REPO_BASE_DIR=$(mktemp -d stack-orchestrator-fixturenet-eth-test.XXXXXXXXXX)
echo "Testing this package: $TEST_TARGET_SO"
echo "Test version command"
echo "$(date +"%Y-%m-%d %T"): Testing this package: $TEST_TARGET_SO"
echo "$(date +"%Y-%m-%d %T"): Test version command"
reported_version_string=$( $TEST_TARGET_SO version )
echo "Version reported is: ${reported_version_string}"
echo "Cloning repositories into: $CERC_REPO_BASE_DIR"
$TEST_TARGET_SO --stack fixturenet-eth setup-repositories
echo "$(date +"%Y-%m-%d %T"): Version reported is: ${reported_version_string}"
echo "$(date +"%Y-%m-%d %T"): Cloning repositories into: $CERC_REPO_BASE_DIR"
$TEST_TARGET_SO --stack fixturenet-eth setup-repositories
echo "$(date +"%Y-%m-%d %T"): Building containers"
$TEST_TARGET_SO --stack fixturenet-eth build-containers
echo "$(date +"%Y-%m-%d %T"): Starting stack"
$TEST_TARGET_SO --stack fixturenet-eth deploy up
echo "$(date +"%Y-%m-%d %T"): Stack started"
# Verify that the fixturenet is up and running
$TEST_TARGET_SO --stack fixturenet-eth deploy ps
$TEST_TARGET_SO --stack fixturenet-eth deploy exec fixturenet-eth-bootnode-lighthouse /scripts/status-internal.sh
# echo "$(date +"%Y-%m-%d %T"): Getting stack status"
# $TEST_TARGET_SO --stack fixturenet-eth deploy exec fixturenet-eth-bootnode-lighthouse /scripts/status-internal.sh
echo "$(date +"%Y-%m-%d %T"): Getting initial block number"
initial_block_number=$($TEST_TARGET_SO --stack fixturenet-eth deploy exec foundry "cast block-number")
# Check that the block number increases some time later
sleep 12
sleep 120
echo "$(date +"%Y-%m-%d %T"): Getting subsequent block number"
subsequent_block_number=$($TEST_TARGET_SO --stack fixturenet-eth deploy exec foundry "cast block-number")
block_number_difference=$((subsequent_block_number - initial_block_number))
# Block height difference should be between 1 and some small number
if [[ $block_number_difference -gt 1 && $block_number_difference -lt 10 ]]; then
if [[ $block_number_difference -gt 1 && $block_number_difference -lt 100 ]]; then
echo "Test passed"
test_result=0
else
echo "Test failed: block numbers were ${initial_block_number} and ${subsequent_block_number}"
echo "Logs from stack:"
$TEST_TARGET_SO --stack fixturenet-eth deploy logs
test_result=1
fi
$TEST_TARGET_SO --stack fixturenet-eth deploy down
echo "Removing cloned repositories"
echo "$(date +"%Y-%m-%d %T"): Removing cloned repositories"
rm -rf $CERC_REPO_BASE_DIR
echo "$(date +"%Y-%m-%d %T"): Test finished"
exit $test_result
+58
View File
@@ -0,0 +1,58 @@
#!/bin/bash
set -e
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
node_count=4
node_dir_prefix="laconic-network-dir"
chain_id="laconic_81337-6"
node_moniker_prefix="node"
echo "Deleting any existing network directories..."
for (( i=1 ; i<=$node_count ; i++ ));
do
node_network_dir=${node_dir_prefix}${i}
if [[ -d $node_network_dir ]]; then
echo "Deleting ${node_network_dir}"
rm -rf ${node_network_dir}
fi
done
echo "Initalizing ${node_count} nodes networks..."
for (( i=1 ; i<=$node_count ; i++ ));
do
node_network_dir=${node_dir_prefix}${i}
node_moniker=${node_moniker_prefix}${i}
laconic-so --stack mainnet-laconic deploy setup --network-dir ${node_network_dir} --initialize-network --chain-id ${chain_id} --node-moniker ${node_moniker}
done
echo "Joining ${node_count} nodes to the network..."
for (( i=1 ; i<=$node_count ; i++ ));
do
node_network_dir=${node_dir_prefix}${i}
node_moniker=${node_moniker_prefix}${i}
laconic-so --stack mainnet-laconic deploy setup --network-dir ${node_network_dir} --join-network --key-name ${node_moniker}
done
echo "Merging ${node_count} nodes genesis txns..."
gentx_files=""
delimeter=""
# Note: start at node 2 here because we're going to copy to node 1
for (( i=2 ; i<=$node_count ; i++ ));
do
node_network_dir=${node_dir_prefix}${i}
node_gentx_file=$(ls ${node_network_dir}/config/gentx/*.json)
gentx_files+=${delimeter}${node_gentx_file}
delimeter=","
done
# Generate the genesis file on node 1
laconic-so --stack mainnet-laconic deploy setup --network-dir ${node_dir_prefix}1 --create-network --gentx-files ${gentx_files}
genesis_file=${node_dir_prefix}1/config/genesis.json
# Now import the genesis file to the other nodes
for (( i=2 ; i<=$node_count ; i++ ));
do
echo "Importing genesis.json into node ${i}"
node_network_dir=${node_dir_prefix}${i}
laconic-so --stack mainnet-laconic deploy setup --network-dir ${node_network_dir} --create-network --genesis-file ${genesis_file}
done