From ff44728ecf82717d2ed0c51af8c09083dc5a16a7 Mon Sep 17 00:00:00 2001 From: Alexander Sysoev Date: Tue, 28 Nov 2023 16:01:22 +0300 Subject: [PATCH] Update docker-compose deployments (#156) * Update docker-compose deployments Signed-off-by: cyc60 * Bump version Signed-off-by: cyc60 --------- Signed-off-by: cyc60 --- deploy/gnosis/docker-compose.yml | 4 +- deploy/goerli/docker-compose.yml | 4 +- deploy/harbour_goerli/.env.example | 92 --------- deploy/harbour_goerli/docker-compose.yml | 237 ---------------------- deploy/harbour_mainnet/.env.example | 92 --------- deploy/harbour_mainnet/docker-compose.yml | 236 --------------------- deploy/mainnet/docker-compose.yml | 4 +- pyproject.toml | 2 +- 8 files changed, 7 insertions(+), 664 deletions(-) delete mode 100644 deploy/harbour_goerli/.env.example delete mode 100644 deploy/harbour_goerli/docker-compose.yml delete mode 100644 deploy/harbour_mainnet/.env.example delete mode 100644 deploy/harbour_mainnet/docker-compose.yml diff --git a/deploy/gnosis/docker-compose.yml b/deploy/gnosis/docker-compose.yml index 5b7f009..0cc96ac 100644 --- a/deploy/gnosis/docker-compose.yml +++ b/deploy/gnosis/docker-compose.yml @@ -24,7 +24,7 @@ networks: services: oracle: container_name: oracle_gnosis - image: europe-west4-docker.pkg.dev/stakewiselabs/public/oracle:v3.0.0 + image: europe-west4-docker.pkg.dev/stakewiselabs/public/oracle:v3.1.0 restart: always entrypoint: ["python"] command: ["oracle/oracle/main.py"] @@ -34,7 +34,7 @@ services: keeper: container_name: keeper_gnosis - image: europe-west4-docker.pkg.dev/stakewiselabs/public/oracle:v3.0.0 + image: europe-west4-docker.pkg.dev/stakewiselabs/public/oracle:v3.1.0 restart: always entrypoint: ["python"] command: ["oracle/keeper/main.py"] diff --git a/deploy/goerli/docker-compose.yml b/deploy/goerli/docker-compose.yml index 7657b90..f96d8d5 100644 --- a/deploy/goerli/docker-compose.yml +++ b/deploy/goerli/docker-compose.yml @@ -26,7 +26,7 @@ networks: services: oracle: container_name: oracle_goerli - image: europe-west4-docker.pkg.dev/stakewiselabs/public/oracle:v3.0.0 + image: europe-west4-docker.pkg.dev/stakewiselabs/public/oracle:v3.3.0 restart: always entrypoint: ["python"] command: ["oracle/oracle/main.py"] @@ -36,7 +36,7 @@ services: keeper: container_name: keeper_goerli - image: europe-west4-docker.pkg.dev/stakewiselabs/public/oracle:v3.0.0 + image: europe-west4-docker.pkg.dev/stakewiselabs/public/oracle:v3.3.0 restart: always entrypoint: ["python"] command: ["oracle/keeper/main.py"] diff --git a/deploy/harbour_goerli/.env.example b/deploy/harbour_goerli/.env.example deleted file mode 100644 index 8a41e47..0000000 --- a/deploy/harbour_goerli/.env.example +++ /dev/null @@ -1,92 +0,0 @@ -########## -# Oracle # -########## -LOG_LEVEL=INFO -NETWORK=harbour_goerli -ENABLE_HEALTH_SERVER=true -HEALTH_SERVER_PORT=8080 -HEALTH_SERVER_HOST=0.0.0.0 - -# Uncomment LOCAL_IPFS_CLIENT_ENDPOINT if you are using "ipfs" profile -#LOCAL_IPFS_CLIENT_ENDPOINT="/dns/ipfs/tcp/5001/http" - -INFURA_IPFS_CLIENT_ENDPOINT=/dns/ipfs.infura.io/tcp/5001/https -INFURA_IPFS_CLIENT_USERNAME= -INFURA_IPFS_CLIENT_PASSWORD= - -# Optionally pin merkle proofs to the pinata service for redundancy -IPFS_PINATA_API_KEY= -IPFS_PINATA_SECRET_KEY= - -# Change https://api.thegraph.com to http://graph-node:8000 if running local graph node -STAKEWISE_SUBGRAPH_URLS=https://api.thegraph.com/subgraphs/name/stakewise/stakewise-perm-goerli -ETHEREUM_SUBGRAPH_URLS=https://api.thegraph.com/subgraphs/name/stakewise/ethereum-goerli - -# Ethereum private key -# NB! You must use a different private key for every network -ORACLE_PRIVATE_KEY=0x - -# ETH1 (execution) client endpoint -# Change if running an external ETH1 node -ETH1_ENDPOINT=http://eth1-node:8545 - -# ETH2 (consensus) client endpoint -# Change if running an external ETH2 node -ETH2_ENDPOINT=http://eth2-node:5052 - -# AWS bucket to publish oracle votes to -AWS_ACCESS_KEY_ID= -AWS_SECRET_ACCESS_KEY= -AWS_BUCKET_NAME=oracle-votes-perm-goerli -AWS_REGION=eu-central-1 - -########## -# Keeper # -########## -# Change if running an external ETH1 node -KEEPER_ETH1_ENDPOINT=http://eth1-node:8545 -# Use https://eth-converter.com/ to calculate -KEEPER_MIN_BALANCE_WEI=100000000000000000 -KEEPER_MAX_FEE_PER_GAS_GWEI=150 - -######## -# IPFS # -######## -IPFS_URL=http://ipfs:5001 -IPFS_PROFILE=server -IPFS_FD_MAX=8192 - -############# -# ETH2 Node # -############# -ETH1_AUTH_ENDPOINT=http://eth1-node:8551 - -############## -# Graph Node # -############## -GRAPH_LOG=info -GRAPH_NODE_URL=http://graph-node:8020 -# Change if running remote IPFS node -ipfs=ipfs:5001 -# Change if running an external ETH1 node -# NB! If syncing graph node from scratch archive node must be used. -# It can be switched to fast-sync node once fully synced. -ethereum=goerli:http://eth1-node:8545 -# Postgres DB settings for graph node -postgres_host=postgres -postgres_user=graph -postgres_pass=strong-password -postgres_db=graph-node - -############ -# Postgres # -############ -# postgres is used by local graph node -POSTGRES_DB=graph-node -POSTGRES_USER=graph -POSTGRES_PASSWORD=strong-password - -############ -# SENTRY # -############ -# SENTRY_DSN= diff --git a/deploy/harbour_goerli/docker-compose.yml b/deploy/harbour_goerli/docker-compose.yml deleted file mode 100644 index cd22d2b..0000000 --- a/deploy/harbour_goerli/docker-compose.yml +++ /dev/null @@ -1,237 +0,0 @@ -version: "3.9" - -volumes: - prometheus: - driver: local - alertmanager: - driver: local - postgres: - driver: local - ipfs: - driver: local - geth: - driver: local - besu: - driver: local - prysm: - driver: local - lighthouse: - driver: local - -networks: - harbour_goerli: - name: harbour_goerli - driver: bridge - -services: - oracle: - container_name: oracle_harbour_goerli - image: europe-west4-docker.pkg.dev/stakewiselabs/public/oracle:v3.0.0 - restart: always - entrypoint: ["python"] - command: ["oracle/oracle/main.py"] - env_file: [".env"] - networks: - - harbour_goerli - - keeper: - container_name: keeper_harbour_goerli - image: europe-west4-docker.pkg.dev/stakewiselabs/public/oracle:v3.0.0 - restart: always - entrypoint: ["python"] - command: ["oracle/keeper/main.py"] - env_file: [".env"] - profiles: ["keeper"] - networks: - - harbour_goerli - - prometheus: - container_name: prometheus_harbour_goerli - image: bitnami/prometheus:2 - restart: always - env_file: [".env"] - volumes: - - prometheus:/opt/bitnami/prometheus/data - - ../configs/prometheus.yml:/opt/bitnami/prometheus/conf/prometheus.yml - - ../configs/rules.yml:/opt/bitnami/prometheus/conf/rules.yml - networks: - - harbour_goerli - - alertmanager: - container_name: alertmanager_harbour_goerli - image: bitnami/alertmanager:0 - restart: always - env_file: [".env"] - volumes: - - alertmanager:/opt/bitnami/alertmanager/data - - ../configs/alertmanager.yml:/opt/bitnami/alertmanager/conf/config.yml - depends_on: ["prometheus"] - networks: - - harbour_goerli - - graph-node: - container_name: graph_node_harbour_goerli - image: graphprotocol/graph-node:v0.25.2 - restart: always - env_file: [".env"] - depends_on: ["postgres","ipfs"] - profiles: ["graph"] - networks: - - harbour_goerli - - postgres: - container_name: postgres_harbour_goerli - image: postgres:14-alpine - restart: always - command: ["postgres", "-cshared_preload_libraries=pg_stat_statements"] - env_file: [".env"] - volumes: ["postgres:/var/lib/postgresql/data"] - profiles: ["graph"] - networks: - - harbour_goerli - - subgraphs: - container_name: subgraphs_harbour_goerli - image: europe-west4-docker.pkg.dev/stakewiselabs/public/subgraphs:v1.3.0 - command: > - /bin/sh -c "until nc -vz graph-node 8020; do echo 'Waiting graph-node'; sleep 2; done - && yarn build:harbour_goerli - && yarn create:local - && yarn deploy:local" - env_file: [".env"] - restart: "no" - depends_on: ["graph-node","ipfs"] - profiles: ["graph"] - networks: - - harbour_goerli - - ipfs: - container_name: ipfs_harbour_goerli - image: ipfs/go-ipfs:v0.12.1 - restart: always - env_file: [".env"] - ulimits: - nofile: - soft: 8192 - hard: 8192 - volumes: ["ipfs:/data/ipfs","../configs/ipfs-entrypoint.sh:/usr/local/bin/start_ipfs"] - profiles: ["ipfs"] - networks: - - harbour_goerli - - geth: - container_name: geth_harbour_goerli - image: ethereum/client-go:v1.12.0 - restart: always - command: - - --goerli - - --syncmode=full - - --authrpc.jwtsecret=/jwtsecret - - --authrpc.addr=0.0.0.0 - - --authrpc.port=8551 - - --authrpc.vhosts=* - - --http - - --http.addr=0.0.0.0 - - --http.port=8545 - - --http.vhosts=* - - --http.api=web3,eth,net - - --datadir=/data/ethereum - - --ethash.dagdir=/data/ethereum/.ethash - - --ipcdisable - - --port=30300 - volumes: ["geth:/data","../configs/jwtsecret:/jwtsecret"] - profiles: ["geth"] - ports: - - 30300:30300/tcp - - 30300:30300/udp - networks: - harbour_goerli: - aliases: - - eth1-node - - besu: - container_name: besu_harbour_goerli - image: hyperledger/besu:23.4.4 - restart: always - command: > - --network=goerli - --data-path=/opt/besu/database - --data-storage-format=BONSAI - --sync-mode=X_SNAP - --rpc-http-enabled - --rpc-http-cors-origins=* - --rpc-http-host=0.0.0.0 - --rpc-http-max-active-connections=256 - --rpc-http-port=8545 - --engine-rpc-enabled - --engine-host-allowlist=* - --engine-jwt-secret=/jwtsecret - --engine-rpc-port=8551 - --host-allowlist=* - --max-peers=50 - --p2p-enabled=true - --p2p-port=30300 - volumes: ["besu:/data","../configs/jwtsecret:/jwtsecret"] - user: "0:0" - profiles: ["besu"] - ports: - - 30300:30300/tcp - - 30300:30300/udp - networks: - harbour_goerli: - aliases: - - eth1-node - - prysm: - container_name: prysm_harbour_goerli - image: gcr.io/prysmaticlabs/prysm/beacon-chain:v4.0.0 - restart: always - command: - - --prater - - --genesis-state=/data/genesis.ssz - - --datadir=/data - - --jwt-secret=/jwtsecret - - --rpc-host=0.0.0.0 - - --rpc-port=5052 - - --monitoring-host=0.0.0.0 - - --execution-endpoint=$ETH1_AUTH_ENDPOINT - - --slots-per-archive-point=1024 - - --accept-terms-of-use - - --p2p-tcp-port=30301 - - --p2p-udp-port=30301 - volumes: ["prysm:/data","../configs/genesis.ssz:/data/gensis.ssz","../configs/jwtsecret:/jwtsecret"] - profiles: ["prysm"] - ports: - - 30301:30301/tcp - - 30301:30301/udp - networks: - harbour_goerli: - aliases: - - eth2-node - - lighthouse: - container_name: lighthouse_harbour_goerli - image: sigp/lighthouse:v4.3.0 - restart: always - command: - - lighthouse - - --network - - prater - - beacon - - --http - - --http-address=0.0.0.0 - - --http-port=5052 - - --execution-endpoint - - $ETH1_AUTH_ENDPOINT - - --execution-jwt=/jwtsecret - - --port=30301 - - --enr-udp-port=30302 - volumes: ["lighthouse:/root/.lighthouse","../configs/jwtsecret:/jwtsecret"] - profiles: ["lighthouse"] - ports: - - 30302:30302/tcp - - 30302:30302/udp - networks: - harbour_goerli: - aliases: - - eth2-node diff --git a/deploy/harbour_mainnet/.env.example b/deploy/harbour_mainnet/.env.example deleted file mode 100644 index 90fa40f..0000000 --- a/deploy/harbour_mainnet/.env.example +++ /dev/null @@ -1,92 +0,0 @@ -########## -# Oracle # -########## -LOG_LEVEL=INFO -NETWORK=harbour_mainnet -ENABLE_HEALTH_SERVER=true -HEALTH_SERVER_PORT=8080 -HEALTH_SERVER_HOST=0.0.0.0 - -# Uncomment LOCAL_IPFS_CLIENT_ENDPOINT if you are using "ipfs" profile -#LOCAL_IPFS_CLIENT_ENDPOINT="/dns/ipfs/tcp/5001/http" - -INFURA_IPFS_CLIENT_ENDPOINT=/dns/ipfs.infura.io/tcp/5001/https -INFURA_IPFS_CLIENT_USERNAME= -INFURA_IPFS_CLIENT_PASSWORD= - -# Optionally pin merkle proofs to the pinata service for redundancy -IPFS_PINATA_API_KEY= -IPFS_PINATA_SECRET_KEY= - -# Change https://api.thegraph.com to http://graph-node:8000 if running local graph node -STAKEWISE_SUBGRAPH_URLS=https://api.thegraph.com/subgraphs/name/stakewise/stakewise-harbour-mainnet -ETHEREUM_SUBGRAPH_URLS=https://api.thegraph.com/subgraphs/name/stakewise/ethereum-mainnet - -# Ethereum private key -# NB! You must use a different private key for every network -ORACLE_PRIVATE_KEY=0x - -# ETH1 (execution) client endpoint -# Change if running an external ETH1 node -ETH1_ENDPOINT=http://eth1-node:8545 - -# ETH2 (consensus) client endpoint -# Change if running an external ETH2 node -ETH2_ENDPOINT=http://eth2-node:5052 - -# AWS bucket to publish oracle votes to -AWS_ACCESS_KEY_ID= -AWS_SECRET_ACCESS_KEY= -AWS_BUCKET_NAME=oracle-votes-harbour-mainnet -AWS_REGION=us-east-1 - -########## -# Keeper # -########## -# Change if running an external ETH1 node -KEEPER_ETH1_ENDPOINT=http://eth1-node:8545 -# Use https://eth-converter.com/ to calculate -KEEPER_MIN_BALANCE_WEI=100000000000000000 -KEEPER_MAX_FEE_PER_GAS_GWEI=150 - -######## -# IPFS # -######## -IPFS_URL=http://ipfs:5001 -IPFS_PROFILE=server -IPFS_FD_MAX=8192 - -############# -# ETH2 Node # -############# -ETH1_AUTH_ENDPOINT=http://eth1-node:8551 - -############## -# Graph Node # -############## -GRAPH_LOG=info -GRAPH_NODE_URL=http://graph-node:8020 -# Change if running remote IPFS node -ipfs=ipfs:5001 -# Change if running an external ETH1 node -# NB! If syncing graph node from scratch archive node must be used. -# It can be switched to fast-sync node once fully synced. -ethereum=mainnet:http://eth1-node:8545 -# Postgres DB settings for graph node -postgres_host=postgres -postgres_user=graph -postgres_pass=strong-password -postgres_db=graph-node - -############ -# Postgres # -############ -# postgres is used by local graph node -POSTGRES_DB=graph-node -POSTGRES_USER=graph -POSTGRES_PASSWORD=strong-password - -############ -# SENTRY # -############ -# SENTRY_DSN= diff --git a/deploy/harbour_mainnet/docker-compose.yml b/deploy/harbour_mainnet/docker-compose.yml deleted file mode 100644 index 736d8cd..0000000 --- a/deploy/harbour_mainnet/docker-compose.yml +++ /dev/null @@ -1,236 +0,0 @@ -version: "3.9" - -volumes: - prometheus: - driver: local - alertmanager: - driver: local - postgres: - driver: local - ipfs: - driver: local - geth: - driver: local - besu: - driver: local - prysm: - driver: local - lighthouse: - driver: local - -networks: - harbour_mainnet: - name: harbour_mainnet - driver: bridge - -services: - oracle: - container_name: oracle_harbour_mainnet - image: europe-west4-docker.pkg.dev/stakewiselabs/public/oracle:v3.0.0 - restart: always - entrypoint: ["python"] - command: ["oracle/oracle/main.py"] - env_file: [".env"] - networks: - - harbour_mainnet - - keeper: - container_name: keeper_harbour_mainnet - image: europe-west4-docker.pkg.dev/stakewiselabs/public/oracle:v3.0.0 - restart: always - entrypoint: ["python"] - command: ["oracle/keeper/main.py"] - env_file: [".env"] - profiles: ["keeper"] - networks: - - harbour_mainnet - - prometheus: - container_name: prometheus_harbour_mainnet - image: bitnami/prometheus:2 - restart: always - env_file: [".env"] - volumes: - - prometheus:/opt/bitnami/prometheus/data - - ../configs/prometheus.yml:/opt/bitnami/prometheus/conf/prometheus.yml - - ../configs/rules.yml:/opt/bitnami/prometheus/conf/rules.yml - networks: - - harbour_mainnet - - alertmanager: - container_name: alertmanager_harbour_mainnet - image: bitnami/alertmanager:0 - restart: always - env_file: [".env"] - volumes: - - alertmanager:/opt/bitnami/alertmanager/data - - ../configs/alertmanager.yml:/opt/bitnami/alertmanager/conf/config.yml - depends_on: ["prometheus"] - networks: - - harbour_mainnet - - graph-node: - container_name: graph_node_harbour_mainnet - image: graphprotocol/graph-node:v0.25.2 - restart: always - env_file: [".env"] - depends_on: ["postgres","ipfs"] - profiles: ["graph"] - networks: - - harbour_mainnet - - postgres: - container_name: postgres_harbour_mainnet - image: postgres:14-alpine - restart: always - command: ["postgres", "-cshared_preload_libraries=pg_stat_statements"] - env_file: [".env"] - volumes: ["postgres:/var/lib/postgresql/data"] - profiles: ["graph"] - networks: - - harbour_mainnet - - subgraphs: - container_name: subgraphs_harbour_mainnet - image: europe-west4-docker.pkg.dev/stakewiselabs/public/subgraphs:v1.3.0 - command: > - /bin/sh -c "until nc -vz graph-node 8020; do echo 'Waiting graph-node'; sleep 2; done - && yarn build:harbour_mainnet - && yarn create:local - && yarn deploy:local" - env_file: [".env"] - restart: "no" - depends_on: ["graph-node","ipfs"] - profiles: ["graph"] - networks: - - harbour_mainnet - - ipfs: - container_name: ipfs_harbour_mainnet - image: ipfs/go-ipfs:v0.12.1 - restart: always - env_file: [".env"] - ulimits: - nofile: - soft: 8192 - hard: 8192 - volumes: ["ipfs:/data/ipfs","../configs/ipfs-entrypoint.sh:/usr/local/bin/start_ipfs"] - profiles: ["ipfs"] - networks: - - harbour_mainnet - - geth: - container_name: geth_harbour_mainnet - image: ethereum/client-go:v1.12.0 - restart: always - command: - - --mainnet - - --syncmode=full - - --authrpc.jwtsecret=/jwtsecret - - --authrpc.addr=0.0.0.0 - - --authrpc.port=8551 - - --authrpc.vhosts=* - - --http - - --http.addr=0.0.0.0 - - --http.port=8545 - - --http.vhosts=* - - --http.api=web3,eth,net - - --datadir=/data/ethereum - - --ethash.dagdir=/data/ethereum/.ethash - - --ipcdisable - - --port=30300 - volumes: ["geth:/data","../configs/jwtsecret:/jwtsecret"] - profiles: ["geth"] - ports: - - 30300:30300/tcp - - 30300:30300/udp - networks: - harbour_mainnet: - aliases: - - eth1-node - - besu: - container_name: besu_harbour_mainnet - image: hyperledger/besu:23.4.4 - restart: always - command: > - --network=mainnet - --data-path=/data - --data-storage-format=BONSAI - --sync-mode=X_SNAP - --rpc-http-enabled - --rpc-http-cors-origins=* - --rpc-http-host=0.0.0.0 - --rpc-http-max-active-connections=256 - --rpc-http-port=8545 - --engine-rpc-enabled - --engine-host-allowlist=* - --engine-jwt-secret=/jwtsecret - --engine-rpc-port=8551 - --host-allowlist=* - --max-peers=50 - --p2p-enabled=true - --p2p-port=30300 - volumes: ["besu:/data","../configs/jwtsecret:/jwtsecret"] - user: "0:0" - profiles: ["besu"] - ports: - - 30300:30300/tcp - - 30300:30300/udp - networks: - harbour_mainnet: - aliases: - - eth1-node - - prysm: - container_name: prysm_harbour_mainnet - image: gcr.io/prysmaticlabs/prysm/beacon-chain:v4.0.7 - restart: always - command: - - --mainnet - - --datadir=/data - - --jwt-secret=/jwtsecret - - --rpc-host=0.0.0.0 - - --rpc-port=5052 - - --monitoring-host=0.0.0.0 - - --execution-endpoint=$ETH1_AUTH_ENDPOINT - - --slots-per-archive-point=1024 - - --accept-terms-of-use - - --p2p-tcp-port=30301 - - --p2p-udp-port=30301 - volumes: ["prysm:/data","../configs/genesis.ssz:/data/gensis.ssz","../configs/jwtsecret:/jwtsecret"] - profiles: ["prysm"] - ports: - - 30301:30301/tcp - - 30301:30301/udp - networks: - harbour_mainnet: - aliases: - - eth2-node - - lighthouse: - container_name: lighthouse_harbour_mainnet - image: sigp/lighthouse:v4.3.0 - restart: always - command: - - lighthouse - - --network - - mainnet - - beacon - - --http - - --http-address=0.0.0.0 - - --http-port=5052 - - --execution-endpoint - - $ETH1_AUTH_ENDPOINT - - --execution-jwt=/jwtsecret - - --port=30301 - - --enr-udp-port=30302 - volumes: ["lighthouse:/root/.lighthouse","../configs/jwtsecret:/jwtsecret"] - profiles: ["lighthouse"] - ports: - - 30302:30302/tcp - - 30302:30302/udp - networks: - harbour_mainnet: - aliases: - - eth2-node diff --git a/deploy/mainnet/docker-compose.yml b/deploy/mainnet/docker-compose.yml index 87eaab6..11f23c5 100644 --- a/deploy/mainnet/docker-compose.yml +++ b/deploy/mainnet/docker-compose.yml @@ -26,7 +26,7 @@ networks: services: oracle: container_name: oracle_mainnet - image: europe-west4-docker.pkg.dev/stakewiselabs/public/oracle:v3.0.0 + image: europe-west4-docker.pkg.dev/stakewiselabs/public/oracle:v3.3.0 restart: always entrypoint: ["python"] command: ["oracle/oracle/main.py"] @@ -36,7 +36,7 @@ services: keeper: container_name: keeper_mainnet - image: europe-west4-docker.pkg.dev/stakewiselabs/public/oracle:v3.0.0 + image: europe-west4-docker.pkg.dev/stakewiselabs/public/oracle:v3.3.0 restart: always entrypoint: ["python"] command: ["oracle/keeper/main.py"] diff --git a/pyproject.toml b/pyproject.toml index 8393b90..a66f413 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "oracle" -version = "3.2.0" +version = "3.3.0" description = "StakeWise Oracles are responsible for submitting off-chain data." authors = ["Dmitri Tsumak "] license = "AGPL-3.0-only"