Compare commits

..
Author SHA1 Message Date
zramsay bcf6564cec huh 2023-09-11 14:04:57 -04:00
99 changed files with 1040 additions and 3301 deletions
-13
View File
@@ -16,7 +16,6 @@ Ensure that the following are already installed:
- [Python3](https://wiki.python.org/moin/BeginnersGuide/Download): `python3 --version` >= `3.8.10` (the Python3 shipped in Ubuntu 20+ is good to go)
- [Docker](https://docs.docker.com/get-docker/): `docker --version` >= `20.10.21`
- [jq](https://stedolan.github.io/jq/download/): `jq --version` >= `1.5`
- [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git): `git --version` >= `2.10.3`
Note: if installing docker-compose via package manager on Linux (as opposed to Docker Desktop), you must [install the plugin](https://docs.docker.com/compose/install/linux/#install-the-plugin-manually), e.g. :
@@ -49,18 +48,6 @@ Verify operation (your version will probably be different, just check here that
laconic-so version
Version: 1.1.0-7a607c2-202304260513
```
Save the distribution url to `~/.laconic-so/config.yml`:
```bash
mkdir ~/.laconic-so
echo "distribution-url: https://github.com/cerc-io/stack-orchestrator/releases/latest/download/laconic-so" > ~/.laconic-so/config.yml"
```
### Update
If Stack Orchestrator was installed using the process described above, it is able to subsequently self-update to the current latest version by running:
```bash
laconic-so update
```
## Usage
@@ -40,7 +40,6 @@ services:
- fixturenet-eth-bootnode-geth
ports:
- "8545"
- "8546"
- "40000"
- "6060"
@@ -62,9 +61,6 @@ services:
- fixturenet-eth-bootnode-geth
volumes:
- fixturenet_eth_geth_2_data:/root/ethdata
ports:
- "8545"
- "8546"
fixturenet-eth-bootnode-lighthouse:
restart: always
@@ -70,7 +70,6 @@ services:
command: "/run-op-geth.sh"
ports:
- "0.0.0.0:8545:8545"
- "0.0.0.0:8546:8546"
healthcheck:
test: ["CMD", "nc", "-vz", "localhost:8545"]
interval: 30s
@@ -20,7 +20,7 @@ services:
- SYS_PTRACE
environment:
CERC_REMOTE_DEBUG: ${CERC_REMOTE_DEBUG:-true}
CERC_RUN_STATEDIFF: ${CERC_RUN_STATEDIFF:-detect}
CERC_RUN_STATEDIFF: "detect"
CERC_STATEDIFF_DB_NODE_ID: 1
CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG}
env_file:
@@ -38,7 +38,6 @@ services:
- fixturenet-eth-bootnode-geth
ports:
- "8545"
- "8546"
- "40000"
- "6060"
@@ -60,9 +59,6 @@ services:
- fixturenet-eth-bootnode-geth
volumes:
- fixturenet_plugeth_geth_2_data:/root/ethdata
ports:
- "8545"
- "8546"
fixturenet-eth-bootnode-lighthouse:
restart: always
@@ -1,49 +0,0 @@
version: '3.7'
services:
go-nitro:
image: cerc/go-nitro:local
hostname: go-nitro
restart: on-failure
depends_on:
# Wait for Nitro contracts to be deployed
nitro-contracts:
condition: service_completed_successfully
environment:
CERC_NITRO_CHAIN_URL: ${CERC_NITRO_CHAIN_URL:-ws://fixturenet-eth-geth-1:8546}
CERC_NITRO_PK: ${CERC_NITRO_PK:-2d999770f7b5d49b694080f987b82bbc9fc9ac2b4dcc10b0f8aba7d700f69c6d}
CERC_NITRO_CHAIN_PK: ${CERC_NITRO_CHAIN_PK:-570b909da9669b2f35a0b1ac70b8358516d55ae1b5b3710e95e9a94395090597}
CERC_NITRO_USE_DURABLE_STORE: ${CERC_NITRO_USE_DURABLE_STORE:-true}
CERC_NITRO_DURABLE_STORE_FOLDER: ${CERC_NITRO_DURABLE_STORE_FOLDER:-/app/data/nitro-store}
CERC_NA_ADDRESS: ${CERC_NA_ADDRESS}
CERC_VPA_ADDRESS: ${CERC_VPA_ADDRESS}
CERC_CA_ADDRESS: ${CERC_CA_ADDRESS}
entrypoint: ["bash", "-c", "/app/run-nitro-node.sh"]
volumes:
- go_nitro_data:/app/data
- nitro_deployment:/app/deployment
- ../config/go-nitro/run-nitro-node.sh:/app/run-nitro-node.sh
healthcheck:
test: ["CMD", "nc", "-vz", "localhost", "4005"]
interval: 10s
timeout: 5s
retries: 10
start_period: 10s
ports:
- "3005"
- "4005:4005"
- "5005:5005"
nitro-rpc-client:
image: cerc/nitro-rpc-client:local
hostname: nitro-rpc-client
restart: on-failure
depends_on:
# Wait for the go-nitro node to start
go-nitro:
condition: service_healthy
command: ["bash", "-c", "tail -f /dev/null"]
volumes:
go_nitro_data:
nitro_deployment:
@@ -6,6 +6,9 @@ services:
condition: service_healthy
ipfs:
condition: service_healthy
# Uncomment when running against fixturenet-lotus to wait for the Lotus node to come up
# lotus-node-1:
# condition: service_healthy
extra_hosts:
- host.docker.internal:host-gateway
environment:
@@ -15,13 +18,9 @@ services:
postgres_user: graph-node
postgres_pass: password
postgres_db: graph-node
ethereum: ${ETH_NETWORKS:-lotus-fixturenet:http://lotus-node-1:1234/rpc/v1}
ethereum: ${NETWORK:-filecoin}:${ETH_RPC_ENDPOINT:-https://archive.lotus.vdb.to/rpc/v1}
GRAPH_LOG: debug
ETHEREUM_REORG_THRESHOLD: 3
entrypoint: ["bash", "-c"]
# Wait for ETH RPC endpoint to be up when running with fixturenet-lotus
command: |
"wait_for ${ETH_RPC_HOST:-lotus-node-1}:${ETH_RPC_PORT:-1234} -t 1800 -- start"
ports:
- "8000"
- "8001"
@@ -1,45 +0,0 @@
version: '3.2'
services:
# Builds and serves the MobyMask v3 react-app
mobymask-v3-app:
restart: unless-stopped
image: cerc/mobymask-ui:local
env_file:
- ../config/watcher-mobymask-v3/mobymask-params.env
environment:
CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG}
CERC_CHAIN_ID: ${CERC_CHAIN_ID}
CERC_DEPLOYED_CONTRACT: ${CERC_DEPLOYED_CONTRACT}
CERC_RELAY_NODES: ${CERC_RELAY_NODES}
CERC_DENY_MULTIADDRS: ${CERC_DENY_MULTIADDRS}
CERC_PUBSUB: ${CERC_PUBSUB}
CERC_GOSSIPSUB_DIRECT_PEERS: ${CERC_GOSSIPSUB_DIRECT_PEERS}
CERC_NA_ADDRESS: ${CERC_NA_ADDRESS}
CERC_VPA_ADDRESS: ${CERC_VPA_ADDRESS}
CERC_CA_ADDRESS: ${CERC_CA_ADDRESS}
CERC_APP_WATCHER_URL: ${CERC_APP_WATCHER_URL}
CERC_PAYMENT_NITRO_ADDRESS: ${CERC_PAYMENT_NITRO_ADDRESS:-0xBBB676f9cFF8D242e9eaC39D063848807d3D1D94}
CERC_SNAP_URL: ${CERC_SNAP_URL}
working_dir: /app
command: ["bash", "/scripts/mobymask-app-start.sh"]
volumes:
- ../config/watcher-mobymask-v3/mobymask-app-start.sh:/scripts/mobymask-app-start.sh
- peers_ids:/peers
- mobymask_deployment:/server
- nitro_deployment:/nitro
ports:
- "127.0.0.1:3004:80"
healthcheck:
test: ["CMD", "nc", "-vz", "localhost", "80"]
interval: 20s
timeout: 5s
retries: 15
start_period: 10s
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
peers_ids:
mobymask_deployment:
nitro_deployment:
@@ -1,14 +0,0 @@
version: '3.7'
services:
mobymask-snap:
restart: unless-stopped
image: cerc/mobymask-snap:local
ports:
- "127.0.0.1:8080:8080"
healthcheck:
test: ["CMD", "nc", "-vz", "localhost", "8080"]
interval: 10s
timeout: 5s
retries: 10
start_period: 10s
@@ -1,23 +0,0 @@
version: '3.7'
services:
# Optionally deploys the Nitro contracts
nitro-contracts:
image: cerc/nitro-contracts:local
restart: on-failure
environment:
CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG}
CERC_ETH_RPC_ENDPOINT: ${CERC_ETH_RPC_ENDPOINT:-http://fixturenet-eth-geth-1:8545}
CERC_PRIVATE_KEY_DEPLOYER: ${CERC_PRIVATE_KEY_DEPLOYER:-0x888814df89c4358d7ddb3fa4b0213e7331239a80e1f013eaa7b2deca2a41a218}
CERC_NA_ADDRESS: ${CERC_NA_ADDRESS}
CERC_VPA_ADDRESS: ${CERC_VPA_ADDRESS}
CERC_CA_ADDRESS: ${CERC_CA_ADDRESS}
volumes:
- ../config/nitro-contracts/deploy.sh:/app/deploy.sh
- nitro_deployment:/app/deployment
command: ["bash", "-c", "/app/deploy.sh"]
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
nitro_deployment:
@@ -1,27 +0,0 @@
version: '3.7'
services:
nitro-reverse-payment-proxy:
image: cerc/go-nitro:local
hostname: nitro-reverse-payment-proxy
restart: on-failure
depends_on:
# Wait for the go-nitro node to start
go-nitro:
condition: service_healthy
environment:
CERC_PROXY_ADDRESS: 0.0.0.0:8081
CERC_PROXY_NITRO_ENDPOINT: ${CERC_PROXY_NITRO_ENDPOINT:-go-nitro:4005/api/v1}
CERC_PROXY_DESTINATION_URL: ${CERC_PROXY_DESTINATION_URL:-http://ipld-eth-server:8081}
CERC_PROXY_COST_PER_BYTE: ${CERC_PROXY_COST_PER_BYTE:-1}
entrypoint: ["bash", "-c", "/app/run-reverse-payment-proxy.sh"]
volumes:
- ../config/go-nitro/run-reverse-payment-proxy.sh:/app/run-reverse-payment-proxy.sh
healthcheck:
test: ["CMD", "nc", "-vz", "localhost", "8081"]
interval: 10s
timeout: 5s
retries: 10
start_period: 10s
ports:
- "8081:8081"
@@ -1,31 +0,0 @@
version: '3.7'
services:
ponder-app:
restart: unless-stopped
image: cerc/ponder:local
working_dir: /app/examples/token-erc20
environment:
CERC_PONDER_CHAIN_ID: ${PONDER_CHAIN_ID:-99}
CERC_PONDER_RPC_URL_1: ${PONDER_RPC_URL_1:-http://nitro-reverse-payment-proxy:8081}
CERC_PONDER_NITRO_PK: ${CERC_PONDER_NITRO_PK:-58368d20ff12f17669c06158c21d885897aa56f9be430edc789614bf9851d53f}
CERC_PONDER_NITRO_CHAIN_PK: ${CERC_PONDER_NITRO_CHAIN_PK:-fb1e9af328c283ca3e2486e7c24d13582b7912057d8b9542ff41503c85bc05c0}
CERC_PONDER_NITRO_CHAIN_URL: ${CERC_PONDER_NITRO_CHAIN_URL:-http://fixturenet-eth-geth-1:8546}
CERC_RELAY_MULTIADDR: ${CERC_RELAY_MULTIADDR}
CERC_UPSTREAM_NITRO_ADDRESS: ${CERC_UPSTREAM_NITRO_ADDRESS:-0xAAA6628Ec44A8a742987EF3A114dDFE2D4F7aDCE}
CERC_UPSTREAM_NITRO_MULTIADDR: ${CERC_UPSTREAM_NITRO_MULTIADDR:-/dns4/go-nitro/tcp/5005/ws/p2p/16Uiu2HAmSjXJqsyBJgcBUU2HQmykxGseafSatbpq5471XmuaUqyv}
CERC_UPSTREAM_NITRO_PAY_AMOUNT: ${CERC_UPSTREAM_NITRO_PAY_AMOUNT:-5000}
command: ["bash", "./ponder-start.sh"]
volumes:
- ../config/ponder/ponder-start.sh:/app/examples/token-erc20/ponder-start.sh
- ../config/ponder/ponder.config.ts:/app/examples/token-erc20/ponder.config.ts
- peers_ids:/peers
- nitro_deployment:/nitro
- ponder_nitro_data:/app/examples/token-erc20/.ponder/nitro-db
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
peers_ids:
nitro_deployment:
ponder_nitro_data:
-1
View File
@@ -4,7 +4,6 @@ services:
restart: always
environment:
CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG}
CERC_TEST_PARAM_1: ${CERC_TEST_PARAM_1:-FAILED}
volumes:
- test-data:/data
ports:
@@ -1,123 +0,0 @@
version: '3.2'
services:
# Starts the PostgreSQL database for watcher
mobymask-watcher-db:
restart: unless-stopped
image: postgres:14-alpine
environment:
- POSTGRES_USER=vdbm
- POSTGRES_MULTIPLE_DATABASES=mobymask-watcher,mobymask-watcher-job-queue
- POSTGRES_EXTENSION=mobymask-watcher-job-queue:pgcrypto
- POSTGRES_PASSWORD=password
volumes:
- ../config/postgresql/multiple-postgressql-databases.sh:/docker-entrypoint-initdb.d/multiple-postgressql-databases.sh
- mobymask_watcher_db_data:/var/lib/postgresql/data
ports:
- "127.0.0.1:15432:5432"
healthcheck:
test: ["CMD", "nc", "-v", "localhost", "5432"]
interval: 20s
timeout: 5s
retries: 15
start_period: 10s
# Deploys the MobyMask contract and generates an invite link
# Deployment is skipped if CERC_DEPLOYED_CONTRACT env is set
mobymask:
image: cerc/mobymask:local
working_dir: /app/packages/server
env_file:
- ../config/watcher-mobymask-v3/mobymask-params.env
environment:
CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG}
ENV: "PROD"
CERC_ETH_RPC_ENDPOINT: ${CERC_ETH_RPC_ENDPOINT}
CERC_PRIVATE_KEY_DEPLOYER: ${CERC_PRIVATE_KEY_DEPLOYER:-0x888814df89c4358d7ddb3fa4b0213e7331239a80e1f013eaa7b2deca2a41a218}
CERC_MOBYMASK_APP_BASE_URI: ${CERC_MOBYMASK_APP_BASE_URI}
CERC_DEPLOYED_CONTRACT: ${CERC_DEPLOYED_CONTRACT}
command: ["bash", "-c", "./deploy-and-generate-invite.sh"]
volumes:
- ../config/watcher-mobymask-v3/deploy-and-generate-invite.sh:/app/packages/server/deploy-and-generate-invite.sh
- mobymask_deployment:/app/packages/server
extra_hosts:
- "host.docker.internal:host-gateway"
# Creates peer-id files if they don't exist
peer-ids-gen:
image: cerc/watcher-ts:local
restart: on-failure
environment:
CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG}
working_dir: /app/packages/peer
command: ["sh", "generate-peer-ids.sh"]
volumes:
- ../config/watcher-mobymask-v2/generate-peer-ids.sh:/app/packages/peer/generate-peer-ids.sh
- peers_ids:/peer-ids
# Starts the MobyMask v3 watcher server
mobymask-watcher-server:
image: cerc/watcher-mobymask-v3:local
restart: unless-stopped
depends_on:
mobymask-watcher-db:
condition: service_healthy
peer-ids-gen:
condition: service_completed_successfully
mobymask:
condition: service_completed_successfully
nitro-contracts:
condition: service_completed_successfully
env_file:
- ../config/watcher-mobymask-v3/mobymask-params.env
environment:
CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG}
CERC_ETH_RPC_QUERY_ENDPOINT: ${CERC_ETH_RPC_QUERY_ENDPOINT}
CERC_ETH_RPC_MUTATION_ENDPOINT: ${CERC_ETH_RPC_MUTATION_ENDPOINT}
CERC_NITRO_CHAIN_URL: ${CERC_NITRO_CHAIN_URL}
CERC_RELAY_PEERS: ${CERC_RELAY_PEERS}
CERC_DENY_MULTIADDRS: ${CERC_DENY_MULTIADDRS}
CERC_PUBSUB: ${CERC_PUBSUB}
CERC_RELAY_ANNOUNCE_DOMAIN: ${CERC_RELAY_ANNOUNCE_DOMAIN}
CERC_ENABLE_PEER_L2_TXS: ${CERC_ENABLE_PEER_L2_TXS}
CERC_DEPLOYED_CONTRACT: ${CERC_DEPLOYED_CONTRACT}
CERC_NA_ADDRESS: ${CERC_NA_ADDRESS}
CERC_VPA_ADDRESS: ${CERC_VPA_ADDRESS}
CERC_CA_ADDRESS: ${CERC_CA_ADDRESS}
CERC_PRIVATE_KEY_PEER: ${CERC_PRIVATE_KEY_PEER:-111b7500bdce494d6f4bcfe8c2a0dde2ef92f751d9070fac6475dbd6d8021b3f}
CERC_WATCHER_NITRO_PK: ${CERC_WATCHER_NITRO_PK:-0279651921cd800ac560c21ceea27aab0107b67daf436cdd25ce84cad30159b4}
CERC_PEER_ID: ${CERC_PEER_ID}
CERC_ENABLE_UPSTREAM_PAYMENTS: ${CERC_ENABLE_UPSTREAM_PAYMENTS}
CERC_UPSTREAM_NITRO_ADDRESS: ${CERC_UPSTREAM_NITRO_ADDRESS:-0xAAA6628Ec44A8a742987EF3A114dDFE2D4F7aDCE}
CERC_UPSTREAM_NITRO_MULTIADDR: ${CERC_UPSTREAM_NITRO_MULTIADDR:-/dns4/go-nitro/tcp/5005/ws/p2p/16Uiu2HAmSjXJqsyBJgcBUU2HQmykxGseafSatbpq5471XmuaUqyv}
CERC_UPSTREAM_NITRO_PAY_AMOUNT: ${CERC_UPSTREAM_NITRO_PAY_AMOUNT:-5000}
command: ["bash", "./start-server.sh"]
volumes:
- ../config/watcher-mobymask-v3/watcher-config-template.toml:/app/environments/watcher-config-template.toml
- ../config/watcher-mobymask-v3/watcher-config-rates.toml:/app/environments/rates.toml
- ../config/watcher-mobymask-v3/keys:/app/keys
- ../config/watcher-mobymask-v3/start-server.sh:/app/start-server.sh
- watcher_nitro_data:/app/out/nitro-db
- peers_ids:/app/peers
- nitro_deployment:/nitro
- mobymask_deployment:/server
# Expose GQL, metrics and relay node ports
ports:
- "127.0.0.1:3001:3001"
- "127.0.0.1:9001:9001"
- "127.0.0.1:9090:9090"
healthcheck:
test: ["CMD", "busybox", "nc", "localhost", "9090"]
interval: 20s
timeout: 5s
retries: 15
start_period: 5s
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
mobymask_watcher_db_data:
peers_ids:
mobymask_deployment:
nitro_deployment:
watcher_nitro_data:
@@ -17,8 +17,8 @@ module.exports = {
whitelistedTokenAddresses: [
'NATIVE_ADDRESS',
],
stableTokenAddresses: [],
nativePricePool: '0x0000000000000000000000000000000000000000',
stableTokenAddresses: [
],
minimumEthLocked: 1.5
}
}
@@ -1,49 +0,0 @@
#!/bin/bash
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
nitro_addresses_file="/app/deployment/nitro-addresses.json"
# Check if CERC_NA_ADDRESS environment variable is set
if [ -n "$CERC_NA_ADDRESS" ]; then
echo "CERC_NA_ADDRESS is set to '$CERC_NA_ADDRESS'"
echo "CERC_VPA_ADDRESS is set to '$CERC_VPA_ADDRESS'"
echo "CERC_CA_ADDRESS is set to '$CERC_CA_ADDRESS'"
echo "Using the above Nitro addresses"
NA_ADDRESS=${CERC_NA_ADDRESS}
VPA_ADDRESS=${CERC_VPA_ADDRESS}
CA_ADDRESS=${CERC_CA_ADDRESS}
elif [ -f ${nitro_addresses_file} ]; then
echo "Reading Nitro addresses from ${nitro_addresses_file}"
NA_ADDRESS=$(jq -r '.nitroAdjudicatorAddress' ${nitro_addresses_file})
VPA_ADDRESS=$(jq -r '.virtualPaymentAppAddress' ${nitro_addresses_file})
CA_ADDRESS=$(jq -r '.consensusAppAddress' ${nitro_addresses_file})
else
echo "File ${nitro_addresses_file} not found"
exit 1
fi
echo "Running Nitro node"
# Wait till chain endpoint is available
retry_interval=5
while true; do
# Assuming CERC_NITRO_CHAIN_URL is of format <ws|http>://host:port
ws_host=$(echo "$CERC_NITRO_CHAIN_URL" | awk -F '://' '{print $2}' | cut -d ':' -f 1)
ws_port=$(echo "$CERC_NITRO_CHAIN_URL" | awk -F '://' '{print $2}' | cut -d ':' -f 2)
nc -z -w 1 "$ws_host" "$ws_port"
if [ $? -eq 0 ]; then
echo "Chain endpoint is available"
break
fi
echo "Chain endpoint not yet available, retrying in $retry_interval seconds..."
sleep $retry_interval
done
./nitro -chainurl ${CERC_NITRO_CHAIN_URL} -msgport 3005 -rpcport 4005 -wsmsgport 5005 -pk ${CERC_NITRO_PK} -chainpk ${CERC_NITRO_CHAIN_PK} -naaddress ${NA_ADDRESS} -vpaaddress ${VPA_ADDRESS} -caaddress ${CA_ADDRESS} -usedurablestore ${CERC_NITRO_USE_DURABLE_STORE} -durablestorefolder ${CERC_NITRO_DURABLE_STORE_FOLDER}
@@ -1,14 +0,0 @@
#!/bin/bash
set -e
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
echo "Running Nitro reverse payment proxy"
echo "Using CERC_PROXY_ADDRESS ${CERC_PROXY_ADDRESS}"
echo "Using CERC_PROXY_NITRO_ENDPOINT ${CERC_PROXY_NITRO_ENDPOINT}"
echo "Using CERC_PROXY_DESTINATION_URL ${CERC_PROXY_DESTINATION_URL}"
echo "Using CERC_PROXY_COST_PER_BYTE ${CERC_PROXY_COST_PER_BYTE}"
./proxy -proxyaddress ${CERC_PROXY_ADDRESS} -nitroendpoint=${CERC_PROXY_NITRO_ENDPOINT} -destinationurl=${CERC_PROXY_DESTINATION_URL} -costperbyte ${CERC_PROXY_COST_PER_BYTE} -enablepaidrpcmethods
File diff suppressed because it is too large Load Diff
@@ -10,13 +10,6 @@ scrape_configs:
static_configs:
- targets: ['mainnet-eth-geth-1:6060']
# lighthouse
- job_name: 'lighthouse'
metrics_path: /metrics
scheme: http
static_configs:
- targets: ['mainnet-eth-lighthouse-1:5054']
# keycloak
- job_name: 'keycloak'
scrape_interval: 5s
-57
View File
@@ -1,57 +0,0 @@
#!/bin/bash
set -e
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
nitro_addresses_file="/app/deployment/nitro-addresses.json"
# Check if CERC_NA_ADDRESS environment variable set to skip contract deployment
if [ -n "$CERC_NA_ADDRESS" ]; then
echo "CERC_NA_ADDRESS is set to '$CERC_NA_ADDRESS'"
echo "CERC_VPA_ADDRESS is set to '$CERC_VPA_ADDRESS'"
echo "CERC_CA_ADDRESS is set to '$CERC_CA_ADDRESS'"
echo "Skipping Nitro contracts deployment"
exit
fi
# Check and exit if a deployment already exists (on restarts)
if [ -f ${nitro_addresses_file} ]; then
echo "${nitro_addresses_file} already exists, skipping Nitro contracts deployment"
cat ${nitro_addresses_file}
exit
fi
echo "Using ETH RPC endpoint ${CERC_ETH_RPC_ENDPOINT}"
# Wait till ETH RPC endpoint is available with block number > 1
retry_interval=5
while true; do
block_number_hex=$(curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' ${CERC_ETH_RPC_ENDPOINT} | jq -r '.result')
# Check if the request call was successful
if [ $? -ne 0 ]; then
echo "RPC endpoint not yet available, retrying in $retry_interval seconds..."
sleep $retry_interval
continue
fi
# Convert hex to decimal
block_number_dec=$(printf %u ${block_number_hex})
# Check if block number is > 1 to avoid failures in the deployment
if [ "$block_number_dec" -ge 1 ]; then
echo "RPC endpoint is up"
break
else
echo "RPC endpoint not yet available, retrying in $retry_interval seconds..."
sleep $retry_interval
continue
fi
done
echo "Using CERC_PRIVATE_KEY_DEPLOYER from env"
yarn test:deploy-contracts --chainUrl ${CERC_ETH_RPC_ENDPOINT} --key ${CERC_PRIVATE_KEY_DEPLOYER} --addressesFilePath ${nitro_addresses_file}
cat ${nitro_addresses_file}
-60
View File
@@ -1,60 +0,0 @@
#!/bin/bash
set -e
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
nitro_addresses_file="/nitro/nitro-addresses.json"
nitro_addresses_destination_file="/app/examples/token-erc20/nitro-addresses.json"
# Check if CERC_NA_ADDRESS environment variable is set
if [ -n "$CERC_NA_ADDRESS" ]; then
echo "CERC_NA_ADDRESS is set to '$CERC_NA_ADDRESS'"
echo "CERC_VPA_ADDRESS is set to '$CERC_VPA_ADDRESS'"
echo "CERC_CA_ADDRESS is set to '$CERC_CA_ADDRESS'"
echo "Using the above Nitro addresses"
# Create the required JSON and write it to a file
nitro_addresses_json=$(jq -n \
--arg na "$CERC_NA_ADDRESS" \
--arg vpa "$CERC_VPA_ADDRESS" \
--arg ca "$CERC_CA_ADDRESS" \
'.nitroAdjudicatorAddress = $na | .virtualPaymentAppAddress = $vpa | .consensusAppAddress = $ca')
echo "$nitro_addresses_json" > "${nitro_addresses_destination_file}"
elif [ -f ${nitro_addresses_file} ]; then
echo "Using Nitro addresses from ${nitro_addresses_file}:"
cat "$nitro_addresses_file"
cat "$nitro_addresses_file" > "$nitro_addresses_destination_file"
else
echo "Nitro addresses not available"
exit 1
fi
echo "Using CERC_PONDER_NITRO_PK from env for Nitro account"
echo "Using CERC_PONDER_NITRO_CHAIN_PK (account with funds) from env for sending Nitro txs"
echo "Using ${CERC_PONDER_NITRO_CHAIN_URL} as the RPC endpoint for Nitro txs"
# If not set, check the mounted volume for relay peer id
if [ -z "$CERC_RELAY_MULTIADDR" ]; then
echo "CERC_RELAY_MULTIADDR not provided, taking from the mounted volume"
CERC_RELAY_MULTIADDR="/dns4/mobymask-watcher-server/tcp/9090/ws/p2p/$(jq -r '.id' /peers/relay-id.json)"
fi
env_file='.env.local'
echo "PONDER_TELEMETRY_DISABLED=true" > "$env_file"
echo "PONDER_LOG_LEVEL=debug" >> "$env_file"
echo "PONDER_CHAIN_ID=\"$CERC_PONDER_CHAIN_ID\"" >> "$env_file"
echo "PONDER_RPC_URL_1=\"$CERC_PONDER_RPC_URL_1\"" >> "$env_file"
echo "PONDER_NITRO_PK=\"$CERC_PONDER_NITRO_PK\"" >> "$env_file"
echo "PONDER_NITRO_CHAIN_PK=\"$CERC_PONDER_NITRO_CHAIN_PK\"" >> "$env_file"
echo "PONDER_NITRO_CHAIN_URL=\"$CERC_PONDER_NITRO_CHAIN_URL\"" >> "$env_file"
echo "RELAY_MULTIADDR=\"$CERC_RELAY_MULTIADDR\"" >> "$env_file"
echo "UPSTREAM_NITRO_ADDRESS=\"$CERC_UPSTREAM_NITRO_ADDRESS\"" >> "$env_file"
echo "UPSTREAM_NITRO_MULTIADDR=\"$CERC_UPSTREAM_NITRO_MULTIADDR\"" >> "$env_file"
echo "UPSTREAM_NITRO_PAY_AMOUNT=\"$CERC_UPSTREAM_NITRO_PAY_AMOUNT\"" >> "$env_file"
cat "$env_file"
# Keep the container running
tail -f
-50
View File
@@ -1,50 +0,0 @@
import type { Config } from "@ponder/core";
import contractAddresses from "./nitro-addresses.json";
export const config: Config = {
networks: [
{
name: "fixturenet",
chainId: Number(process.env.PONDER_CHAIN_ID),
rpcUrl: process.env.PONDER_RPC_URL_1,
maxRpcRequestConcurrency: 1,
pollingInterval: 5000,
payments: {
nitro: {
address: process.env.UPSTREAM_NITRO_ADDRESS!,
multiAddr: process.env.UPSTREAM_NITRO_MULTIADDR!,
fundingAmounts: {
// TODO: Pass amounts from env
directFund: "1000000000000",
virtualFund: "1000000000",
},
},
paidRPCMethods: [
"eth_getLogs",
"eth_getBlockByNumber",
"eth_getBlockByHash",
],
amount: process.env.UPSTREAM_NITRO_PAY_AMOUNT!,
},
},
],
contracts: [
{
name: "AdventureGold",
network: "fixturenet",
abi: "./abis/AdventureGold.json",
address: "0x32353A6C91143bfd6C7d363B546e62a9A2489A20",
startBlock: 5,
maxBlockRange: 100,
},
],
nitro: {
privateKey: process.env.PONDER_NITRO_PK!,
chainPrivateKey: process.env.PONDER_NITRO_CHAIN_PK!,
chainUrl: process.env.PONDER_NITRO_CHAIN_URL!,
contractAddresses,
relayMultiAddr: process.env.RELAY_MULTIADDR!,
store: "./.ponder/nitro-db",
},
};
@@ -1,78 +0,0 @@
#!/bin/bash
set -e
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
CERC_ETH_RPC_ENDPOINT="${CERC_ETH_RPC_ENDPOINT:-${DEFAULT_CERC_ETH_RPC_ENDPOINT}}"
CERC_MOBYMASK_APP_BASE_URI="${CERC_MOBYMASK_APP_BASE_URI:-${DEFAULT_CERC_MOBYMASK_APP_BASE_URI}}"
CERC_DEPLOYED_CONTRACT="${CERC_DEPLOYED_CONTRACT:-${DEFAULT_CERC_DEPLOYED_CONTRACT}}"
# Check if CERC_DEPLOYED_CONTRACT environment variable set to skip contract deployment
if [ -n "$CERC_DEPLOYED_CONTRACT" ]; then
echo "CERC_DEPLOYED_CONTRACT is set to '$CERC_DEPLOYED_CONTRACT'"
echo "Skipping contract deployment"
exit 0
fi
echo "Using ETH RPC endpoint ${CERC_ETH_RPC_ENDPOINT}"
# Wait till ETH RPC endpoint is available with block number > 1
retry_interval=5
while true; do
block_number_hex=$(curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' ${CERC_ETH_RPC_ENDPOINT} | jq -r '.result')
# Check if the request call was successful
if [ $? -ne 0 ]; then
echo "RPC endpoint not yet available, retrying in $retry_interval seconds..."
sleep $retry_interval
continue
fi
# Convert hex to decimal
block_number_dec=$(printf %u ${block_number_hex})
# Check if block number is > 1 to avoid failures in the deployment
if [ "$block_number_dec" -ge 1 ]; then
echo "RPC endpoint is up"
break
else
echo "RPC endpoint not yet available, retrying in $retry_interval seconds..."
sleep $retry_interval
continue
fi
done
echo "Using CERC_PRIVATE_KEY_DEPLOYER from env"
# Create the required JSON and write it to a file
secrets_file="secrets.json"
secrets_json=$(jq -n \
--arg privateKey "$CERC_PRIVATE_KEY_DEPLOYER" \
--arg rpcUrl "$CERC_ETH_RPC_ENDPOINT" \
--arg baseURI "$CERC_MOBYMASK_APP_BASE_URI" \
'.privateKey = $privateKey | .rpcUrl = $rpcUrl | .baseURI = $baseURI')
echo "$secrets_json" > "${secrets_file}"
export RPC_URL="${CERC_ETH_RPC_ENDPOINT}"
# Check and exit if a deployment already exists (on restarts)
if [ -f ./config.json ]; then
echo "config.json already exists, checking the contract deployment"
# Read JSON file
deployment_details=$(cat config.json)
deployed_contract=$(echo "$deployment_details" | jq -r '.address')
cd ../hardhat
if yarn verifyDeployment --network optimism --contract "${deployed_contract}"; then
echo "Deployment verfication successful"
cd ../server
else
echo "Deployment verfication failed, please clear MobyMask deployment volume before starting"
exit 1
fi
fi
npm run deployAndGenerateInvite
@@ -1,11 +0,0 @@
{
"peerId": {
"id": "12D3KooWAMjBkFCT9DtCnSDcxftxJzSuTBvzVojabv64cnEvX4AZ",
"privKey": "CAESQAKCrnY0QKTky1I18fqn+VPydXGUv1NYiV+nVKqBFkw/CAjE9sKKIDGnYAo8mivnI6dngFenERY+0Q8AJrPTaXY=",
"pubKey": "CAESIAgIxPbCiiAxp2AKPJor5yOnZ4BXpxEWPtEPACaz02l2"
},
"consensus": {
"publicKey": "02cd17b05ca998955be5ca7bf4fd4531243d438f1aae7ce8a0ed5159f53cee5b40",
"privateKey": "67d80505614bdf61fca11cbad31d93acb2c7df1c653dc25975d77d05f05f154f"
}
}
@@ -1,11 +0,0 @@
{
"peerId": {
"id": "12D3KooWBNEbY3QS4y23ngupDw9PDc4bvNvRJGVRejjV9EZLjux5",
"privKey": "CAESQGSTw0ymvn8+wX9Dbvyr4/Gib1q2voe0CC0VyeClMQP6FwW14x0fpRbBIx0XhLdxWHkRndphVg3gVAHyC+7ZI8o=",
"pubKey": "CAESIBcFteMdH6UWwSMdF4S3cVh5EZ3aYVYN4FQB8gvu2SPK"
},
"consensus": {
"publicKey": "029c8035b3e9401b8f178f7c37285b5cb22501e017340e2058b3b842f2a1f0ae45",
"privateKey": "0261008e8e3ec808168e99333599da38ca59a056a2ae4510a6ad3d8b5cb0918c"
}
}
@@ -1,11 +0,0 @@
{
"peerId": {
"id": "12D3KooWSRH6ftgkAZsKZK7UX1Zr6Hx6YAsEepHqzopFszqfTxxi",
"privKey": "CAESQHBjlHxfVhZ2gXsBItrIEEgSGKcjMkFiGs3PPz9E3ace9qyWEkvR4oit5ve9SAROVoh20hoa42IC91NIafMaqws=",
"pubKey": "CAESIPaslhJL0eKIreb3vUgETlaIdtIaGuNiAvdTSGnzGqsL"
},
"consensus": {
"publicKey": "039160c244a7ad8be16a64bdb69e6dbacdcfe20b37076792a0d06032a8097468ca",
"privateKey": "8894685fe81001d75662b079905472699373967451d1255ee5fc669d0a09a9ca"
}
}
@@ -1,86 +0,0 @@
#!/bin/bash
set -e
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
CERC_CHAIN_ID="${CERC_CHAIN_ID:-${DEFAULT_CERC_CHAIN_ID}}"
CERC_DEPLOYED_CONTRACT="${CERC_DEPLOYED_CONTRACT:-${DEFAULT_CERC_DEPLOYED_CONTRACT}}"
CERC_RELAY_NODES="${CERC_RELAY_NODES:-${DEFAULT_CERC_RELAY_NODES}}"
CERC_DENY_MULTIADDRS="${CERC_DENY_MULTIADDRS:-${DEFAULT_CERC_DENY_MULTIADDRS}}"
CERC_PUBSUB="${CERC_PUBSUB:-${DEFAULT_CERC_PUBSUB}}"
CERC_GOSSIPSUB_DIRECT_PEERS="${CERC_GOSSIPSUB_DIRECT_PEERS:-${DEFAULT_CERC_GOSSIPSUB_DIRECT_PEERS}}"
CERC_APP_WATCHER_URL="${CERC_APP_WATCHER_URL:-${DEFAULT_CERC_APP_WATCHER_URL}}"
CERC_SNAP_URL="${CERC_SNAP_URL:-${DEFAULT_CERC_SNAP_URL}}"
# If not set (or []), check the mounted volume for relay peer id
if [ -z "$CERC_RELAY_NODES" ] || [ "$CERC_RELAY_NODES" = "[]" ]; then
echo "CERC_RELAY_NODES not provided, taking from the mounted volume"
CERC_RELAY_NODES="[\"/ip4/127.0.0.1/tcp/9090/ws/p2p/$(jq -r '.id' /peers/relay-id.json)\"]"
fi
echo "Using CERC_RELAY_NODES $CERC_RELAY_NODES"
if [ -z "$CERC_DEPLOYED_CONTRACT" ]; then
# Use config from mounted volume (when running web-app along with watcher stack)
echo "Taking config for deployed contract from mounted volume"
while [ ! -f /server/config.json ]; do
echo "Config not found, retrying in 5 seconds..."
sleep 5
done
# Get deployed contract address and chain id
CERC_DEPLOYED_CONTRACT=$(jq -r '.address' /server/config.json | tr -d '"')
CERC_CHAIN_ID=$(jq -r '.chainId' /server/config.json)
else
echo "Using CERC_DEPLOYED_CONTRACT ${CERC_DEPLOYED_CONTRACT} from env as the MobyMask contract address"
fi
nitro_addresses_file="/nitro/nitro-addresses.json"
nitro_addresses_destination_file="/app/src/utils/nitro-addresses.json"
# Check if CERC_NA_ADDRESS environment variable is set
if [ -n "$CERC_NA_ADDRESS" ]; then
echo "CERC_NA_ADDRESS is set to '$CERC_NA_ADDRESS'"
echo "CERC_VPA_ADDRESS is set to '$CERC_VPA_ADDRESS'"
echo "CERC_CA_ADDRESS is set to '$CERC_CA_ADDRESS'"
echo "Using the above Nitro addresses"
# Create the required JSON and write it to a file
nitro_addresses_json=$(jq -n \
--arg na "$CERC_NA_ADDRESS" \
--arg vpa "$CERC_VPA_ADDRESS" \
--arg ca "$CERC_CA_ADDRESS" \
'.nitroAdjudicatorAddress = $na | .virtualPaymentAppAddress = $vpa | .consensusAppAddress = $ca')
echo "$nitro_addresses_json" > "${nitro_addresses_destination_file}"
elif [ -f ${nitro_addresses_file} ]; then
echo "Using Nitro addresses from ${nitro_addresses_file}:"
cat "$nitro_addresses_file"
cat "$nitro_addresses_file" > "$nitro_addresses_destination_file"
else
echo "Nitro addresses not available"
exit 1
fi
# Export config values in a json file
app_config_file="/app/src/utils/config.json"
app_config_json=$(jq -n \
--arg name "MobyMask" \
--argjson enableDebugInfo true \
--arg address "$CERC_DEPLOYED_CONTRACT" \
--argjson chainId "$CERC_CHAIN_ID" \
--argjson relayNodes "$CERC_RELAY_NODES" \
--argjson denyMultiaddrs "$CERC_DENY_MULTIADDRS" \
--arg pubsub "$CERC_PUBSUB" \
--argjson directPeers "$CERC_GOSSIPSUB_DIRECT_PEERS" \
'.name = $name | .address = $address | .chainId = $chainId | .relayNodes = $relayNodes | .peer.enableDebugInfo = $enableDebugInfo | .peer.denyMultiaddrs = $denyMultiaddrs | .peer.pubsub = $pubsub | .peer.directPeers = $directPeers')
echo "$app_config_json" > "${app_config_file}"
REACT_APP_DEBUG_PEER=true \
REACT_APP_WATCHER_URI="$CERC_APP_WATCHER_URL/graphql" \
REACT_APP_PAY_TO_NITRO_ADDRESS="$CERC_PAYMENT_NITRO_ADDRESS" \
REACT_APP_SNAP_ORIGIN="local:$CERC_SNAP_URL" \
yarn build
http-server -p 80 /app/build
@@ -1,53 +0,0 @@
# Defaults
# ETH RPC endpoint used for contract(s) deployment
DEFAULT_CERC_ETH_RPC_ENDPOINT="http://fixturenet-eth-geth-1:8545"
# ETH RPC endpoint used for queries in the watcher
DEFAULT_CERC_ETH_RPC_QUERY_ENDPOINT="http://nitro-reverse-payment-proxy:8081"
# ETH RPC endpoint used for mutations in the watcher
DEFAULT_CERC_ETH_RPC_MUTATION_ENDPOINT="http://fixturenet-eth-geth-1:8545"
# ETH endpoint used by watcher's Nitro node
DEFAULT_CERC_NITRO_CHAIN_URL="http://fixturenet-eth-geth-1:8546"
# Set of relay peers to connect to from the relay node
DEFAULT_CERC_RELAY_PEERS=[]
# Domain to be used in the relay node's announce address
DEFAULT_CERC_RELAY_ANNOUNCE_DOMAIN=
# Base URI for mobymask-app (used for generating invite)
DEFAULT_CERC_MOBYMASK_APP_BASE_URI="http://127.0.0.1:3004/#"
# Set to false for disabling watcher peer to send txs to L2
DEFAULT_CERC_ENABLE_PEER_L2_TXS=true
# Set deployed MobyMask contract address to avoid deploying contract in stack
# mobymask-app will use this contract address in config if run separately
DEFAULT_CERC_DEPLOYED_CONTRACT=
# Chain ID is used by mobymask web-app for txs
DEFAULT_CERC_CHAIN_ID=1212
# Watcher endpoint used by the web-app
DEFAULT_CERC_APP_WATCHER_URL="http://localhost:3001"
# MobyMask snap URL to be used by the web-app
DEFAULT_CERC_SNAP_URL=http://localhost:8080
# Set of relay nodes to be used by web-apps
DEFAULT_CERC_RELAY_NODES=[]
# Set of multiaddrs to be avoided while dialling
DEFAULT_CERC_DENY_MULTIADDRS=[]
# Type of pubsub to be used
DEFAULT_CERC_PUBSUB=""
# Set of direct peers to be used when pubsub is set to gossipsub
DEFAULT_CERC_GOSSIPSUB_DIRECT_PEERS=[]
# Whether to enable payments to upstream ETH server
DEFAULT_CERC_ENABLE_UPSTREAM_PAYMENTS=true
@@ -1,166 +0,0 @@
#!/bin/bash
set -e
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
CERC_ETH_RPC_QUERY_ENDPOINT="${CERC_ETH_RPC_QUERY_ENDPOINT:-${DEFAULT_CERC_ETH_RPC_QUERY_ENDPOINT}}"
CERC_ETH_RPC_MUTATION_ENDPOINT="${CERC_ETH_RPC_MUTATION_ENDPOINT:-${DEFAULT_CERC_ETH_RPC_MUTATION_ENDPOINT}}"
CERC_NITRO_CHAIN_URL="${CERC_NITRO_CHAIN_URL:-${DEFAULT_CERC_NITRO_CHAIN_URL}}"
CERC_RELAY_PEERS="${CERC_RELAY_PEERS:-${DEFAULT_CERC_RELAY_PEERS}}"
CERC_DENY_MULTIADDRS="${CERC_DENY_MULTIADDRS:-${DEFAULT_CERC_DENY_MULTIADDRS}}"
CERC_PUBSUB="${CERC_PUBSUB:-${DEFAULT_CERC_PUBSUB}}"
CERC_RELAY_ANNOUNCE_DOMAIN="${CERC_RELAY_ANNOUNCE_DOMAIN:-${DEFAULT_CERC_RELAY_ANNOUNCE_DOMAIN}}"
CERC_ENABLE_PEER_L2_TXS="${CERC_ENABLE_PEER_L2_TXS:-${DEFAULT_CERC_ENABLE_PEER_L2_TXS}}"
CERC_DEPLOYED_CONTRACT="${CERC_DEPLOYED_CONTRACT:-${DEFAULT_CERC_DEPLOYED_CONTRACT}}"
CERC_ENABLE_UPSTREAM_PAYMENTS="${CERC_ENABLE_UPSTREAM_PAYMENTS:-${DEFAULT_CERC_ENABLE_UPSTREAM_PAYMENTS}}"
watcher_keys_dir="./keys"
echo "Using RPC query endpoint ${CERC_ETH_RPC_QUERY_ENDPOINT}"
echo "Using RPC mutation endpoint ${CERC_ETH_RPC_MUTATION_ENDPOINT}"
echo "Using Nitro chain URL ${CERC_NITRO_CHAIN_URL}"
# Use public domain for relay multiaddr in peer config if specified
# Otherwise, use the docker container's host IP
if [ -n "$CERC_RELAY_ANNOUNCE_DOMAIN" ]; then
CERC_RELAY_MULTIADDR="/dns4/${CERC_RELAY_ANNOUNCE_DOMAIN}/tcp/443/wss/p2p/$(jq -r '.id' /app/peers/relay-id.json)"
else
CERC_RELAY_MULTIADDR="/dns4/mobymask-watcher-server/tcp/9090/ws/p2p/$(jq -r '.id' /app/peers/relay-id.json)"
fi
# Use contract address from environment variable or set from config.json in mounted volume
if [ -n "$CERC_DEPLOYED_CONTRACT" ]; then
CONTRACT_ADDRESS="${CERC_DEPLOYED_CONTRACT}"
else
# Assign deployed contract address from server config (created by mobymask container after deploying contract)
CONTRACT_ADDRESS=$(jq -r '.address' /server/config.json | tr -d '"')
fi
nitro_addresses_file="/nitro/nitro-addresses.json"
nitro_addresses_destination_file="./src/nitro-addresses.json"
# Check if CERC_NA_ADDRESS environment variable is set
if [ -n "$CERC_NA_ADDRESS" ]; then
echo "CERC_NA_ADDRESS is set to '$CERC_NA_ADDRESS'"
echo "CERC_VPA_ADDRESS is set to '$CERC_VPA_ADDRESS'"
echo "CERC_CA_ADDRESS is set to '$CERC_CA_ADDRESS'"
echo "Using the above Nitro addresses"
# Create the required JSON and write it to a file
nitro_addresses_json=$(jq -n \
--arg na "$CERC_NA_ADDRESS" \
--arg vpa "$CERC_VPA_ADDRESS" \
--arg ca "$CERC_CA_ADDRESS" \
'.nitroAdjudicatorAddress = $na | .virtualPaymentAppAddress = $vpa | .consensusAppAddress = $ca')
echo "$nitro_addresses_json" > "${nitro_addresses_destination_file}"
elif [ -f ${nitro_addresses_file} ]; then
echo "Using Nitro addresses from ${nitro_addresses_file}:"
cat "$nitro_addresses_file"
cat "$nitro_addresses_file" > "$nitro_addresses_destination_file"
else
echo "Nitro addresses not available"
exit 1
fi
# Build after setting the Nitro addresses
yarn build
echo "Using CERC_PRIVATE_KEY_PEER (account with funds) from env for sending txs to L2"
echo "Using CERC_WATCHER_NITRO_PK from env for Nitro account"
if [ -n "$CERC_PEER_ID" ]; then
echo "Using CERC_PEER_ID ${CERC_PEER_ID} from env for watcher fixture"
echo "Consensus module enabled"
# Set corresponding variables
PEER_ID_FILE='./peer-id.json'
CONSENSUS_ENABLED=true
WATCHER_PARTY_PEERS_FILE='./watcher-party-peers.json'
# Create watcher party array
watcher_parties=()
# Iterate over each fixture JSON file
for peer_data_file in "$watcher_keys_dir"/*.json; do
# Extract the filename without the path and extension
peer_id=$(basename "$peer_data_file" .json)
# Read the consensus keys
consensus_public_key=$(jq -r '.consensus.publicKey' "$peer_data_file")
consensus_private_key=$(jq -r '.consensus.privateKey' "$peer_data_file")
# Append watcher party
watcher_party=$(jq -n \
--arg peerId "$peer_id" \
--arg publicKey "$consensus_public_key" \
'.peerId = $peerId | .publicKey = $publicKey')
watcher_parties+=("$watcher_party")
if [ "$peer_id" = "$CERC_PEER_ID" ]; then
# Export peer id
peer_id_data=$(jq '.peerId' "$peer_data_file")
echo "$peer_id_data" > "${PEER_ID_FILE}"
# Set consensus keys for this peer
CONSENSUS_PUBLIC_KEY=${consensus_public_key}
CONSENSUS_PRIVATE_KEY=${consensus_private_key}
fi
done
# Export watcher party file
watcher_parties_json=$(printf '%s\n' "${watcher_parties[@]}" | jq -s .)
echo "$watcher_parties_json" > "${WATCHER_PARTY_PEERS_FILE}"
echo "Watcher party peers exported to ${WATCHER_PARTY_PEERS_FILE}"
else
echo "Using generated peer id"
echo "Consensus module disabled"
# Set corresponding variables
PEER_ID_FILE='./peers/peer-id.json'
CONSENSUS_ENABLED=false
WATCHER_PARTY_PEERS_FILE=''
CONSENSUS_PUBLIC_KEY=''
CONSENSUS_PRIVATE_KEY=''
fi
if [ "$CERC_ENABLE_UPSTREAM_PAYMENTS" = true ]; then
UPSTREAM_NITRO_ADDRESS=${CERC_UPSTREAM_NITRO_ADDRESS}
UPSTREAM_NITRO_MULTIADDR=${CERC_UPSTREAM_NITRO_MULTIADDR}
UPSTREAM_NITRO_PAY_AMOUNT=${CERC_UPSTREAM_NITRO_PAY_AMOUNT}
else
UPSTREAM_NITRO_ADDRESS=""
UPSTREAM_NITRO_MULTIADDR=""
UPSTREAM_NITRO_PAY_AMOUNT=""
fi
# Read in the config template TOML file and modify it
WATCHER_CONFIG_TEMPLATE=$(cat environments/watcher-config-template.toml)
WATCHER_CONFIG=$(echo "$WATCHER_CONFIG_TEMPLATE" | \
sed -E "s|REPLACE_WITH_CERC_RELAY_PEERS|${CERC_RELAY_PEERS}|g; \
s|REPLACE_WITH_CERC_DENY_MULTIADDRS|${CERC_DENY_MULTIADDRS}|g; \
s/REPLACE_WITH_CERC_PUBSUB/${CERC_PUBSUB}/g; \
s/REPLACE_WITH_CERC_RELAY_ANNOUNCE_DOMAIN/${CERC_RELAY_ANNOUNCE_DOMAIN}/g; \
s|REPLACE_WITH_CERC_RELAY_MULTIADDR|${CERC_RELAY_MULTIADDR}|g; \
s|REPLACE_WITH_PEER_ID_FILE|${PEER_ID_FILE}|g; \
s/REPLACE_WITH_CERC_ENABLE_PEER_L2_TXS/${CERC_ENABLE_PEER_L2_TXS}/g; \
s/REPLACE_WITH_CERC_PRIVATE_KEY_PEER/${CERC_PRIVATE_KEY_PEER}/g; \
s/REPLACE_WITH_CERC_WATCHER_NITRO_PK/${CERC_WATCHER_NITRO_PK}/g; \
s/REPLACE_WITH_CONTRACT_ADDRESS/${CONTRACT_ADDRESS}/g; \
s|REPLACE_WITH_CERC_NITRO_CHAIN_URL|${CERC_NITRO_CHAIN_URL}|g; \
s/REPLACE_WITH_CONSENSUS_ENABLED/${CONSENSUS_ENABLED}/g; \
s/REPLACE_WITH_CONSENSUS_PUBLIC_KEY/${CONSENSUS_PUBLIC_KEY}/g; \
s/REPLACE_WITH_CONSENSUS_PRIVATE_KEY/${CONSENSUS_PRIVATE_KEY}/g; \
s|REPLACE_WITH_WATCHER_PARTY_PEERS_FILE|${WATCHER_PARTY_PEERS_FILE}|g; \
s|REPLACE_WITH_CERC_ETH_RPC_QUERY_ENDPOINT|${CERC_ETH_RPC_QUERY_ENDPOINT}|g; \
s|REPLACE_WITH_CERC_ETH_RPC_MUTATION_ENDPOINT|${CERC_ETH_RPC_MUTATION_ENDPOINT}|g; \
s/REPLACE_WITH_UPSTREAM_NITRO_ADDRESS/${UPSTREAM_NITRO_ADDRESS}/g; \
s|REPLACE_WITH_UPSTREAM_NITRO_MULTIADDR|${UPSTREAM_NITRO_MULTIADDR}|g; \
s/REPLACE_WITH_UPSTREAM_NITRO_PAY_AMOUNT/${UPSTREAM_NITRO_PAY_AMOUNT}/ ")
# Write the modified content to a new file
echo "$WATCHER_CONFIG" > environments/local.toml
echo 'yarn server'
yarn server
@@ -1,14 +0,0 @@
freeQueriesLimit = 10
freeQueriesList = []
[queries]
multiNonce = '50'
_owner = '50'
isRevoked = '50'
isPhisher = '50'
isMember = '50'
[mutations]
invoke = '100'
revoke = '100'
@@ -1,123 +0,0 @@
[server]
host = "0.0.0.0"
port = 3001
kind = "lazy"
# Checkpointing state.
checkpointing = true
# Checkpoint interval in number of blocks.
checkpointInterval = 2000
# Enable state creation
enableState = true
# Boolean to filter logs by contract.
filterLogs = true
# Max block range for which to return events in eventsInRange GQL query.
# Use -1 for skipping check on block range.
maxEventsBlockRange = -1
# Flag to specify whether RPC endpoint supports block hash as block tag parameter
rpcSupportsBlockHashParam = true
[server.p2p]
enableRelay = true
enablePeer = true
[server.p2p.relay]
host = "0.0.0.0"
port = 9090
relayPeers = REPLACE_WITH_CERC_RELAY_PEERS
denyMultiaddrs = REPLACE_WITH_CERC_DENY_MULTIADDRS
peerIdFile = './peers/relay-id.json'
announce = 'REPLACE_WITH_CERC_RELAY_ANNOUNCE_DOMAIN'
pubsub = 'REPLACE_WITH_CERC_PUBSUB'
enableDebugInfo = true
[server.p2p.peer]
relayMultiaddr = 'REPLACE_WITH_CERC_RELAY_MULTIADDR'
pubSubTopic = 'mobymask'
denyMultiaddrs = REPLACE_WITH_CERC_DENY_MULTIADDRS
peerIdFile = 'REPLACE_WITH_PEER_ID_FILE'
pubsub = 'REPLACE_WITH_CERC_PUBSUB'
enableDebugInfo = true
enableL2Txs = REPLACE_WITH_CERC_ENABLE_PEER_L2_TXS
pingInterval = 4000
pingTimeout = 1500
maxRelayConnections = 10
[server.p2p.peer.l2TxsConfig]
privateKey = 'REPLACE_WITH_CERC_PRIVATE_KEY_PEER'
contractAddress = 'REPLACE_WITH_CONTRACT_ADDRESS'
[server.p2p.nitro]
chainUrl = 'REPLACE_WITH_CERC_NITRO_CHAIN_URL'
store = './out/nitro-db'
privateKey = 'REPLACE_WITH_CERC_WATCHER_NITRO_PK'
chainPrivateKey = 'REPLACE_WITH_CERC_PRIVATE_KEY_PEER'
[server.p2p.nitro.payments]
ratesFile = './environments/rates.toml'
requestTimeoutInSecs = 10
[server.p2p.nitro.payments.cache]
maxAccounts = 1000
accountTTLInSecs = 1800
maxVouchersPerAccount = 1000
voucherTTLInSecs = 300
maxPaymentChannels = 10000
paymentChannelTTLInSecs = 1800
[server.p2p.consensus]
enabled = REPLACE_WITH_CONSENSUS_ENABLED
publicKey = 'REPLACE_WITH_CONSENSUS_PUBLIC_KEY'
privateKey = 'REPLACE_WITH_CONSENSUS_PRIVATE_KEY'
watcherPartyPeersFile = 'REPLACE_WITH_WATCHER_PARTY_PEERS_FILE'
[metrics]
host = "0.0.0.0"
port = 9000
[metrics.gql]
port = 9001
[database]
type = "postgres"
host = "mobymask-watcher-db"
port = 5432
database = "mobymask-watcher"
username = "vdbm"
password = "password"
synchronize = true
logging = false
[upstream]
[upstream.ethServer]
gqlApiEndpoint = "http://ipld-eth-server:8083/graphql"
rpcProviderEndpoint = 'REPLACE_WITH_CERC_ETH_RPC_QUERY_ENDPOINT'
rpcProviderMutationEndpoint = 'REPLACE_WITH_CERC_ETH_RPC_MUTATION_ENDPOINT'
[upstream.ethServer.payments]
paidRPCMethods = ["eth_getBlockByHash", "eth_getBlockByNumber", "eth_getStorageAt"]
amount = 'REPLACE_WITH_UPSTREAM_NITRO_PAY_AMOUNT'
[upstream.ethServer.payments.nitro]
address = 'REPLACE_WITH_UPSTREAM_NITRO_ADDRESS'
multiAddr = 'REPLACE_WITH_UPSTREAM_NITRO_MULTIADDR'
[upstream.ethServer.payments.nitro.fundingAmounts]
directFund = "1000000000000"
virtualFund = "1000000000"
[upstream.cache]
name = "requests"
enabled = false
deleteOnStart = false
[jobQueue]
dbConnectionString = "postgres://vdbm:password@mobymask-watcher-db/mobymask-watcher-job-queue"
maxCompletionLagInSecs = 300
jobDelayInMilliSecs = 100
eventsInBatch = 50
blockDelayInMilliSecs = 60000
@@ -1,7 +1,7 @@
#!/bin/bash
# Usage: build-npm-package-local-dependencies.sh <registry-url> <publish-with-this-version>
# Runs build-npm-package.sh after first fixing up yarn.lock to use a local
# npm registry for all packages in a specific scope (currently @cerc-io and @lirewine)
# npm registry for all packages in a specific scope (currently @cerc-io, @lirewine and @muknsys)
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
@@ -18,7 +18,7 @@ set -e
local_npm_registry_url=$1
package_publish_version=$2
# If we need to handle an additional scope, add it to the list below:
npm_scopes_to_handle=("@cerc-io" "@lirewine")
npm_scopes_to_handle=("@cerc-io" "@lirewine" "@muknsys")
for npm_scope_for_local in ${npm_scopes_to_handle[@]}
do
# We need to configure the local registry
@@ -24,6 +24,7 @@ package_name=$( cat package.json | jq -r .name )
local_npm_registry_url=$1
npm config set @cerc-io:registry ${local_npm_registry_url}
npm config set @lirewine:registry ${local_npm_registry_url}
npm config set @muknsys:registry ${local_npm_registry_url}
# Workaround bug in npm unpublish where it needs the url to be of the form //<foo> and not http://<foo>
local_npm_registry_url_fixed=$( echo ${local_npm_registry_url} | sed -e 's/^http[s]\{0,1\}://')
npm config set -- ${local_npm_registry_url_fixed}:_authToken ${CERC_NPM_AUTH_TOKEN}
@@ -13,7 +13,6 @@ NOW=${1:-`date +%s`}
lcli \
change-genesis-time \
--testnet-dir $TESTNET_DIR \
$TESTNET_DIR/genesis.ssz \
$NOW
@@ -1,6 +0,0 @@
#!/usr/bin/env bash
# Build cerc/go-nitro
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
docker build -t cerc/go-nitro:local -f ${CERC_REPO_BASE_DIR}/go-nitro/docker/local/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/go-nitro
@@ -1,13 +0,0 @@
FROM node:18.15.0-alpine3.16
RUN apk --update --no-cache add git python3 alpine-sdk bash
WORKDIR /app
COPY . .
RUN echo "Installing dependencies..." && \
yarn install && \
cd packages/snap
CMD ["bash", "-c", "yarn start"]
@@ -1,7 +0,0 @@
#!/usr/bin/env bash
# Build cerc/mobymask-snap
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
docker build -t cerc/mobymask-snap:local -f ${SCRIPT_DIR}/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/mobymask-snap
@@ -1,6 +1,6 @@
# 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
ARG VARIANT=16-bullseye
FROM node:${VARIANT}
ARG USERNAME=node
@@ -37,7 +37,7 @@ RUN yarn global add http-server
WORKDIR /app
COPY . .
RUN yarn install
RUN npm install
# Expose port for http
EXPOSE 80
@@ -1,12 +0,0 @@
FROM node:18.17.1-alpine3.18
RUN apk --update --no-cache add python3 alpine-sdk bash curl jq
WORKDIR /app
COPY . .
RUN echo "Installing dependencies" && \
yarn && yarn build:node
WORKDIR /app/packages/nitro-node
@@ -1,9 +0,0 @@
#!/usr/bin/env bash
# Build cerc/nitro-contracts
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/nitro-contracts:local -f ${SCRIPT_DIR}/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/ts-nitro
@@ -1,12 +0,0 @@
FROM node:18.17.1-alpine3.18
RUN apk --update --no-cache add python3 alpine-sdk bash curl jq
WORKDIR /app
COPY . .
RUN echo "Installing dependencies" && \
yarn
RUN cd packages/nitro-rpc-client
@@ -1,9 +0,0 @@
#!/usr/bin/env bash
# Build cerc/nitro-rpc-client
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/nitro-rpc-client:local -f ${SCRIPT_DIR}/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/go-nitro
@@ -1,13 +0,0 @@
FROM node:18.15.0-alpine3.16
RUN apk --update --no-cache add git alpine-sdk bash jq curl
RUN curl -L https://unpkg.com/@pnpm/self-installer | node
WORKDIR /app
COPY . .
RUN echo "Installing dependencies and building..." && \
pnpm install && pnpm build && \
cd examples/token-erc20 && \
pnpm install
@@ -1,7 +0,0 @@
#!/usr/bin/env bash
# Build cerc/ponder
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
docker build -t cerc/ponder:local -f ${SCRIPT_DIR}/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/ponder
@@ -14,8 +14,6 @@ else
echo "Filesystem is fresh"
echo `date` > $EXISTSFILENAME
fi
if [ -n "$CERC_TEST_PARAM_1" ]; then
echo "Test-param-1: ${CERC_TEST_PARAM_1}"
fi
# Run nginx which will block here forever
/usr/sbin/nginx -g "daemon off;"
@@ -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/watcher-erc20:local -f ${SCRIPT_DIR}/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/watcher-ts
docker build -t cerc/watcher-erc20:local -f ${SCRIPT_DIR}/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/erc20-watcher-ts
@@ -1,20 +0,0 @@
FROM ubuntu:22.04
RUN apt-get update \
&& apt-get install -y curl wget gnupg build-essential \
&& curl --silent --location https://deb.nodesource.com/setup_18.x | bash - \
&& apt-get update \
&& apt-get install -y nodejs git busybox jq \
&& node -v
RUN corepack enable \
&& yarn --version
WORKDIR /app
COPY . .
RUN echo "Building mobymask-v2-watcher-ts" && \
yarn && yarn build
WORKDIR /app
@@ -1,9 +0,0 @@
#!/usr/bin/env bash
# Build cerc/watcher-mobymask-v3
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/watcher-mobymask-v3:local -f ${SCRIPT_DIR}/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/mobymask-v2-watcher-ts
@@ -1,4 +1,4 @@
FROM node:18.17.1-alpine3.18
FROM node:16.17.1-alpine3.16
RUN apk --update --no-cache add git python3 alpine-sdk jq
-7
View File
@@ -14,7 +14,6 @@ cerc/laconic-registry-cli
cerc/laconic-console-host
cerc/fixturenet-eth-geth
cerc/fixturenet-eth-lighthouse
cerc/fixturenet-eth-genesis
cerc/watcher-ts
cerc/watcher-mobymask
cerc/watcher-erc20
@@ -51,9 +50,3 @@ cerc/watcher-sushiswap
cerc/graph-node
cerc/sushiswap-subgraphs
cerc/webapp-base
cerc/watcher-mobymask-v3
cerc/go-nitro
cerc/nitro-contracts
cerc/mobymask-snap
cerc/ponder
cerc/nitro-rpc-client
-7
View File
@@ -35,10 +35,3 @@ contract-sushiswap
graph-node
sushiswap-subgraph-v3
fixturenet-sushiswap-subgraph-v3
watcher-mobymask-v3
mobymask-app-v3
go-nitro
nitro-contracts
nitro-reverse-payment-proxy
mobymask-snap
ponder
+6 -10
View File
@@ -1,7 +1,7 @@
git.vdb.to/cerc-io/ipld-eth-db
git.vdb.to/cerc-io/go-ethereum
git.vdb.to/cerc-io/ipld-eth-server
git.vdb.to/cerc-io/eth-statediff-service
github.com/cerc-io/ipld-eth-db
github.com/cerc-io/go-ethereum
github.com/cerc-io/ipld-eth-server
github.com/cerc-io/eth-statediff-service
github.com/cerc-io/eth-statediff-fill-service
github.com/cerc-io/ipld-eth-db-validator
github.com/cerc-io/ipld-eth-beacon-indexer
@@ -18,7 +18,7 @@ github.com/vulcanize/uniswap-watcher-ts
github.com/vulcanize/uniswap-v3-info
github.com/vulcanize/assemblyscript
github.com/cerc-io/eth-probe
git.vdb.to/cerc-io/tx-spammer
github.com/cerc-io/tx-spammer
github.com/dboreham/foundry
github.com/lirewine/gem
github.com/lirewine/debug
@@ -30,7 +30,7 @@ github.com/ethereum-optimism/optimism
github.com/pokt-network/pocket-core
github.com/pokt-network/pocket-core-deployments
github.com/cerc-io/azimuth-watcher-ts
git.vdb.to/cerc-io/ipld-eth-state-snapshot
github.com/cerc-io/ipld-eth-state-snapshot
github.com/cerc-io/gelato-watcher-ts
github.com/filecoin-project/lotus
git.vdb.to/cerc-io/test-project
@@ -43,7 +43,3 @@ github.com/cerc-io/sushiswap-v3-core
github.com/cerc-io/sushiswap-v3-periphery
github.com/graphprotocol/graph-node
github.com/sushiswap/subgraphs
github.com/cerc-io/go-nitro
github.com/cerc-io/ts-nitro
github.com/cerc-io/mobymask-snap
github.com/cerc-io/ponder
+4 -4
View File
@@ -2,10 +2,10 @@ version: "1.0"
name: chain-chunker
description: "Stack to build containers for chain-chunker"
repos:
- git.vdb.to/cerc-io/ipld-eth-state-snapshot@v5
- git.vdb.to/cerc-io/eth-statediff-service@v5
- git.vdb.to/cerc-io/ipld-eth-db@v5
- git.vdb.to/cerc-io/ipld-eth-server@v5
- github.com/cerc-io/ipld-eth-state-snapshot@v5
- github.com/cerc-io/eth-statediff-service@v5
- github.com/cerc-io/ipld-eth-db@v5
- github.com/cerc-io/ipld-eth-server@v5
containers:
- cerc/ipld-eth-state-snapshot
- cerc/eth-statediff-service
+4 -4
View File
@@ -1,10 +1,10 @@
version: "1.0"
name: erc20-watcher
repos:
- git.vdb.to/cerc-io/go-ethereum@v1.11.6-statediff-v5
- git.vdb.to/cerc-io/ipld-eth-db@v5
- git.vdb.to/cerc-io/ipld-eth-server@v1.11.6-statediff-v5
- github.com/cerc-io/watcher-ts
- github.com/cerc-io/go-ethereum
- github.com/cerc-io/ipld-eth-db
- github.com/cerc-io/ipld-eth-server
- github.com/cerc-io/erc20-watcher-ts
- github.com/dboreham/foundry
containers:
- cerc/foundry
+3 -3
View File
@@ -1,9 +1,9 @@
version: "1.0"
name: erc721-watcher
repos:
- git.vdb.to/cerc-io/go-ethereum@v1.11.6-statediff-v5
- git.vdb.to/cerc-io/ipld-eth-db@v5
- git.vdb.to/cerc-io/ipld-eth-server@v1.11.6-statediff-v5
- github.com/cerc-io/go-ethereum
- github.com/cerc-io/ipld-eth-db
- github.com/cerc-io/ipld-eth-server
- github.com/cerc-io/watcher-ts
containers:
- cerc/go-ethereum
@@ -2,11 +2,11 @@ version: "1.0"
name: fixturenet-eth-loaded
description: "Loaded Ethereum Fixturenet"
repos:
- git.vdb.to/cerc-io/go-ethereum@v1.11.6-statediff-v5
- git.vdb.to/cerc-io/tx-spammer
- git.vdb.to/cerc-io/ipld-eth-server@v1.11.6-statediff-v5
- git.vdb.to/cerc-io/ipld-eth-db@v5
- git.vdb.to/cerc-io/lighthouse
- github.com/cerc-io/go-ethereum
- github.com/cerc-io/tx-spammer
- github.com/cerc-io/ipld-eth-server
- github.com/cerc-io/ipld-eth-db
- github.com/cerc-io/lighthouse
containers:
- cerc/go-ethereum
- cerc/lighthouse
+3 -3
View File
@@ -2,10 +2,10 @@ version: "1.2"
name: fixturenet-eth-tx
description: "Ethereum Fixturenet w/ tx-spammer"
repos:
- git.vdb.to/cerc-io/go-ethereum@v1.11.6-statediff-v5
- git.vdb.to/cerc-io/tx-spammer
- git.vdb.to/cerc-io/lighthouse
- github.com/cerc-io/go-ethereum
- github.com/cerc-io/tx-spammer
- github.com/dboreham/foundry
- github.com/cerc-io/lighthouse
containers:
- cerc/go-ethereum
- cerc/lighthouse
+1 -1
View File
@@ -66,7 +66,7 @@ It is not necessary to use them all at once, but a complete example follows:
```
# Setup
$ laconic-so setup-repositories --include git.vdb.to/cerc-io/go-ethereum,git.vdb.to/cerc-io/ipld-eth-db,git.vdb.to/cerc-io/ipld-eth-server,github.com/cerc-io/ipld-eth-beacon-db,github.com/cerc-io/ipld-eth-beacon-indexer,github.com/cerc-io/eth-probe,git.vdb.to/cerc-io/tx-spammer
$ laconic-so setup-repositories --include github.com/cerc-io/go-ethereum,github.com/cerc-io/ipld-eth-db,github.com/cerc-io/ipld-eth-server,github.com/cerc-io/ipld-eth-beacon-db,github.com/cerc-io/ipld-eth-beacon-indexer,github.com/cerc-io/eth-probe,github.com/cerc-io/tx-spammer
# Build
$ laconic-so build-containers --include cerc/go-ethereum,cerc/lighthouse,cerc/fixturenet-eth-geth,cerc/fixturenet-eth-lighthouse,cerc/ipld-eth-db,cerc/ipld-eth-server,cerc/ipld-eth-beacon-db,cerc/ipld-eth-beacon-indexer,cerc/eth-probe,cerc/keycloak,cerc/tx-spammer
+2 -2
View File
@@ -2,8 +2,8 @@ version: "1.1"
name: fixturenet-eth
description: "Ethereum Fixturenet"
repos:
- git.vdb.to/cerc-io/go-ethereum@v1.11.6-statediff-v5
- git.vdb.to/cerc-io/lighthouse
- github.com/cerc-io/go-ethereum
- github.com/cerc-io/lighthouse
- github.com/dboreham/foundry
containers:
- cerc/go-ethereum
@@ -0,0 +1,3 @@
# Graph-Node Fixturenet
Experimental
@@ -0,0 +1,12 @@
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
- graph-node
@@ -4,8 +4,6 @@ Testing a "Loaded" fixturenet with console.
Instructions for deploying a local Laconic blockchain "fixturenet" for development and testing purposes using laconic-stack-orchestrator.
**Note:** For building some NPMs, access to the @lirewine repositories is required. If you don't have access, see [this tutorial](/docs/laconicd-fixturenet.md) to run this stack
## 1. Install Laconic Stack Orchestrator
Installation is covered in detail [here](https://github.com/cerc-io/stack-orchestrator#user-mode) but if you're on Linux and already have docker installed it should be as simple as:
```
@@ -32,24 +30,24 @@ $ export CERC_NPM_AUTH_TOKEN=<my-token>
## 3. Clone required repositories
```
$ laconic-so --stack fixturenet-laconic-loaded setup-repositories
$ laconic-so --stack fixturenet-laconicd setup-repositories
```
## 4. Build the stack's packages and containers
```
$ laconic-so --stack fixturenet-laconic-loaded build-npms
$ laconic-so --stack fixturenet-laconic-loaded build-containers
$ laconic-so --stack fixturenet-laconicd build-npms
$ laconic-so --stack fixturenet-laconicd build-containers
```
## 5. Deploy the stack
```
$ laconic-so --stack fixturenet-laconic-loaded deploy up
$ laconic-so --stack fixturenet-laconicd deploy up
```
Correct operation should be verified by checking the laconicd container's logs with:
```
$ laconic-so --stack fixturenet-laconic-loaded deploy logs
$ laconic-so --stack fixturenet-laconicd deploy logs
```
## 6. Test with the Registry CLI
```
$ laconic-so --stack fixturenet-laconic-loaded deploy exec cli "laconic cns status"
$ laconic-so --stack fixturenet-laconicd deploy exec cli "laconic cns status"
```
## 7. View the laconic console
Get the URL for the console web app with this command (the port number will be different for each deployment):
@@ -9,7 +9,7 @@ Prerequisite: An L1 Ethereum RPC endpoint
Clone required repositories:
```bash
laconic-so --stack fixturenet-optimism setup-repositories --exclude git.vdb.to/cerc-io/go-ethereum
laconic-so --stack fixturenet-optimism setup-repositories --exclude github.com/cerc-io/go-ethereum
# If this throws an error as a result of being already checked out to a branch/tag in a repo, remove the repositories mentioned below and re-run the command
```
@@ -2,8 +2,8 @@ version: "1.0"
name: fixturenet-optimism
description: "Optimism Fixturenet"
repos:
- git.vdb.to/cerc-io/go-ethereum@v1.11.6-statediff-v5
- git.vdb.to/cerc-io/lighthouse
- github.com/cerc-io/go-ethereum
- github.com/cerc-io/lighthouse
- github.com/dboreham/foundry
- github.com/ethereum-optimism/optimism@v1.0.4
- github.com/ethereum-optimism/op-geth@v1.101105.2
@@ -1,57 +0,0 @@
# fixturenet-payments
Instructions to setup and deploy an end-to-end fixturenet-payments stack
## Setup
Clone required repositories:
```bash
laconic-so --stack fixturenet-payments setup-repositories --pull
```
Build the container images:
```bash
laconic-so --stack fixturenet-payments build-containers
```
## Deploy
Deploy the stack:
```bash
laconic-so --stack fixturenet-payments deploy --cluster payments up
# Exposed on host ports:
# 4005: go-nitro node's RPC endpoint
# 5005: go-nitro node's p2p endpoint
# 8081: reverse payment proxy's RPC endpoint
# 15432: MobyMask v3 watcher's db endpoint
# 3001: MobyMask v3 watcher endpoint
# 9090: MobyMask v3 watcher relay node endpoint
# 8080: MobyMask snap
# 3004: MobyMask v3 app
```
## Demo
Follow the [demo](./demo.md) to try out end-to-end payments
## Clean up
Stop all the services running in background:
```bash
laconic-so --stack fixturenet-payments deploy --cluster payments down 30
```
Clear volumes created by this stack:
```bash
# List all relevant volumes
docker volume ls -q --filter "name=[payments"
# Remove all the listed volumes
docker volume rm $(docker volume ls -q --filter "name=[payments")
```
-275
View File
@@ -1,275 +0,0 @@
# Demo
Stack components:
* `ipld-eth-db` database for statediffed data
* Local geth + lighthouse blockchain "fixturenet" running in statediffing mode
* `ipld-eth-server` which runs an ETH RPC API and a GQL server; serves data from `ipld-eth-db`
* A go-nitro deployment acting as the Nitro node for `ipld-eth-server`
* A modified reverse payment proxy server (based on the one from go-nitro) that proxies requests to `ipld-eth-server`'s RPC endpoint; it talks to `ipld-eth-server`'s Nitro node to accept and validate payments required for configured RPC requests
* A MobyMask v3 watcher that pays the `ipld-eth-server` for ETH RPC requests
* A MobyMask v3 app that pays the watcher for reads (GQL queries) and writes
* An example ERC20 Ponder app that pays the `ipld-eth-server` for ETH RPC requests
## Setup
* On starting the stack, MobyMask watcher creates a payment channel with the `ipld-eth-server`'s Nitro node. Check watcher logs and wait for the same:
```bash
docker logs -f $(docker ps -aq --filter name="mobymask-watcher-server")
# Expected output:
# vulcanize:server Peer ID: 12D3KooWKLqLWU82VU7jmsmQMruRvZWhoBoVsf1UHchM5Nuq9ymY
# vulcanize:server Using chain URL http://fixturenet-eth-geth-1:8546 for Nitro node
# ...
# ts-nitro:util:nitro Ledger channel created with id 0x65703ccdfacab09ac35367bdbe6c5a337e7a6651aad526807607b1c59b28bc1e
# ...
# ts-nitro:util:nitro Virtual payment channel created with id 0x29ff1335d73391a50e8fde3e9b34f00c3d81c39ddc7f89187f44dd51df96140e
# vulcanize:server Starting server... +0ms
```
* Keep the above command running to keep track of incoming payments and GQL requests from the MobyMask app
* In another terminal, export the payment channel id to a variable:
```bash
export WATCHER_UPSTREAM_PAYMENT_CHANNEL=<PAYMENT_CHANNEL_ID>
```
* Check the payment channel status:
```bash
docker exec payments-nitro-rpc-client-1 npm exec -c "nitro-rpc-client get-payment-channel $WATCHER_UPSTREAM_PAYMENT_CHANNEL -h go-nitro -p 4005"
# Expected output:
# {
# ID: '0x8c0d17639bd2ba07dbcd248304a8f3c6c7276bfe25c2b87fe41f461e20f33f01',
# Status: 'Open',
# Balance: {
# AssetAddress: '0x0000000000000000000000000000000000000000',
# Payee: '0xaaa6628ec44a8a742987ef3a114ddfe2d4f7adce',
# Payer: '0xbbb676f9cff8d242e9eac39d063848807d3d1d94',
# PaidSoFar: 0n,
# RemainingFunds: 1000000000n
# }
# }
```
* In another terminal, check the reverse payment proxy server's logs to keep track of incoming payments and RPC requests:
```bash
docker logs -f $(docker ps -aq --filter name="nitro-reverse-payment-proxy")
```
* MetaMask flask wallet setup for running the MobyMask app:
* Get the geth nodes port mapped to host:
```bash
docker port payments-fixturenet-eth-geth-1-1 8545
```
* In MetaMask, add a custom network with the following settings:
```bash
# Network name
Local fixturenet
# New RPC URL
http://127.0.0.1:<GETH_PORT>
# Chain ID
1212
# Currency symbol
ETH
```
* Import a faucet account with the following private key:
```bash
# Faucet PK
# 0x570b909da9669b2f35a0b1ac70b8358516d55ae1b5b3710e95e9a94395090597
```
* Create an additional account for usage in the app; fund it from the faucet account
* Get the generated root invite link for MobyMask from contract deployment container logs:
```bash
docker logs -f $(docker ps -aq --filter name="mobymask-1")
# Expected output:
# ...
# "key": "0x60e706fda4639fe0a8eb102cb0ce81231cf6e819f41cb4eadf72d865ea4c11ad"
# }
# http://127.0.0.1:3004/#/members?invitation=<INVITATION>
```
## Run
### MobyMask App
* Open app in a browser (where MetaMask was setup) using the invite link
* Run the following in browser console to enable logs:
```bash
localStorage.debug = 'ts-nitro:*'
# Refresh the tab for taking effect
```
* In the apps debug panel, check that the peer gets connected to relay node and watcher peer
* Open the `NITRO` tab in debug panel
* Click on `Connect Wallet` to connect to MetaMask (make sure that the newly funded account is active)
* Click on `Connect Snap` to install/connect snap
* Perform `DIRECT FUND` with the preset amount and wait for the MetaMask confirmation prompt to appear; confirm the transaction and wait for a ledger channel to be created with the watcher
* Perform `VIRTUAL FUND` with amount set to `10000` and wait for a payment channel to be created with the watcher
* Perform phisher status check queries now that a payment channel is created:
* Check the watcher logs for received payments along with the GQL queries:
```bash
# Expected output:
# ...
# laconic:payments Serving a paid query for 0x86804299822212c070178B5135Ba6DdAcFC357D3
# vulcanize:resolver isPhisher 0x98ae4f9e9d01cc892adfe6871e1db0287039e0c183d3b5bb31d724228c114744 0x2B6AFbd4F479cE4101Df722cF4E05F941523EaD9 TWT:ash1
# vulcanize:indexer isPhisher: db miss, fetching from upstream server
# laconic:payments Making RPC call: eth_chainId
# laconic:payments Making RPC call: eth_getBlockByHash
# laconic:payments Making RPC call: eth_chainId
# laconic:payments Making RPC call: eth_getStorageAt
```
* The watcher makes several ETH RPC requests to `ipld-eth-server` to fetch data required for satisfying the GQL request(s); check the payment proxy server logs for charged RPC requests (`eth_getBlockByHash`, `eth_getBlockByNumber`, `eth_getStorageAt`):
```bash
# Expected output:
# ...
# {"time":"2023-10-06T06:46:52.769009314Z","level":"DEBUG","msg":"Serving RPC request","method":"eth_chainId"}
# {"time":"2023-10-06T06:46:52.773006426Z","level":"DEBUG","msg":"Serving RPC request","method":"eth_getBlockByNumber"}
# {"time":"2023-10-06T06:46:52.811142054Z","level":"DEBUG","msg":"Request cost","cost-per-byte":1,"response-length":1480,"cost":1480,"method":"eth_getBlockByNumber"}
# {"time":"2023-10-06T06:46:52.811418494Z","level":"DEBUG","msg":"sent message","address":"0xAAA6628Ec44A8a742987EF3A114dDFE2D4F7aDCE","method":"receive_voucher"}
# {"time":"2023-10-06T06:46:52.812557482Z","level":"DEBUG","msg":"Received voucher","delta":5000}
# ...
# {"time":"2023-10-06T06:46:52.87525215Z","level":"DEBUG","msg":"Serving RPC request","method":"eth_getStorageAt"}
# {"time":"2023-10-06T06:46:52.882859654Z","level":"DEBUG","msg":"Request cost","cost-per-byte":1,"response-length":104,"cost":104,"method":"eth_getStorageAt"}
# {"time":"2023-10-06T06:46:52.882946485Z","level":"DEBUG","msg":"sent message","address":"0xAAA6628Ec44A8a742987EF3A114dDFE2D4F7aDCE","method":"receive_voucher"}
# {"time":"2023-10-06T06:46:52.884012641Z","level":"DEBUG","msg":"Received voucher","delta":5000}
# {"time":"2023-10-06T06:46:52.884032961Z","level":"DEBUG","msg":"Destination request","url":"http://ipld-eth-server:8081/"}
```
* Change the amount besides `PAY` button in debug panel to `>=100` for phisher reports next
* Perform a phisher report and check the watcher logs for received payments:
```bash
# Expected output:
# ...
# vulcanize:libp2p-utils [6:50:2] Received a message on mobymask P2P network from peer: 12D3KooWRkxV9SX8uTUZYkbRjai4Fsn7yavB61J5TMnksixsabsP
# ts-nitro:engine {"msg":"Received message","_msg":{"to":"0xBBB676","from":"0x868042","payloadSummaries":[],"proposalSummaries":[],"payments":[{"amount":200,"channelId":"0x557153d729cf3323c0bdb40a36b245f98c2d4562933ba2182c9d61c5cfeda948"}],"rejectedObjectives":[]}}
# laconic:payments Received a payment voucher of 100 from 0x86804299822212c070178B5135Ba6DdAcFC357D3
# vulcanize:libp2p-utils Payment received for a mutation request from 0x86804299822212c070178B5135Ba6DdAcFC357D3
# vulcanize:libp2p-utils Transaction receipt for invoke message {
# to: '0x2B6AFbd4F479cE4101Df722cF4E05F941523EaD9',
# blockNumber: 232,
# blockHash: '0x6a188722c102662ea48af3786fe9db0d4b6c7ab7b27473eb0e628cf95746a244',
# transactionHash: '0x6521205db8a905b3222adc2b6855f9b2abc72580624d299bec2a35bcba173efa',
# effectiveGasPrice: '1500000007',
# gasUsed: '113355'
# }
```
* Check the watcher - ipld-eth-server payment channel status after a few requests:
```bash
docker exec payments-nitro-rpc-client-1 npm exec -c "nitro-rpc-client get-payment-channel $WATCHER_UPSTREAM_PAYMENT_CHANNEL -h go-nitro -p 4005"
# Expected output ('PaidSoFar' should be non zero):
# {
# ID: '0x8c0d17639bd2ba07dbcd248304a8f3c6c7276bfe25c2b87fe41f461e20f33f01',
# Status: 'Open',
# Balance: {
# AssetAddress: '0x0000000000000000000000000000000000000000',
# Payee: '0xaaa6628ec44a8a742987ef3a114ddfe2d4f7adce',
# Payer: '0xbbb676f9cff8d242e9eac39d063848807d3d1d94',
# PaidSoFar: 30000n,
# RemainingFunds: 999970000n
# }
# }
```
### ERC20 Ponder App
* Run the ponder app in it's container:
```bash
docker exec -it payments-ponder-app-1 bash -c "pnpm start"
# Expected output:
# 09:58:54.288 INFO payment Creating ledger channel with nitro node 0xAAA6628Ec44A8a742987EF3A114dDFE2D4F7aDCE
# ...
# 09:59:14.230 INFO payment Creating payment channel with nitro node 0xAAA6628Ec44A8a742987EF3A114dDFE2D4F7aDCE
# ...
# 09:59:14.329 INFO payment Using payment channel 0x10f049519bc3f862e2b26e974be8666886228f30ea54aab06e2f23718afffab0
```
* On starting the Ponder app, it creates a payment channel with the `ipld-eth-server`'s Nitro node and then starts the historical sync service
* The sync service makes several ETH RPC requests to the `ipld-eth-server` to fetch required data; check the payment proxy server logs for charged RPC requests (`eth_getBlockByNumber`, `eth_getLogs`)
```bash
# Expected output:
# ...
# {"time":"2023-10-06T06:51:45.214478402Z","level":"DEBUG","msg":"Serving RPC request","method":"eth_getBlockByNumber"}
# {"time":"2023-10-06T06:51:45.22251171Z","level":"DEBUG","msg":"Request cost","cost-per-byte":1,"response-length":576,"cost":576,"method":"eth_getBlockByNumber"}
# {"time":"2023-10-06T06:51:45.222641963Z","level":"DEBUG","msg":"sent message","address":"0xAAA6628Ec44A8a742987EF3A114dDFE2D4F7aDCE","method":"receive_voucher"}
# {"time":"2023-10-06T06:51:45.224042391Z","level":"DEBUG","msg":"Received voucher","delta":5000}
# {"time":"2023-10-06T06:51:45.224061411Z","level":"DEBUG","msg":"Destination request","url":"http://ipld-eth-server:8081/"}
# {"time":"2023-10-06T06:51:45.242064953Z","level":"DEBUG","msg":"Serving RPC request","method":"eth_getLogs"}
# {"time":"2023-10-06T06:51:45.249118517Z","level":"DEBUG","msg":"Request cost","cost-per-byte":1,"response-length":61,"cost":61,"method":"eth_getLogs"}
# {"time":"2023-10-06T06:51:45.249189892Z","level":"DEBUG","msg":"sent message","address":"0xAAA6628Ec44A8a742987EF3A114dDFE2D4F7aDCE","method":"receive_voucher"}
# {"time":"2023-10-06T06:51:45.249743149Z","level":"DEBUG","msg":"Received voucher","delta":5000}
# {"time":"2023-10-06T06:51:45.249760631Z","level":"DEBUG","msg":"Destination request","url":"http://ipld-eth-server:8081/"}
# ...
```
* Export the payment channel id to a variable:
```bash
export PONDER_UPSTREAM_PAYMENT_CHANNEL=<PAYMENT_CHANNEL_ID>
```
* Check the ponder - ipld-eth-server payment channel status:
```bash
docker exec payments-nitro-rpc-client-1 npm exec -c "nitro-rpc-client get-payment-channel $PONDER_UPSTREAM_PAYMENT_CHANNEL -h go-nitro -p 4005"
# Expected output ('PaidSoFar' is non zero):
# {
# ID: '0x1178ac0f2a43e54a122216fa6afdd30333b590e49e50317a1f9274a591da0f96',
# Status: 'Open',
# Balance: {
# AssetAddress: '0x0000000000000000000000000000000000000000',
# Payee: '0xaaa6628ec44a8a742987ef3a114ddfe2d4f7adce',
# Payer: '0x67d5b55604d1af90074fcb69b8c51838fff84f8d',
# PaidSoFar: 215000n,
# RemainingFunds: 999785000n
# }
# }
```
## Clean Up
* In the MobyMask app, perform `VIRTUAL DEFUND` and `DIRECT DEFUND` (in order) for closing the payment channel created with watcher
* Run the following in the browser console to delete the Nitro node's data:
```bash
await clearNodeStorage()
```
* On a fresh restart, clear activity tab data in MetaMask for concerned accounts
@@ -1,54 +0,0 @@
version: "1.0"
name: fixturenet-payments
description: "Stack to demonstrate payments between various services"
repos:
# fixturenet repos
- git.vdb.to/cerc-io/go-ethereum@v1.11.6-statediff-v5
- git.vdb.to/cerc-io/lighthouse
- git.vdb.to/cerc-io/ipld-eth-db@v5
- git.vdb.to/cerc-io/ipld-eth-server@v1.11.6-statediff-v5
# nitro repos
- github.com/cerc-io/ts-nitro@v0.1.13
- github.com/cerc-io/go-nitro@v0.1.1-ts-port-0.1.5
# mobymask watcher repos
- github.com/cerc-io/watcher-ts@v0.2.63
- github.com/cerc-io/mobymask-v2-watcher-ts@v0.2.2
- github.com/cerc-io/MobyMask@v0.1.3
# mobymask app repos
- github.com/cerc-io/mobymask-snap
- github.com/cerc-io/mobymask-ui@v0.2.1
# ponder repo
- github.com/cerc-io/ponder@laconic
containers:
# fixturenet images
- cerc/go-ethereum
- cerc/lighthouse
- cerc/lighthouse-cli
- cerc/fixturenet-eth-genesis
- cerc/fixturenet-eth-geth
- cerc/fixturenet-eth-lighthouse
- cerc/ipld-eth-db
- cerc/ipld-eth-server
- cerc/nitro-contracts
- cerc/go-nitro
- cerc/nitro-rpc-client
# mobymask watcher images
- cerc/watcher-ts
- cerc/watcher-mobymask-v3
- cerc/mobymask
# mobymask app images
- cerc/mobymask-snap
- cerc/mobymask-ui
# ponder image
- cerc/ponder
pods:
- fixturenet-eth
- ipld-eth-server
- ipld-eth-db
- nitro-contracts
- go-nitro
- nitro-reverse-payment-proxy
- watcher-mobymask-v3
- mobymask-snap
- mobymask-app-v3
- ponder
@@ -4,10 +4,10 @@ description: "plugeth Ethereum Fixturenet w/ tx-spammer"
repos:
- git.vdb.to/cerc-io/plugeth@statediff
- git.vdb.to/cerc-io/plugeth-statediff
- git.vdb.to/cerc-io/lighthouse
- git.vdb.to/cerc-io/ipld-eth-db@v5
- git.vdb.to/cerc-io/ipld-eth-server@v5
- git.vdb.to/cerc-io/tx-spammer
- github.com/cerc-io/lighthouse
- github.com/cerc-io/ipld-eth-db@v5
- github.com/cerc-io/ipld-eth-server@v5
- github.com/cerc-io/tx-spammer
- github.com/dboreham/foundry
containers:
- cerc/plugeth-statediff
+2 -2
View File
@@ -2,8 +2,8 @@ version: "1.0"
name: fixturenet-pocket
description: "A single node pocket chain that can serve relays from the geth-1 node in eth-fixturenet"
repos:
- git.vdb.to/cerc-io/go-ethereum@v1.11.6-statediff-v5
- git.vdb.to/cerc-io/lighthouse
- github.com/cerc-io/go-ethereum
- github.com/cerc-io/lighthouse
- github.com/pokt-network/pocket-core
- github.com/pokt-network/pocket-core-deployments # contains the dockerfile
containers:
@@ -32,10 +32,21 @@ laconic-so --stack fixturenet-sushiswap-subgraph build-containers
## Deploy
Create an env file with the following contents to be used in the next step:
```bash
# Network and ETH RPC endpoint to run graph-node against
NETWORK=lotus-fixturenet
ETH_RPC_ENDPOINT=http://lotus-node-1:1234/rpc/v1
```
Uncomment the dependency on `lotus-node-1` in the [graph-node compose file](../../compose/docker-compose-graph-node.yml)
Deploy the stack:
```bash
laconic-so --stack fixturenet-sushiswap-subgraph deploy --cluster sushigraph up
laconic-so --stack fixturenet-sushiswap-subgraph deploy --cluster sushigraph --env-file <PATH_TO_ENV_FILE> up
# Note: Remove any existing volumes for the cluster for a fresh start
```
@@ -143,42 +154,6 @@ http://127.0.0.1:<HOST_PORT>/subgraphs/name/sushiswap/v3-lotus/graphql
docker exec -it sushigraph-sushiswap-v3-core-1 pnpm run pool:burn:docker --pool $POOL_ADDRESS --amount 10
```
* Query the sushiswap v3-lotus subgraph GQL after running above commands
```graphql
{
_meta {
block {
number
}
deployment
hasIndexingErrors
}
factories {
poolCount
id
}
pools {
id
token0 {
id
name
symbol
}
mints {
id
owner
}
burns {
id
owner
}
}
}
```
## Clean up
Stop all the services running in background run:
-157
View File
@@ -1,157 +0,0 @@
# Graph Node
## Setup
Clone required repositories:
```bash
laconic-so --stack graph-node setup-repositories --pull
```
Checkout to a non-default branch in the cloned repos if required:
```bash
# Default repo base dir
cd ~/cerc
# Example
cd graph-node
git checkout <your-branch> && git pull
# Remove the corresponding docker image if it already exists
docker image rm cerc/graph-node:local
# Remove any dangling images
docker image prune
```
Build the container images:
```bash
laconic-so --stack graph-node build-containers
```
## Create a deployment
Initialize deployment and create "spec" file:
```bash
laconic-so --stack graph-node deploy init --output graph-node-spec.yml
```
We need to assign fixed ports: `8000` for subgraph GQL endpoint, `8020` for subgraph deployment and `5001` for IPFS. The values can be
customized by editing the "spec" file generated by `laconic-so deploy init`.
```
$ cat graph-node-spec.yml
stack: graph-node
ports:
graph-node:
- '8000:8000'
- '8001'
- '8020:8020'
- '8030'
ipfs:
- '8080'
- '4001'
- '5001:5001'
...
```
Create deployment:
```bash
laconic-so deploy create --spec-file graph-node-spec.yml --deployment-dir graph-node-deployment
```
## Start the stack
Create an env file with the following values to be set before starting the stack:
```bash
# Set ETH RPC endpoint the graph node will use
# Host and port of the ETH RPC endpoint to check before starting graph-node
export ETH_RPC_HOST=
export ETH_RPC_PORT=
# The etherum network(s) graph-node will connect to
# Set this to a space-separated list of the networks where each entry has the form NAME:URL
export ETH_NETWORKS=
```
Example env file:
```bash
export ETH_RPC_HOST=filecoin.chainup.net
export ETH_RPC_PORT=443
export ETH_NETWORKS=filecoin:https://filecoin.chainup.net/rpc/v1
```
Set the environment variables:
```bash
source <PATH_TO_ENV_FILE>
```
Deploy the stack:
```bash
laconic-so deployment --dir graph-node-deployment start
# Note: Remove any existing volumes in the cluster for a fresh start
```
After all services have started, follow `graph-node` logs:
```bash
laconic-so deployment --dir graph-node-deployment logs -f graph-node
```
Subgraphs can now be deployed to the graph-node.
Follow [Deploy the Subgraph](https://github.com/graphprotocol/graph-node/blob/v0.32.0/docs/getting-started.md#24-deploy-the-subgraph) section in graph-node docs for an existing subgraph.
## Set environment variables
* The graph-node environment variable `ETHEREUM_REORG_THRESHOLD` can be set in the deployment compose file
```bash
$ cat graph-node-deployment/compose/docker-compose-graph-node.yml
services:
graph-node:
image: cerc/graph-node:local
...
environment:
...
GRAPH_LOG: debug
ETHEREUM_REORG_THRESHOLD: 3
```
Change `ETHEREUM_REORG_THRESHOLD` to desired value
* To restart graph-node with updated values
* Stop the stack first
```bash
laconic-so deployment --dir graph-node-deployment stop
```
* Start the stack again
```
laconic-so deployment --dir graph-node-deployment start
```
* To check if environment variable has been updated in graph-node container
```bash
$ laconic-so deployment --dir graph-node-deployment exec graph-node bash
root@dc4d3abe1615:/# echo $ETHEREUM_REORG_THRESHOLD
16
```
## Clean up
Stop all the services running in background run:
```bash
laconic-so deployment --dir graph-node-deployment stop
```
Clear volumes created by this stack:
```bash
laconic-so deployment --dir graph-node-deployment stop --delete-volumes
```
@@ -1,68 +0,0 @@
# Deploying Subgraph
## Setup
We will use the [ethereum-gravatar](https://github.com/graphprotocol/graph-tooling/tree/%40graphprotocol/graph-cli%400.58.0/examples/ethereum-gravatar) example subgraph from `graphprotocol/graph-tooling` repo
- Clone the repo
```bash
git clone git@github.com:graphprotocol/graph-tooling.git
cd graph-tooling
```
- Install dependencies
```bash
pnpm install
```
- Change directory to example-subgraph
```bash
cd examples/ethereum-gravatar
```
## Deploy
The following steps should be similar for every subgraph
- Change the network and address in `subgraph.yaml`
```yaml
...
dataSources:
- kind: ethereum/contract
name: Gravity
network: <NETWORK_NAME>
source:
address: '<CONTRACT_ADDRESS>'
abi: Gravity
startBlock: <START_BLOCK>
...
```
- `CONTRACT_ADDRESS` is the address of the deployed contract on the desired network
- `START_BLOCK` is the block number after which we want to process events
- `NETWORK_NAME` is the name of the network specified when deploying graph-node
- When deploying graph-node `ETH_NETWORKS` env is set to a space-separated list of the networks where each entry has the form `NAME:URL`
- The `NAME` can be used in subgraph to specify which network to use
- More details can be seen in [Start the stack](./README.md#start-the-stack) section
- Build the subgraph
```bash
pnpm codegen
pnpm build
```
- Create and deploy the subgraph
```bash
pnpm graph create example --node <GRAPH_NODE_DEPLOY_ENDPOINT>
pnpm graph deploy example --ipfs <GRAPH_NODE_IPFS_ENDPOINT> --node <GRAPH_NODE_DEPLOY_ENDPOINT>
```
- `GRAPH_NODE_DEPLOY_ENDPOINT` and `GRAPH_NODE_IPFS_ENDPOINT` will be available after graph-node has been deployed
- More details can be seen in [Create a deployment](./README.md#create-a-deployment) section
- The subgraph GQL endpoint will be seen after deploy command runs successfully
- To remove the subgraph
```bash
pnpm graph remove --node <GRAPH_NODE_DEPLOY_ENDPOINT> example
```
-9
View File
@@ -1,9 +0,0 @@
version: "1.0"
name: graph-node
description: "Stack for running graph-node"
repos:
- github.com/graphprotocol/graph-node
containers:
- cerc/graph-node
pods:
- graph-node
+2 -2
View File
@@ -17,7 +17,7 @@ $ laconic-so --stack mainnet-eth build-containers
## Create a deployment
```
$ laconic-so --stack mainnet-eth deploy init --map-ports-to-host any-same --output mainnet-eth-spec.yml
$ laconic-so --stack mainnet-eth deploy init --output mainnet-eth-spec.yml
$ laconic-so deploy create --spec-file mainnet-eth-spec.yml --deployment-dir mainnet-eth-deployment
```
## Start the stack
@@ -138,4 +138,4 @@ $ sudo du -h mainnet-eth-deployment/data/
860G mainnet-eth-deployment/data/mainnet_eth_geth_1_data/geth
860G mainnet-eth-deployment/data/mainnet_eth_geth_1_data
885G mainnet-eth-deployment/data/
```
```
+6 -3
View File
@@ -1,12 +1,13 @@
version: "1.2"
version: "1.1"
name: mainnet-eth
description: "Ethereum Mainnet"
repos:
- git.vdb.to/cerc-io/go-ethereum@v1.11.6-statediff-v5
- git.vdb.to/cerc-io/lighthouse
- 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
@@ -16,8 +17,10 @@ containers:
- 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
@@ -27,7 +27,10 @@ import sys
import tomli
import re
default_spec_file_content = ""
default_spec_file_content = """config:
node_moniker: my-node-name
chain_id: my-chain-id
"""
class SetupPhase(Enum):
+2 -2
View File
@@ -1,8 +1,8 @@
version: "1.0"
name: mobymask-v2
repos:
- git.vdb.to/cerc-io/go-ethereum@v1.11.6-statediff-v5
- git.vdb.to/cerc-io/lighthouse
- github.com/cerc-io/go-ethereum
- github.com/cerc-io/lighthouse
- github.com/dboreham/foundry
- github.com/ethereum-optimism/optimism@v1.0.4
- github.com/ethereum-optimism/op-geth@v1.101105.2
-6
View File
@@ -1,6 +0,0 @@
# MobyMask v3
Instructions to setup and deploy MobyMask v3 stack (watcher + web-app) using [laconic-stack-orchestrator](/README.md#install)
* Follow [watcher.md](./watcher.md) for deploying the watcher
* Follow [web-app.md](./web-app.md) for deploying the app
-19
View File
@@ -1,19 +0,0 @@
version: "1.0"
description: "MobyMask v3 stack"
name: mobymask-v3
repos:
- github.com/cerc-io/ts-nitro@v0.1.13
- github.com/cerc-io/watcher-ts@v0.2.63
- github.com/cerc-io/mobymask-v2-watcher-ts@v0.2.2
- github.com/cerc-io/MobyMask@v0.1.3
- github.com/cerc-io/mobymask-ui@v0.2.1
containers:
- cerc/nitro-contracts
- cerc/watcher-ts
- cerc/watcher-mobymask-v3
- cerc/mobymask
- cerc/mobymask-ui
pods:
- nitro-contracts
- watcher-mobymask-v3
- mobymask-app-v3
-136
View File
@@ -1,136 +0,0 @@
# MobyMask v3 Watcher
## Setup
Prerequisite: L2 Optimism Geth RPC endpoint
Clone required repositories:
```bash
laconic-so --stack mobymask-v3 setup-repositories --pull --exclude github.com/cerc-io/mobymask-ui
```
Build the container images:
```bash
laconic-so --stack mobymask-v3 build-containers --exclude cerc/mobymask-ui
```
## Deploy
### Configuration
Create and update an env file to be used in the next step ([defaults](../../config/watcher-mobymask-v3/mobymask-params.env)):
```bash
# External ETH RPC endpoint for contract(s) deployment
CERC_ETH_RPC_ENDPOINT=
# External ETH RPC endpoint used for queries in the watcher
CERC_ETH_RPC_QUERY_ENDPOINT=
# External ETH RPC endpoint used for mutations in the watcher
CERC_ETH_RPC_MUTATION_ENDPOINT=
# External ETH endpoint used by watcher's Nitro node
CERC_NITRO_CHAIN_URL=
# Specify the an account PK for contract deployment
CERC_PRIVATE_KEY_DEPLOYER=
# Base URI for mobymask-app
# (used for generating a root invite link after deploying the contract)
CERC_MOBYMASK_APP_BASE_URI="http://127.0.0.1:3004/#"
# (Optional) Domain to be used in the relay node's announce address
CERC_RELAY_ANNOUNCE_DOMAIN=
# (Optional) Set of relay peers to connect to from the relay node
CERC_RELAY_PEERS=[]
# (Optional) Set of multiaddrs to be avoided while dialling
CERC_DENY_MULTIADDRS=[]
# (Optional) Type of pubsub to be used
CERC_PUBSUB=""
# Set to false for disabling watcher peer to send txs to L2
CERC_ENABLE_PEER_L2_TXS=true
# (Optional) Set already deployed MobyMask contract address to avoid deploying contract in the stack
CERC_DEPLOYED_CONTRACT=
# (Optional) Set already deployed Nitro addresses to avoid deploying them in the stack
CERC_NA_ADDRESS=
CERC_VPA_ADDRESS=
CERC_CA_ADDRESS=
# Specify private key of a funded account for sending txs to L2
CERC_PRIVATE_KEY_PEER=
# Specify private key for the Nitro account
CERC_WATCHER_NITRO_PK=
# (Optional) Set a pre-existing peer id to be used (enables consensus)
# Uses a generated peer id if not set (disables consensus)
CERC_PEER_ID=
# Disable payments to upstream ETH server
CERC_ENABLE_UPSTREAM_PAYMENTS=false
```
* NOTE: If Optimism is running on the host machine, use `host.docker.internal` as the hostname to access the host port
### Deploy the stack
```bash
laconic-so --stack mobymask-v3 deploy --cluster mobymask_v3 --exclude mobymask-app-v3 --env-file <PATH_TO_ENV_FILE> up
```
* To list down and monitor the running containers:
```bash
laconic-so --stack mobymask-v3 deploy --cluster mobymask_v3 --exclude mobymask-app-v3 ps
# With status
docker ps -a
# Check logs for a container
docker logs -f <CONTAINER_ID>
```
* The watcher endpoint is exposed on host port `3001` and the relay node endpoint is exposed on host port `9090`
* Check the logs of the MobyMask contract deployment container to get the deployed contract's address and generated root invite link:
```bash
docker logs -f $(docker ps -aq --filter name="mobymask-1")
```
* Check logs of the Nitro contracts container to get the deployed Nitro contracts' addresses:
```bash
docker exec -it $(docker ps -q --filter name="nitro-contracts") bash -c "cat /app/deployment/nitro-addresses.json"
```
## Clean up
Stop all services running in the background:
```bash
laconic-so --stack mobymask-v3 deploy --cluster mobymask_v3 --exclude mobymask-app-v3 down
```
Clear volumes created by this stack:
```bash
# List all relevant volumes
docker volume ls -q --filter "name=mobymask_v3"
# Remove all the listed volumes
docker volume rm $(docker volume ls -q --filter "name=mobymask_v3")
# WARNING: To avoid changing peer ids for the watcher, `peers_ids` volume can be persisted
# To delete all volumes except for `peers_ids`
docker volume rm $(docker volume ls -q --filter "name=mobymask_v3" | grep -v "peers_ids$")
```
-89
View File
@@ -1,89 +0,0 @@
# MobyMask v3 App
## Setup
Prerequisite: Watcher with GQL and relay node endpoints
Clone required repositories:
```bash
laconic-so --stack mobymask-v3 setup-repositories --pull --include github.com/cerc-io/mobymask-ui
```
Build the container images:
```bash
laconic-so --stack mobymask-v3 build-containers --include cerc/mobymask-ui
```
## Deploy
### Configuration
Create and update an env file to be used in the next step ([defaults](../../config/watcher-mobymask-v3/mobymask-params.env)):
```bash
# Set of relay nodes to be used by the web-app
# (use double quotes " for strings, avoid space after commas)
# Eg. CERC_RELAY_NODES=["/dns4/example.com/tcp/443/wss/p2p/12D3KooWGHmDDCc93XUWL16FMcTPCGu2zFaMkf67k8HZ4gdQbRDr"]
CERC_RELAY_NODES=[]
# Set of multiaddrs to be avoided while dialling
CERC_DENY_MULTIADDRS=[]
# Also add if running MobyMask app:
# Watcher endpoint used by the app for GQL queries
CERC_APP_WATCHER_URL="http://127.0.0.1:3001"
# Set deployed MobyMask contract address to be used in MobyMask app's config
CERC_DEPLOYED_CONTRACT=
# L2 Chain ID used by mobymask web-app for L2 txs
CERC_CHAIN_ID=42069
# (Optional) Type of pubsub to be used ("floodsub" | "gossipsub")
CERC_PUBSUB=""
# (Optional) Set of direct peers to be used when pubsub is set to gossipsub
CERC_GOSSIPSUB_DIRECT_PEERS=[]
# Set Nitro addresses
CERC_NA_ADDRESS=
CERC_VPA_ADDRESS=
CERC_CA_ADDRESS=
# Nitro account address to make the query and mutation payments to
CERC_PAYMENT_NITRO_ADDRESS=
# (Optional) Endpoint for Mobymask snap installation
CERC_SNAP_URL=
```
### Deploy the stack
```bash
laconic-so --stack mobymask-v3 deploy --cluster mobymask_v3 --include mobymask-app-v3 --env-file <PATH_TO_ENV_FILE> up
# Runs the MobyMask v3 app on host port 3004
```
To list down and monitor the running containers:
```bash
laconic-so --stack mobymask-v3 deploy --cluster mobymask_v3 --include mobymask-app-v3 ps
# With status
docker ps -a
# Check logs for a container
docker logs -f <CONTAINER_ID>
```
## Clean up
Stop all services running in the background:
```bash
laconic-so --stack mobymask-v3 deploy --cluster mobymask_v3 --include mobymask-app-v3 down
```
+1 -1
View File
@@ -2,7 +2,7 @@ version: "1.1"
name: package-registry
description: "Local Package Registry"
repos:
- git.vdb.to/cerc-io/hosting
- github.com/cerc-io/hosting
- gitea.com/gitea/act_runner
containers:
- cerc/act-runner
+1 -1
View File
@@ -20,7 +20,7 @@ from app.deploy_util import VolumeMapping, run_container_command
from pathlib import Path
default_spec_file_content = """config:
test-variable-1: test-value-1
config_variable: test-value
"""
+15 -22
View File
@@ -20,12 +20,13 @@ import copy
import os
import sys
from dataclasses import dataclass
from decouple import config
from importlib import resources
import subprocess
from python_on_whales import DockerClient, DockerException
import click
from pathlib import Path
from app.util import include_exclude_check, get_parsed_stack_config, global_options2, get_dev_root_path
from app.util import include_exclude_check, get_parsed_stack_config, global_options2
from app.deploy_types import ClusterContext, DeployCommandContext
from app.deployment_create import create as deployment_create
from app.deployment_create import init as deployment_init
@@ -234,15 +235,17 @@ def _make_runtime_env(ctx):
# stack has to be either PathLike pointing to a stack yml file, or a string with the name of a known stack
def _make_cluster_context(ctx, stack, include, exclude, cluster, env_file):
dev_root_path = get_dev_root_path(ctx)
if ctx.local_stack:
dev_root_path = os.getcwd()[0:os.getcwd().rindex("stack-orchestrator")]
print(f'Local stack dev_root_path (CERC_REPO_BASE_DIR) overridden to: {dev_root_path}')
else:
dev_root_path = os.path.expanduser(config("CERC_REPO_BASE_DIR", default="~/cerc"))
# TODO: huge hack, fix this
# If the caller passed a path for the stack file, then we know that we can get the compose files
# from the same directory
deployment = False
if isinstance(stack, os.PathLike):
compose_dir = stack.parent.joinpath("compose")
deployment = True
else:
# See: https://stackoverflow.com/questions/25389095/python-get-path-of-root-project-structure
compose_dir = Path(__file__).absolute().parent.joinpath("data", "compose")
@@ -293,24 +296,14 @@ def _make_cluster_context(ctx, stack, include, exclude, cluster, env_file):
if pod_repository is None or pod_repository == "internal":
compose_file_name = os.path.join(compose_dir, f"docker-compose-{pod_path}.yml")
else:
if deployment:
compose_file_name = os.path.join(compose_dir, "docker-compose.yml")
pod_pre_start_command = pod["pre_start_command"]
pod_post_start_command = pod["post_start_command"]
script_dir = compose_dir.parent.joinpath("pods", pod_name, "scripts")
if pod_pre_start_command is not None:
pre_start_commands.append(os.path.join(script_dir, pod_pre_start_command))
if pod_post_start_command is not None:
post_start_commands.append(os.path.join(script_dir, pod_post_start_command))
else:
pod_root_dir = os.path.join(dev_root_path, pod_repository.split("/")[-1], pod["path"])
compose_file_name = os.path.join(pod_root_dir, "docker-compose.yml")
pod_pre_start_command = pod["pre_start_command"]
pod_post_start_command = pod["post_start_command"]
if pod_pre_start_command is not None:
pre_start_commands.append(os.path.join(pod_root_dir, pod_pre_start_command))
if pod_post_start_command is not None:
post_start_commands.append(os.path.join(pod_root_dir, pod_post_start_command))
pod_root_dir = os.path.join(dev_root_path, pod_repository.split("/")[-1], pod["path"])
compose_file_name = os.path.join(pod_root_dir, "docker-compose.yml")
pod_pre_start_command = pod["pre_start_command"]
pod_post_start_command = pod["post_start_command"]
if pod_pre_start_command is not None:
pre_start_commands.append(os.path.join(pod_root_dir, pod_pre_start_command))
if pod_post_start_command is not None:
post_start_commands.append(os.path.join(pod_root_dir, pod_post_start_command))
compose_files.append(compose_file_name)
else:
if ctx.verbose:
+2 -2
View File
@@ -16,14 +16,14 @@
import os
from typing import List
from app.deploy_types import DeployCommandContext, VolumeMapping
from app.util import get_parsed_stack_config, get_yaml, get_compose_file_dir, get_pod_list
from app.util import get_parsed_stack_config, get_yaml, get_compose_file_dir
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)
pods = get_pod_list(parsed_stack)
pods = parsed_stack["pods"]
yaml = get_yaml()
for pod in pods:
pod_file_path = os.path.join(get_compose_file_dir(), f"docker-compose-{pod}.yml")
+4 -14
View File
@@ -25,16 +25,6 @@ from app.deploy import exec_operation, logs_operation, create_deploy_context
class DeploymentContext:
dir: Path
def get_stack_file(self):
return self.dir.joinpath("stack.yml")
def get_env_file(self):
return self.dir.joinpath("config.env")
# TODO: implement me
def get_cluster_name(self):
return None
@click.group()
@click.option("--dir", required=True, help="path to deployment directory")
@@ -59,10 +49,10 @@ def command(ctx, dir):
def make_deploy_context(ctx):
stack_file_path = ctx.obj.get_stack_file()
env_file = ctx.obj.get_env_file()
cluster_name = ctx.obj.get_cluster_name()
return create_deploy_context(ctx.parent.parent.obj, stack_file_path, None, None, cluster_name, env_file)
# Get the stack config file name
stack_file_path = ctx.obj.dir.joinpath("stack.yml")
# TODO: add cluster name and env file here
return create_deploy_context(ctx.parent.parent.obj, stack_file_path, None, None, None, None)
@command.command()
+22 -94
View File
@@ -17,13 +17,12 @@ import click
from importlib import util
import os
from pathlib import Path
from typing import List
import random
from shutil import copy, copyfile, copytree
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_pod_list, get_pod_file_path, pod_has_scripts, get_pod_script_paths, get_plugin_code_path)
from app.deploy_types import DeploymentContext, DeployCommandContext, LaconicStackSetupCommand
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():
@@ -33,10 +32,10 @@ def _make_default_deployment_dir():
def _get_ports(stack):
ports = {}
parsed_stack = get_parsed_stack_config(stack)
pods = get_pod_list(parsed_stack)
pods = parsed_stack["pods"]
yaml = get_yaml()
for pod in pods:
pod_file_path = get_pod_file_path(parsed_stack, pod)
pod_file_path = os.path.join(get_compose_file_dir(), f"docker-compose-{pod}.yml")
parsed_pod_file = yaml.load(open(pod_file_path, "r"))
if "services" in parsed_pod_file:
for svc_name, svc in parsed_pod_file["services"].items():
@@ -50,10 +49,10 @@ def _get_named_volumes(stack):
# Parse the compose files looking for named volumes
named_volumes = []
parsed_stack = get_parsed_stack_config(stack)
pods = get_pod_list(parsed_stack)
pods = parsed_stack["pods"]
yaml = get_yaml()
for pod in pods:
pod_file_path = get_pod_file_path(parsed_stack, pod)
pod_file_path = os.path.join(get_compose_file_dir(), f"docker-compose-{pod}.yml")
parsed_pod_file = yaml.load(open(pod_file_path, "r"))
if "volumes" in parsed_pod_file:
volumes = parsed_pod_file["volumes"]
@@ -106,27 +105,16 @@ def _fixup_pod_file(pod, spec, compose_dir):
pod["services"][container_name]["ports"] = container_ports
def _commands_plugin_path(ctx: DeployCommandContext):
plugin_path = get_plugin_code_path(ctx.stack)
return plugin_path.joinpath("deploy", "commands.py")
# See: https://stackoverflow.com/a/54625079/1701505
def _has_method(o, name):
return callable(getattr(o, name, None))
def call_stack_deploy_init(deploy_command_context):
# Link with the python file in the stack
# Call a function in it
# If no function found, return None
python_file_path = _commands_plugin_path(deploy_command_context)
python_file_path = get_stack_file_path(deploy_command_context.stack).parent.joinpath("deploy", "commands.py")
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)
if _has_method(imported_stack, "init"):
return imported_stack.init(deploy_command_context)
return imported_stack.init(deploy_command_context)
else:
return None
@@ -136,14 +124,12 @@ def call_stack_deploy_setup(deploy_command_context, parameters: LaconicStackSetu
# Link with the python file in the stack
# Call a function in it
# If no function found, return None
python_file_path = _commands_plugin_path(deploy_command_context)
print(f"Path: {python_file_path}")
python_file_path = get_stack_file_path(deploy_command_context.stack).parent.joinpath("deploy", "commands.py")
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)
if _has_method(imported_stack, "setup"):
return imported_stack.setup(deploy_command_context, parameters, extra_args)
return imported_stack.setup(deploy_command_context, parameters, extra_args)
else:
return None
@@ -153,13 +139,12 @@ 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 = _commands_plugin_path(deployment_context.command_context)
python_file_path = get_stack_file_path(deployment_context.command_context.stack).parent.joinpath("deploy", "commands.py")
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)
if _has_method(imported_stack, "create"):
return imported_stack.create(deployment_context, extra_args)
return imported_stack.create(deployment_context, extra_args)
else:
return None
@@ -193,18 +178,16 @@ def _get_mapped_ports(stack: str, map_recipe: str):
ports_array = ports[service]
for x in range(0, len(ports_array)):
orig_port = ports_array[x]
# Strip /udp suffix if present
bare_orig_port = orig_port.replace("/udp", "")
random_port = random.randint(20000, 50000) # Beware: we're relying on luck to not collide
if map_recipe == "any-variable-random":
# This is the default so take no action
pass
elif map_recipe == "localhost-same":
# Replace instances of "- XX" with "- 127.0.0.1:XX"
ports_array[x] = f"127.0.0.1:{bare_orig_port}:{orig_port}"
ports_array[x] = f"127.0.0.1:{orig_port}:{orig_port}"
elif map_recipe == "any-same":
# Replace instances of "- XX" with "- 0.0.0.0:XX"
ports_array[x] = f"0.0.0.0:{bare_orig_port}:{orig_port}"
ports_array[x] = f"0.0.0.0:{orig_port}:{orig_port}"
elif map_recipe == "localhost-fixed-random":
# Replace instances of "- XX" with "- 127.0.0.1:<rnd>:XX"
ports_array[x] = f"127.0.0.1:{random_port}:{orig_port}"
@@ -219,48 +202,22 @@ def _get_mapped_ports(stack: str, map_recipe: str):
return ports
def _parse_config_variables(variable_values: str):
result = None
if variable_values:
value_pairs = variable_values.split(",")
if len(value_pairs):
result_values = {}
for value_pair in value_pairs:
variable_value_pair = value_pair.split("=")
if len(variable_value_pair) != 2:
print(f"ERROR: config argument is not valid: {variable_values}")
sys.exit(1)
variable_name = variable_value_pair[0]
variable_value = variable_value_pair[1]
result_values[variable_name] = variable_value
result = {"config": result_values}
return result
@click.command()
@click.option("--config", help="Provide config variables for the deployment")
@click.option("--output", required=True, help="Write yaml spec file here")
@click.option("--map-ports-to-host", required=False,
help="Map ports to the host as one of: any-variable-random (default), "
"localhost-same, any-same, localhost-fixed-random, any-fixed-random")
@click.pass_context
def init(ctx, config, output, map_ports_to_host):
def init(ctx, output, map_ports_to_host):
yaml = get_yaml()
stack = global_options(ctx).stack
debug = global_options(ctx).debug
verbose = global_options(ctx).verbose
default_spec_file_content = call_stack_deploy_init(ctx.obj)
spec_file_content = {"stack": stack}
if default_spec_file_content:
spec_file_content.update(default_spec_file_content)
config_variables = _parse_config_variables(config)
if config_variables:
# Implement merge, since update() overwrites
orig_config = spec_file_content["config"]
new_config = config_variables["config"]
merged_config = {**new_config, **orig_config}
spec_file_content.update({"config": merged_config})
if debug:
print(f"Creating spec file for stack: {stack} with content: {spec_file_content}")
if verbose:
print(f"Creating spec file for stack: {stack}")
ports = _get_mapped_ports(stack, map_ports_to_host)
spec_file_content["ports"] = ports
@@ -276,23 +233,6 @@ def init(ctx, config, output, map_ports_to_host):
yaml.dump(spec_file_content, output_file)
def _write_config_file(spec_file: Path, config_env_file: Path):
spec_content = get_parsed_deployment_spec(spec_file)
# Note: we want to write an empty file even if we have no config variables
with open(config_env_file, "w") as output_file:
if "config" in spec_content and spec_content["config"]:
config_vars = spec_content["config"]
if config_vars:
for variable_name, variable_value in config_vars.items():
output_file.write(f"{variable_name}={variable_value}\n")
def _copy_files_to_directory(file_paths: List[Path], directory: Path):
for path in file_paths:
# Using copy to preserve the execute bit
copy(path, os.path.join(directory, os.path.basename(path)))
@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")
@@ -317,22 +257,16 @@ def create(ctx, spec_file, deployment_dir, network_dir, initial_peers):
# Copy spec file and the stack file into the deployment dir
copyfile(spec_file, os.path.join(deployment_dir, os.path.basename(spec_file)))
copyfile(stack_file, os.path.join(deployment_dir, os.path.basename(stack_file)))
# Copy any config varibles from the spec file into an env file suitable for compose
_write_config_file(spec_file, os.path.join(deployment_dir, "config.env"))
# Copy the pod files into the deployment dir, fixing up content
pods = get_pod_list(parsed_stack)
pods = parsed_stack['pods']
destination_compose_dir = os.path.join(deployment_dir, "compose")
os.mkdir(destination_compose_dir)
destination_pods_dir = os.path.join(deployment_dir, "pods")
os.mkdir(destination_pods_dir)
data_dir = Path(__file__).absolute().parent.joinpath("data")
yaml = get_yaml()
for pod in pods:
pod_file_path = get_pod_file_path(parsed_stack, pod)
pod_file_path = os.path.join(get_compose_file_dir(), f"docker-compose-{pod}.yml")
parsed_pod_file = yaml.load(open(pod_file_path, "r"))
extra_config_dirs = _find_extra_config_dirs(parsed_pod_file, pod)
destination_pod_dir = os.path.join(destination_pods_dir, pod)
os.mkdir(destination_pod_dir)
if global_options(ctx).debug:
print(f"extra config dirs: {extra_config_dirs}")
_fixup_pod_file(parsed_pod_file, parsed_spec, destination_compose_dir)
@@ -348,12 +282,6 @@ def create(ctx, spec_file, deployment_dir, network_dir, initial_peers):
# If the same config dir appears in multiple pods, it may already have been copied
if not os.path.exists(destination_config_dir):
copytree(source_config_dir, destination_config_dir)
# Copy the script files for the pod, if any
if pod_has_scripts(parsed_stack, pod):
destination_script_dir = os.path.join(destination_pod_dir, "scripts")
os.mkdir(destination_script_dir)
script_paths = get_pod_script_paths(parsed_stack, pod)
_copy_files_to_directory(script_paths, destination_script_dir)
# Delegate to the stack's Python code
# The deploy create command doesn't require a --stack argument so we need to insert the
# stack member here.
-90
View File
@@ -1,90 +0,0 @@
# Copyright © 2023 Vulcanize
# 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/>.
import click
import datetime
import filecmp
import os
from pathlib import Path
import requests
import sys
import stat
import shutil
import validators
from app.util import get_yaml
def _download_url(url: str, file_path: Path):
r = requests.get(url, stream=True)
r.raw.decode_content = True
with open(file_path, 'wb') as f:
shutil.copyfileobj(r.raw, f)
def _error_exit(s: str):
print(s)
sys.exit(1)
# Note at present this probably won't work on non-Unix based OSes like Windows
@click.command()
@click.option("--check-only", is_flag=True, default=False, help="only check, don't update")
@click.pass_context
def command(ctx, check_only):
'''update shiv binary from a distribution url'''
# Get the distribution URL from config
config_key = 'distribution-url'
config_file_path = Path(os.path.expanduser("~/.laconic-so/config.yml"))
if not config_file_path.exists():
_error_exit(f"Error: Config file: {config_file_path} not found")
yaml = get_yaml()
config = yaml.load(open(config_file_path, "r"))
if "distribution-url" not in config:
_error_exit(f"Error: {config_key} not defined in {config_file_path}")
distribution_url = config[config_key]
# Sanity check the URL
if not validators.url(distribution_url):
_error_exit(f"ERROR: distribution url: {distribution_url} is not valid")
# Figure out the filename for ourselves
shiv_binary_path = Path(sys.argv[0])
timestamp_filename = f"laconic-so-download-{datetime.datetime.now().strftime('%y%m%d-%H%M%S')}"
temp_download_path = shiv_binary_path.parent.joinpath(timestamp_filename)
# Download the file to a temp filename
if ctx.obj.verbose:
print(f"Downloading from: {distribution_url} to {temp_download_path}")
_download_url(distribution_url, temp_download_path)
# Set the executable bit
existing_mode = os.stat(temp_download_path)
os.chmod(temp_download_path, existing_mode.st_mode | stat.S_IXUSR)
# Switch the new file for the path we ran from
# Check if the downloaded file is identical to the existing one
same = filecmp.cmp(temp_download_path, shiv_binary_path)
if same:
if not ctx.obj.quiet or check_only:
print("No update available, latest version already installed")
else:
if not ctx.obj.quiet:
print("Update available")
if check_only:
if not ctx.obj.quiet:
print("Check-only node, update not installed")
else:
if not ctx.obj.quiet:
print("Installing...")
if ctx.obj.verbose:
print(f"Replacing: {shiv_binary_path} with {temp_download_path}")
os.replace(temp_download_path, shiv_binary_path)
if not ctx.obj.quiet:
print("Run \"laconic-so version\" to see the newly installed version")
-73
View File
@@ -13,7 +13,6 @@
# 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 decouple import config
import os.path
import sys
import ruamel.yaml
@@ -38,16 +37,6 @@ def get_stack_file_path(stack):
return stack_file_path
def get_dev_root_path(ctx):
if ctx and ctx.local_stack:
# TODO: This code probably doesn't work
dev_root_path = os.getcwd()[0:os.getcwd().rindex("stack-orchestrator")]
print(f'Local stack dev_root_path (CERC_REPO_BASE_DIR) overridden to: {dev_root_path}')
else:
dev_root_path = os.path.expanduser(config("CERC_REPO_BASE_DIR", default="~/cerc"))
return dev_root_path
# Caller can pass either the name of a stack, or a path to a stack file
def get_parsed_stack_config(stack):
stack_file_path = stack if isinstance(stack, os.PathLike) else get_stack_file_path(stack)
@@ -67,68 +56,6 @@ def get_parsed_stack_config(stack):
sys.exit(1)
def get_pod_list(parsed_stack):
# Handle both old and new format
pods = parsed_stack["pods"]
if type(pods[0]) is str:
result = pods
else:
result = []
for pod in pods:
result.append(pod["name"])
return result
def get_plugin_code_path(stack):
parsed_stack = get_parsed_stack_config(stack)
pods = parsed_stack["pods"]
# TODO: Hack
pod = pods[0]
if type(pod) is str:
result = get_stack_file_path(stack).parent
else:
pod_root_dir = os.path.join(get_dev_root_path(None), pod["repository"].split("/")[-1], pod["path"])
result = Path(os.path.join(pod_root_dir, "stack"))
return result
def get_pod_file_path(parsed_stack, pod_name: str):
pods = parsed_stack["pods"]
if type(pods[0]) is str:
result = os.path.join(get_compose_file_dir(), f"docker-compose-{pod_name}.yml")
else:
for pod in pods:
if pod["name"] == pod_name:
pod_root_dir = os.path.join(get_dev_root_path(None), pod["repository"].split("/")[-1], pod["path"])
result = os.path.join(pod_root_dir, "docker-compose.yml")
return result
def get_pod_script_paths(parsed_stack, pod_name: str):
pods = parsed_stack["pods"]
result = []
if not type(pods[0]) is str:
for pod in pods:
if pod["name"] == pod_name:
pod_root_dir = os.path.join(get_dev_root_path(None), pod["repository"].split("/")[-1], pod["path"])
if "pre_start_command" in pod:
result.append(os.path.join(pod_root_dir, pod["pre_start_command"]))
if "post_start_command" in pod:
result.append(os.path.join(pod_root_dir, pod["post_start_command"]))
return result
def pod_has_scripts(parsed_stack, pod_name: str):
pods = parsed_stack["pods"]
if type(pods[0]) is str:
result = False
else:
for pod in pods:
if pod["name"] == pod_name:
result = "pre_start_command" in pod or "post_start_command" in pod
return result
def get_compose_file_dir():
# TODO: refactor to use common code with deploy command
# See: https://stackoverflow.com/questions/25389095/python-get-path-of-root-project-structure
-2
View File
@@ -22,7 +22,6 @@ from app import build_npms
from app import deploy
from app import version
from app import deployment
from app import update
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
@@ -49,4 +48,3 @@ cli.add_command(deploy.command, "deploy") # deploy is an alias for deploy-syste
cli.add_command(deploy.command, "deploy-system")
cli.add_command(deployment.command, "deployment")
cli.add_command(version.command, "version")
cli.add_command(update.command, "update")
-8
View File
@@ -1,8 +0,0 @@
# Stack Orchestrator
Here you will find information about the design of stack orchestrator, contributing to it, and deploying services/applications that combine two or more "stacks".
Most "stacks" contain their own README which has plenty of information on deploying, but stacks can be combined in a variety of ways which are document here, for example:
- [Gitea with Laconicd Fixturenet](./gitea-with-laconicd-fixturenet.md)
- [Laconicd Registry with Console](./laconicd-with-console.md)
-71
View File
@@ -1,71 +0,0 @@
# Adding a new stack
See [this PR](https://github.com/cerc-io/stack-orchestrator/pull/434) for an example of how to currently add a minimal stack to stack orchestrator. The [reth stack](https://github.com/cerc-io/stack-orchestrator/pull/435) is another good example.
For external developers, we recommend forking this repo and adding your stack directly to your fork. This initially requires running in "developer mode" as described [here](/docs/CONTRIBUTING.md). Check out the [Namada stack](https://github.com/vknowable/stack-orchestrator/blob/main/app/data/stacks/public-namada/digitalocean_quickstart.md) from Knowable to see how that is done.
Core to the feature completeness of stack orchestrator is to [decouple the tool functionality from payload](https://github.com/cerc-io/stack-orchestrator/issues/315) which will no longer require forking to add a stack.
## Example
- in `app/data/stacks/my-new-stack/stack.yml` add:
```yaml
version: "0.1"
name: my-new-stack
repos:
- github.com/my-org/my-new-stack
containers:
- cerc/my-new-stack
pods:
- my-new-stack
```
- in `app/data/container-build/cerc-my-new-stack/build.sh` add:
```yaml
#!/usr/bin/env bash
# Build the my-new-stack image
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
docker build -t cerc/my-new-stack:local -f ${CERC_REPO_BASE_DIR}/my-new-stack/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/my-new-stack
```
- in `app/data/compose/docker-compose-my-new-stack.yml` add:
```yaml
version: "3.2"
services:
my-new-stack:
image: cerc/my-new-stack:local
restart: always
ports:
- "0.0.0.0:3000:3000"
```
- in `app/data/repository-list.txt` add:
```bash
github.com/my-org/my-new-stack
```
whereby that repository contains your source code and a `Dockerfile`, and matches the `repos:` field in the `stack.yml`.
- in `app/data/container-image-list.txt` add:
```bash
cerc/my-new-stack
```
- in `app/data/pod-list.txt` add:
```bash
my-new-stack
```
Now, the following commands will fetch, build, and deploy you app:
```bash
laconic-so --stack my-new-stack setup-repositories
laconic-so --stack my-new-stack build-containers
laconic-so --stack my-new-stack deploy-system up
```
+1 -1
View File
@@ -6,7 +6,7 @@ Sub-commands and flags
Clone a single repository:
```
$ laconic-so setup-repositories --include github.com/cerc-io/go-ethereum
$ laconic-so setup-repositories --include cerc-io/go-ethereum
```
Clone the repositories for a stack:
```
-80
View File
@@ -1,80 +0,0 @@
# Gitea x NPMs X Laconicd
Deploy a local Gitea server, publish NPM packages to it, then use those packages to build a Laconicd fixturenet. Demonstrates several components of the Laconic stack
### Build and Deploy Gitea
```bash
laconic-so --stack build-support build-containers
laconic-so --stack package-registry setup-repositories
laconic-so --stack package-registry build-containers
laconic-so --stack package-registry deploy up
```
These commands can take awhile. Eventually, some instructions and a token will output. Set `CERC_NPM_AUTH_TOKEN`:
```bash
export CERC_NPM_AUTH_TOKEN=<your-token>
```
### Configure the hostname gitea.local
How to do this depends on your operating system but usually involves editing a `hosts` file. For example, on Linux add this line to the file `/etc/hosts` (needs sudo):
```bash
127.0.0.1 gitea.local
```
Test with:
```bash
ping gitea.local
```
```bash
PING gitea.local (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.147 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.033 ms
```
Although not necessary in order to build and publish packages, you can now access the Gitea web interface at: [http://gitea.local:3000](http://gitea.local:3000) using these credentials: `gitea_admin/admin1234` (Note: please properly secure Gitea if public internet access is allowed).
### Build npm Packages
Clone the required repositories:
```bash
laconic-so --stack fixturenet-laconicd setup-repositories
```
Build and publish the npm packages:
```bash
laconic-so --stack fixturenet-laconicd build-npms
```
Navigate to the Gitea console and switch to the `cerc-io` user then find the `Packages` tab to confirm that these two npm packages have been published:
- `@cerc-io/laconic-registry-cli`
- `@cerc-io/laconic-sdk`
### Build and deploy fixturenet containers
```bash
laconic-so --stack fixturenet-laconicd build-containers
laconic-so --stack fixturenet-laconicd deploy up
```
Check the logs:
```bash
laconic-so --stack fixturenet-laconicd deploy logs
```
### Test with the registry CLI
```bash
laconic-so --stack fixturenet-laconicd deploy exec cli "laconic cns status"
```
Try additional CLI commands, documented [here](https://github.com/cerc-io/laconic-registry-cli#operations).
+2 -1
View File
@@ -1,6 +1,7 @@
# Specification
Note: this page is out of date (but still useful) - it will no longer be useful once stacks are [decoupled from the tool functionality](https://github.com/cerc-io/stack-orchestrator/issues/315).
(note this page is out of date)
## Implementation
-1
View File
@@ -7,4 +7,3 @@ PyYAML>=6.0.1
ruamel.yaml>=0.17.32
pydantic==1.10.9
tomli==2.0.1
validators==0.22.0
+1 -11
View File
@@ -5,9 +5,6 @@ fi
install_dir=~/bin
# Skip the package install stuff if so directed
if ! [[ -n "$CERC_SO_INSTALL_SKIP_PACKAGES" ]]; then
# First display a reasonable warning to the user unless run with -y
if ! [[ $# -eq 1 && $1 == "-y" ]]; then
echo "**************************************************************************************"
@@ -131,20 +128,13 @@ sudo apt -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin d
# Allow the current user to use Docker
sudo usermod -aG docker $USER
# End of long if block: Skip the package install stuff if so directed
fi
echo "**************************************************************************************"
echo "Installing laconic-so"
# install latest `laconic-so`
distribution_url=https://github.com/cerc-io/stack-orchestrator/releases/latest/download/laconic-so
install_filename=${install_dir}/laconic-so
mkdir -p ${install_dir}
curl -L -o ${install_filename} ${distribution_url}
curl -L -o ${install_filename} https://github.com/cerc-io/stack-orchestrator/releases/latest/download/laconic-so
chmod +x ${install_filename}
# Set up config file for self-update feature
mkdir ~/.laconic-so
echo "distribution-url: ${distribution_url}" > ~/.laconic-so/config.yml
echo "**************************************************************************************"
# Check if our PATH line is already there
+2 -1
View File
@@ -19,7 +19,8 @@ setup(
install_requires=[requirements],
python_requires='>=3.7',
include_package_data=True,
package_data={'': ['data/**']},
# See: https://github.com/pypa/setuptools/issues/1806
package_data={'': ['data/*', 'data/*/*', 'data/*/*/*', 'data/*/*/*/*', 'data/*/*/*/*/*']},
classifiers=[
"Programming Language :: Python :: 3.8",
"Operating System :: OS Independent",
+3 -10
View File
@@ -77,7 +77,7 @@ $TEST_TARGET_SO --stack test deploy down --delete-volumes
# Basic test of creating a deployment
test_deployment_dir=$CERC_REPO_BASE_DIR/test-deployment-dir
test_deployment_spec=$CERC_REPO_BASE_DIR/test-deployment-spec.yml
$TEST_TARGET_SO --stack test deploy init --output $test_deployment_spec --config CERC_TEST_PARAM_1=PASSED
$TEST_TARGET_SO --stack test deploy init --output $test_deployment_spec
# Check the file now exists
if [ ! -f "$test_deployment_spec" ]; then
echo "deploy init test: spec file not present"
@@ -110,20 +110,13 @@ echo "deploy create output file test: passed"
# Try to start the deployment
$TEST_TARGET_SO deployment --dir $test_deployment_dir start
# Check logs command works
log_output_3=$( $TEST_TARGET_SO deployment --dir $test_deployment_dir logs )
if [[ "$log_output_3" == *"Filesystem is fresh"* ]]; then
log_output_2=$( $TEST_TARGET_SO deployment --dir $test_deployment_dir logs )
if [[ "$log_output_2" == *"Filesystem is fresh"* ]]; then
echo "deployment logs test: passed"
else
echo "deployment logs test: FAILED"
exit 1
fi
# Check the config variable CERC_TEST_PARAM_1 was passed correctly
if [[ "$log_output_3" == *"Test-param-1: PASSED"* ]]; then
echo "deployment config test: passed"
else
echo "deployment config test: FAILED"
exit 1
fi
# Stop and clean up
$TEST_TARGET_SO deployment --dir $test_deployment_dir stop --delete-volumes
echo "Test passed"