Compare commits
6 Commits
willruddic
...
lash/norma
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
40730bba4b
|
||
|
|
87e202e340
|
||
|
|
071ebadb95
|
||
|
|
7d8552bf8e
|
||
|
|
a1669a46d2
|
||
|
|
5c36f0536b
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,4 +14,3 @@ build/
|
|||||||
**/.venv
|
**/.venv
|
||||||
.idea
|
.idea
|
||||||
**/.vim
|
**/.vim
|
||||||
**/*secret.yaml
|
|
||||||
|
|||||||
@@ -1,43 +1,14 @@
|
|||||||
include:
|
include:
|
||||||
#- local: 'ci_templates/.cic-template.yml' #kaniko build templates
|
- local: 'ci_templates/.cic-template.yml'
|
||||||
# these includes are app specific unit tests
|
- local: 'apps/contract-migration/.gitlab-ci.yml'
|
||||||
- local: 'apps/cic-eth/.gitlab-ci.yml'
|
- local: 'apps/cic-eth/.gitlab-ci.yml'
|
||||||
- local: 'apps/cic-ussd/.gitlab-ci.yml'
|
- local: 'apps/cic-ussd/.gitlab-ci.yml'
|
||||||
- local: 'apps/cic-notify/.gitlab-ci.yml'
|
- local: 'apps/cic-notify/.gitlab-ci.yml'
|
||||||
- local: 'apps/cic-meta/.gitlab-ci.yml'
|
- local: 'apps/cic-meta/.gitlab-ci.yml'
|
||||||
- local: 'apps/cic-cache/.gitlab-ci.yml'
|
- local: 'apps/cic-cache/.gitlab-ci.yml'
|
||||||
#- local: 'apps/contract-migration/.gitlab-ci.yml'
|
- local: 'apps/data-seeding/.gitlab-ci.yml'
|
||||||
#- local: 'apps/data-seeding/.gitlab-ci.yml'
|
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- build
|
- build
|
||||||
- test
|
- test
|
||||||
- deploy
|
- release
|
||||||
|
|
||||||
image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/docker-with-compose:latest
|
|
||||||
|
|
||||||
variables:
|
|
||||||
DOCKER_BUILDKIT: "1"
|
|
||||||
COMPOSE_DOCKER_CLI_BUILD: "1"
|
|
||||||
CI_DEBUG_TRACE: "true"
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
|
|
||||||
|
|
||||||
# runs on protected branches and pushes to repo
|
|
||||||
build-push:
|
|
||||||
stage: build
|
|
||||||
tags:
|
|
||||||
- integration
|
|
||||||
#script:
|
|
||||||
# - TAG=$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA sh ./scripts/build-push.sh
|
|
||||||
script:
|
|
||||||
- TAG=latest sh ./scripts/build-push.sh
|
|
||||||
rules:
|
|
||||||
- if: $CI_COMMIT_REF_PROTECTED == "true"
|
|
||||||
when: always
|
|
||||||
|
|
||||||
deploy-dev:
|
|
||||||
stage: deploy
|
|
||||||
trigger: grassrootseconomics/devops
|
|
||||||
when: manual
|
|
||||||
|
|||||||
32
README.md
32
README.md
@@ -2,21 +2,25 @@
|
|||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
This repo uses docker-compose and docker buildkit. Set the following environment variables to get started:
|
## Make some keys
|
||||||
|
|
||||||
```
|
```
|
||||||
export COMPOSE_DOCKER_CLI_BUILD=1
|
docker build -t bloxie . && docker run -v "$(pwd)/keys:/root/keys" --rm -it -t bloxie account new --chain /root/bloxberg.json --keys-path /root/keys
|
||||||
export DOCKER_BUILDKIT=1
|
|
||||||
```
|
```
|
||||||
|
|
||||||
start services, database, redis and local ethereum node
|
|
||||||
```
|
|
||||||
docker-compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
Run app/contract-migration to deploy contracts
|
### Prepare the repo
|
||||||
|
|
||||||
|
This is stuff we need to put in makefile but for now...
|
||||||
|
|
||||||
|
File mounts and permisssions need to be set
|
||||||
```
|
```
|
||||||
RUN_MASK=3 docker-compose up contract-migration
|
chmod -R 755 scripts/initdb apps/cic-meta/scripts/initdb
|
||||||
|
````
|
||||||
|
|
||||||
|
start cluster
|
||||||
|
```
|
||||||
|
docker-compose up
|
||||||
```
|
```
|
||||||
|
|
||||||
stop cluster
|
stop cluster
|
||||||
@@ -24,9 +28,9 @@ stop cluster
|
|||||||
docker-compose down
|
docker-compose down
|
||||||
```
|
```
|
||||||
|
|
||||||
stop cluster and delete data
|
delete data
|
||||||
```
|
```
|
||||||
docker-compose down -v --remove-orphans
|
docker-compose down -v
|
||||||
```
|
```
|
||||||
|
|
||||||
rebuild an images
|
rebuild an images
|
||||||
@@ -34,7 +38,5 @@ rebuild an images
|
|||||||
docker-compose up --build <service_name>
|
docker-compose up --build <service_name>
|
||||||
```
|
```
|
||||||
|
|
||||||
to delete the buildkit cache
|
Deployment variables are writtend to service-configs/.env after everthing is up.
|
||||||
```
|
|
||||||
docker builder prune --filter type=exec.cachemount
|
|
||||||
```
|
|
||||||
|
|||||||
34
apps/cic-base-os/Dockerfile
Normal file
34
apps/cic-base-os/Dockerfile
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# The solc image messes up the alpine environment, so we have to go all over again
|
||||||
|
FROM python:3.8.6-slim-buster
|
||||||
|
|
||||||
|
LABEL authors="Louis Holbrook <dev@holbrook.no> 0826EDA1702D1E87C6E2875121D2E7BB88C2A746"
|
||||||
|
LABEL spdx-license-identifier="GPL-3.0-or-later"
|
||||||
|
LABEL description="Base layer for buiding development images for the cic component suite"
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y git gcc g++ libpq-dev && \
|
||||||
|
apt-get install -y vim gawk jq telnet openssl iputils-ping curl wget gnupg socat bash procps make python2 postgresql-client
|
||||||
|
|
||||||
|
|
||||||
|
RUN echo installing nodejs tooling
|
||||||
|
|
||||||
|
COPY ./dev/nvm.sh /root/
|
||||||
|
|
||||||
|
# Install nvm with node and npm
|
||||||
|
# https://stackoverflow.com/questions/25899912/how-to-install-nvm-in-docker
|
||||||
|
ENV NVM_DIR /root/.nvm
|
||||||
|
ENV NODE_VERSION 15.3.0
|
||||||
|
ENV BANCOR_NODE_VERSION 10.16.0
|
||||||
|
|
||||||
|
RUN wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash \
|
||||||
|
&& . $NVM_DIR/nvm.sh \
|
||||||
|
&& nvm install $NODE_VERSION \
|
||||||
|
&& nvm alias default $NODE_VERSION \
|
||||||
|
&& nvm use $NODE_VERSION \
|
||||||
|
# So many ridiculously stupid issues with node in docker that take oceans of absolutely wasted time to resolve
|
||||||
|
# owner of these files is "1001" by default - wtf
|
||||||
|
&& chown -R root:root "$NVM_DIR/versions/node/v$NODE_VERSION"
|
||||||
|
|
||||||
|
ENV NODE_PATH $NVM_DIR/versions/node//v$NODE_VERSION/lib/node_modules
|
||||||
|
ENV PATH $NVM_DIR/versions/node//v$NODE_VERSION/bin:$PATH
|
||||||
|
|
||||||
1
apps/cic-base-os/README.md
Normal file
1
apps/cic-base-os/README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
## this is an example base image if we wanted one for all the other apps. Its just OS level things
|
||||||
@@ -1,17 +1,52 @@
|
|||||||
build-test-cic-cache:
|
.cic_cache_variables:
|
||||||
stage: test
|
variables:
|
||||||
tags:
|
APP_NAME: cic-cache
|
||||||
- integration
|
DOCKERFILE_PATH: docker/Dockerfile_ci
|
||||||
variables:
|
CONTEXT: apps/$APP_NAME
|
||||||
APP_NAME: cic-cache
|
|
||||||
MR_IMAGE_TAG: mr-$APP_NAME-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA
|
build-mr-cic-cache:
|
||||||
script:
|
extends:
|
||||||
- cd apps/cic-cache
|
- .py_build_merge_request
|
||||||
- docker build -t $MR_IMAGE_TAG -f docker/Dockerfile .
|
- .cic_cache_variables
|
||||||
- docker run $MR_IMAGE_TAG sh docker/run_tests.sh
|
rules:
|
||||||
allow_failure: true
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
rules:
|
changes:
|
||||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
- apps/cic-cache/**/*
|
||||||
changes:
|
when: always
|
||||||
- apps/$APP_NAME/**/*
|
|
||||||
when: always
|
test-mr-cic-cache:
|
||||||
|
stage: test
|
||||||
|
extends:
|
||||||
|
- .cic_cache_variables
|
||||||
|
cache:
|
||||||
|
key:
|
||||||
|
files:
|
||||||
|
- test_requirements.txt
|
||||||
|
paths:
|
||||||
|
- /root/.cache/pip
|
||||||
|
image: $MR_IMAGE_TAG
|
||||||
|
script:
|
||||||
|
- cd apps/$APP_NAME/
|
||||||
|
- >
|
||||||
|
pip install --extra-index-url https://pip.grassrootseconomics.net:8433
|
||||||
|
--extra-index-url https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple
|
||||||
|
-r test_requirements.txt
|
||||||
|
- export PYTHONPATH=. && pytest -x --cov=cic_cache --cov-fail-under=90 --cov-report term-missing tests
|
||||||
|
needs: ["build-mr-cic-cache"]
|
||||||
|
rules:
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
|
changes:
|
||||||
|
- apps/$APP_NAME/**/*
|
||||||
|
when: always
|
||||||
|
|
||||||
|
build-push-cic-cache:
|
||||||
|
extends:
|
||||||
|
- .py_build_push
|
||||||
|
- .cic_cache_variables
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH == "master"
|
||||||
|
changes:
|
||||||
|
- apps/cic-cache/**/*
|
||||||
|
when: always
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
# CIC-CACHE
|
|
||||||
|
|||||||
@@ -27,11 +27,11 @@ class RPC:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def from_config(config):
|
def from_config(config):
|
||||||
chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC'))
|
chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC'))
|
||||||
RPCConnection.register_location(config.get('RPC_PROVIDER'), chain_spec, 'default')
|
RPCConnection.register_location(config.get('RPC_HTTP_PROVIDER'), chain_spec, 'default')
|
||||||
if config.get('SIGNER_PROVIDER'):
|
if config.get('SIGNER_PROVIDER'):
|
||||||
RPCConnection.register_constructor(ConnType.UNIX, EthUnixSignerConnection, tag='signer')
|
RPCConnection.register_constructor(ConnType.UNIX, EthUnixSignerConnection, tag='signer')
|
||||||
RPCConnection.register_location(config.get('SIGNER_PROVIDER'), chain_spec, 'signer')
|
RPCConnection.register_location(config.get('SIGNER_PROVIDER'), chain_spec, 'signer')
|
||||||
rpc = RPC(chain_spec, config.get('RPC_PROVIDER'), signer_provider=config.get('SIGNER_PROVIDER'))
|
rpc = RPC(chain_spec, config.get('RPC_HTTP_PROVIDER'), signer_provider=config.get('SIGNER_PROVIDER'))
|
||||||
logg.info('set up rpc: {}'.format(rpc))
|
logg.info('set up rpc: {}'.format(rpc))
|
||||||
return rpc
|
return rpc
|
||||||
|
|
||||||
|
|||||||
38
apps/cic-cache/docker/Dockerfile_ci
Normal file
38
apps/cic-cache/docker/Dockerfile_ci
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# syntax = docker/dockerfile:1.2
|
||||||
|
FROM registry.gitlab.com/grassrootseconomics/cic-base-images:python-3.8.6-dev-55da5f4e as dev
|
||||||
|
|
||||||
|
# RUN pip install $pip_extra_index_url_flag cic-base[full_graph]==0.1.2b9
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
#RUN pip install $pip_extra_index_url_flag -r test_requirements.txt
|
||||||
|
#RUN pip install $pip_extra_index_url_flag .
|
||||||
|
#RUN pip install .[server]
|
||||||
|
|
||||||
|
ARG EXTRA_INDEX_URL="https://pip.grassrootseconomics.net:8433"
|
||||||
|
ARG GITLAB_PYTHON_REGISTRY="https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple"
|
||||||
|
ARG EXTRA_PIP_ARGS=""
|
||||||
|
RUN pip install --index-url https://pypi.org/simple \
|
||||||
|
--extra-index-url $GITLAB_PYTHON_REGISTRY --extra-index-url $EXTRA_INDEX_URL $EXTRA_PIP_ARGS \
|
||||||
|
-r requirements.txt
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN python setup.py install
|
||||||
|
|
||||||
|
# ini files in config directory defines the configurable parameters for the application
|
||||||
|
# they can all be overridden by environment variables
|
||||||
|
# to generate a list of environment variables from configuration, use: confini-dump -z <dir> (executable provided by confini package)
|
||||||
|
COPY config/ /usr/local/etc/cic-cache/
|
||||||
|
|
||||||
|
# for db migrations
|
||||||
|
RUN git clone https://github.com/vishnubob/wait-for-it.git /usr/local/bin/wait-for-it/
|
||||||
|
COPY cic_cache/db/migrations/ /usr/local/share/cic-cache/alembic/
|
||||||
|
|
||||||
|
COPY /docker/start_tracker.sh ./start_tracker.sh
|
||||||
|
COPY /docker/db.sh ./db.sh
|
||||||
|
RUN chmod 755 ./*.sh
|
||||||
|
# Tracker
|
||||||
|
# ENTRYPOINT ["/usr/local/bin/cic-cache-tracker", "-vv"]
|
||||||
|
# Server
|
||||||
|
# ENTRYPOINT [ "/usr/local/bin/uwsgi", "--wsgi-file", "/usr/local/lib/python3.8/site-packages/cic_cache/runnable/server.py", "--http", ":80", "--pyargv", "-vv" ]
|
||||||
|
ENTRYPOINT []
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
pip install --extra-index-url https://pip.grassrootseconomics.net:8433 \
|
|
||||||
--extra-index-url https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple \
|
|
||||||
-r test_requirements.txt
|
|
||||||
|
|
||||||
export PYTHONPATH=. && pytest -x --cov=cic_cache --cov-fail-under=90 --cov-report term-missing tests
|
|
||||||
|
|
||||||
@@ -9,6 +9,7 @@ psycopg2==2.8.6
|
|||||||
celery==4.4.7
|
celery==4.4.7
|
||||||
redis==3.5.3
|
redis==3.5.3
|
||||||
chainsyncer[sql]>=0.0.6a3,<0.1.0
|
chainsyncer[sql]>=0.0.6a3,<0.1.0
|
||||||
erc20-faucet>=0.3.2a2, <0.4.0
|
erc20-faucet>=0.3.2a1, <0.4.0
|
||||||
chainlib-eth>=0.0.9a14,<0.1.0
|
chainlib-eth>=0.0.9a7,<0.1.0
|
||||||
eth-address-index>=0.2.3a4,<0.3.0
|
chainlib>=0.0.9a3,<0.1.0
|
||||||
|
eth-address-index>=0.2.3a1,<0.3.0
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
celery==4.4.7
|
celery==4.4.7
|
||||||
erc20-demurrage-token~=0.0.3a1
|
erc20-demurrage-token~=0.0.3a1
|
||||||
cic-eth-registry>=0.6.1a2,<0.7.0
|
cic-eth-registry~=0.5.8a1
|
||||||
cic-eth[services]~=0.12.4a8
|
chainlib~=0.0.7a1
|
||||||
|
cic_eth~=0.12.2a4
|
||||||
|
|||||||
@@ -1,16 +1,52 @@
|
|||||||
build-test-cic-eth:
|
.cic_eth_variables:
|
||||||
stage: test
|
variables:
|
||||||
tags:
|
APP_NAME: cic-eth
|
||||||
- integration
|
DOCKERFILE_PATH: docker/Dockerfile_ci
|
||||||
variables:
|
CONTEXT: apps/$APP_NAME
|
||||||
APP_NAME: cic-eth
|
|
||||||
MR_IMAGE_TAG: mr-$APP_NAME-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA
|
build-mr-cic-eth:
|
||||||
script:
|
extends:
|
||||||
- cd apps/cic-eth
|
- .cic_eth_variables
|
||||||
- docker build -t $MR_IMAGE_TAG -f docker/Dockerfile .
|
- .py_build_target_dev
|
||||||
- docker run $MR_IMAGE_TAG sh docker/run_tests.sh
|
rules:
|
||||||
rules:
|
|
||||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
changes:
|
changes:
|
||||||
- apps/$APP_NAME/**/*
|
- apps/cic-eth/**/*
|
||||||
|
when: always
|
||||||
|
|
||||||
|
test-mr-cic-eth:
|
||||||
|
stage: test
|
||||||
|
extends:
|
||||||
|
- .cic_eth_variables
|
||||||
|
cache:
|
||||||
|
key:
|
||||||
|
files:
|
||||||
|
- test_requirements.txt
|
||||||
|
paths:
|
||||||
|
- /root/.cache/pip
|
||||||
|
image: $MR_IMAGE_TAG
|
||||||
|
script:
|
||||||
|
- cd apps/$APP_NAME/
|
||||||
|
- >
|
||||||
|
pip install --extra-index-url https://pip.grassrootseconomics.net:8433
|
||||||
|
--extra-index-url https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple
|
||||||
|
-r admin_requirements.txt
|
||||||
|
-r services_requirements.txt
|
||||||
|
-r test_requirements.txt
|
||||||
|
- export PYTHONPATH=. && pytest -x --cov=cic_eth --cov-fail-under=90 --cov-report term-missing tests
|
||||||
|
needs: ["build-mr-cic-eth"]
|
||||||
|
rules:
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
|
changes:
|
||||||
|
- apps/cic-eth/**/*
|
||||||
|
when: always
|
||||||
|
|
||||||
|
build-push-cic-eth:
|
||||||
|
extends:
|
||||||
|
- .py_build_push
|
||||||
|
- .cic_eth_variables
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH == "master"
|
||||||
|
changes:
|
||||||
|
- apps/cic-eth/**/*
|
||||||
when: always
|
when: always
|
||||||
|
|||||||
@@ -35,14 +35,14 @@ class RPC:
|
|||||||
def from_config(config, use_signer=False, default_label='default', signer_label='signer'):
|
def from_config(config, use_signer=False, default_label='default', signer_label='signer'):
|
||||||
chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC'))
|
chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC'))
|
||||||
|
|
||||||
RPCConnection.register_location(config.get('RPC_PROVIDER'), chain_spec, default_label)
|
RPCConnection.register_location(config.get('RPC_HTTP_PROVIDER'), chain_spec, default_label)
|
||||||
if use_signer:
|
if use_signer:
|
||||||
|
|
||||||
RPCConnection.register_constructor(ConnType.UNIX, EthUnixSignerConnection, signer_label)
|
RPCConnection.register_constructor(ConnType.UNIX, EthUnixSignerConnection, signer_label)
|
||||||
RPCConnection.register_constructor(ConnType.HTTP, EthHTTPSignerConnection, signer_label)
|
RPCConnection.register_constructor(ConnType.HTTP, EthHTTPSignerConnection, signer_label)
|
||||||
RPCConnection.register_constructor(ConnType.HTTP_SSL, EthHTTPSignerConnection, signer_label)
|
RPCConnection.register_constructor(ConnType.HTTP_SSL, EthHTTPSignerConnection, signer_label)
|
||||||
RPCConnection.register_location(config.get('SIGNER_PROVIDER'), chain_spec, signer_label)
|
RPCConnection.register_location(config.get('SIGNER_PROVIDER'), chain_spec, signer_label)
|
||||||
rpc = RPC(chain_spec, config.get('RPC_PROVIDER'), signer_provider=config.get('SIGNER_PROVIDER'))
|
rpc = RPC(chain_spec, config.get('RPC_HTTP_PROVIDER'), signer_provider=config.get('SIGNER_PROVIDER'))
|
||||||
logg.info('set up rpc: {}'.format(rpc))
|
logg.info('set up rpc: {}'.format(rpc))
|
||||||
return rpc
|
return rpc
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ Create Date: 2021-04-02 18:41:20.864265
|
|||||||
import datetime
|
import datetime
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from chainlib.eth.constant import ZERO_ADDRESS
|
||||||
from cic_eth.db.enum import LockEnum
|
from cic_eth.db.enum import LockEnum
|
||||||
from cic_eth.encode import ZERO_ADDRESS_NORMAL
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -30,7 +30,7 @@ def upgrade():
|
|||||||
sa.Column("otx_id", sa.Integer, sa.ForeignKey('otx.id'), nullable=True),
|
sa.Column("otx_id", sa.Integer, sa.ForeignKey('otx.id'), nullable=True),
|
||||||
)
|
)
|
||||||
op.create_index('idx_chain_address', 'lock', ['blockchain', 'address'], unique=True)
|
op.create_index('idx_chain_address', 'lock', ['blockchain', 'address'], unique=True)
|
||||||
op.execute("INSERT INTO lock (address, date_created, blockchain, flags) VALUES('{}', '{}', '::', {})".format(ZERO_ADDRESS_NORMAL, datetime.datetime.utcnow(), LockEnum.INIT | LockEnum.SEND | LockEnum.QUEUE))
|
op.execute("INSERT INTO lock (address, date_created, blockchain, flags) VALUES('{}', '{}', '::', {})".format(ZERO_ADDRESS, datetime.datetime.utcnow(), LockEnum.INIT | LockEnum.SEND | LockEnum.QUEUE))
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
|
|||||||
@@ -3,10 +3,7 @@ import logging
|
|||||||
|
|
||||||
# external imports
|
# external imports
|
||||||
import celery
|
import celery
|
||||||
from hexathon import (
|
from hexathon import strip_0x
|
||||||
strip_0x,
|
|
||||||
add_0x,
|
|
||||||
)
|
|
||||||
#from chainlib.eth.constant import ZERO_ADDRESS
|
#from chainlib.eth.constant import ZERO_ADDRESS
|
||||||
from chainlib.chain import ChainSpec
|
from chainlib.chain import ChainSpec
|
||||||
from chainlib.eth.address import is_checksum_address
|
from chainlib.eth.address import is_checksum_address
|
||||||
@@ -183,7 +180,6 @@ def check_gas(self, tx_hashes_hex, chain_spec_dict, txs_hex=[], address=None, ga
|
|||||||
if not is_checksum_address(address):
|
if not is_checksum_address(address):
|
||||||
raise ValueError('invalid address {}'.format(address))
|
raise ValueError('invalid address {}'.format(address))
|
||||||
address = tx_normalize.wallet_address(address)
|
address = tx_normalize.wallet_address(address)
|
||||||
address = add_0x(address)
|
|
||||||
|
|
||||||
tx_hashes = []
|
tx_hashes = []
|
||||||
txs = []
|
txs = []
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ from cic_eth.registry import (
|
|||||||
)
|
)
|
||||||
from cic_eth.task import BaseTask
|
from cic_eth.task import BaseTask
|
||||||
|
|
||||||
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
logging.basicConfig(level=logging.WARNING)
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ from chainlib.eth.nonce import RPCNonceOracle
|
|||||||
from chainlib.eth.gas import RPCGasOracle
|
from chainlib.eth.gas import RPCGasOracle
|
||||||
from cic_eth_registry import CICRegistry
|
from cic_eth_registry import CICRegistry
|
||||||
from cic_eth_registry.error import UnknownContractError
|
from cic_eth_registry.error import UnknownContractError
|
||||||
|
import liveness.linux
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from cic_eth.error import SeppukuError
|
from cic_eth.error import SeppukuError
|
||||||
@@ -47,7 +48,6 @@ class BaseTask(celery.Task):
|
|||||||
|
|
||||||
def on_failure(self, exc, task_id, args, kwargs, einfo):
|
def on_failure(self, exc, task_id, args, kwargs, einfo):
|
||||||
if isinstance(exc, SeppukuError):
|
if isinstance(exc, SeppukuError):
|
||||||
import liveness.linux
|
|
||||||
liveness.linux.reset(rundir=self.run_dir)
|
liveness.linux.reset(rundir=self.run_dir)
|
||||||
logg.critical(einfo)
|
logg.critical(einfo)
|
||||||
msg = 'received critical exception {}, calling shutdown'.format(str(exc))
|
msg = 'received critical exception {}, calling shutdown'.format(str(exc))
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ version = (
|
|||||||
0,
|
0,
|
||||||
12,
|
12,
|
||||||
4,
|
4,
|
||||||
'alpha.8',
|
'alpha.7',
|
||||||
)
|
)
|
||||||
|
|
||||||
version_object = semver.VersionInfo(
|
version_object = semver.VersionInfo(
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
@node cic-eth configuration
|
@node cic-eth configuration
|
||||||
@section Configuration
|
@section Configuration
|
||||||
|
|
||||||
|
(refer to @code{cic-base} for a general overview of the config pipeline)
|
||||||
|
|
||||||
Configuration parameters are grouped by configuration filename.
|
Configuration parameters are grouped by configuration filename.
|
||||||
|
|
||||||
|
|
||||||
@@ -38,26 +40,7 @@ Boolean value. If set, the amount of available context for a task in the result
|
|||||||
|
|
||||||
@subsection database
|
@subsection database
|
||||||
|
|
||||||
@table @var
|
See ref cic-base when ready
|
||||||
@item host
|
|
||||||
Database host
|
|
||||||
@item port
|
|
||||||
Database port
|
|
||||||
@item name
|
|
||||||
Database name
|
|
||||||
@item user
|
|
||||||
Database user
|
|
||||||
@item password
|
|
||||||
Database password
|
|
||||||
@item engine
|
|
||||||
The engine part of the dsn connection string (@code{postgresql} in @code{postgresql+psycopg2})
|
|
||||||
@item driver
|
|
||||||
The driver part of the dsn connection string (@code{psycopg2} in @code{postgresql+psycopg2})
|
|
||||||
@item pool_size
|
|
||||||
Connection pool size for database drivers that provide connection pooling
|
|
||||||
@item debug
|
|
||||||
Output actual sql queries to logs. Potentially very verbose
|
|
||||||
@end table
|
|
||||||
|
|
||||||
|
|
||||||
@subsection eth
|
@subsection eth
|
||||||
|
|||||||
@@ -13,16 +13,7 @@ ARG EXTRA_PIP_ARGS=""
|
|||||||
# pip install --index-url https://pypi.org/simple \
|
# pip install --index-url https://pypi.org/simple \
|
||||||
# --force-reinstall \
|
# --force-reinstall \
|
||||||
# --extra-index-url $GITLAB_PYTHON_REGISTRY --extra-index-url $EXTRA_INDEX_URL \
|
# --extra-index-url $GITLAB_PYTHON_REGISTRY --extra-index-url $EXTRA_INDEX_URL \
|
||||||
# -r requirements.txt
|
# -r requirements.txt
|
||||||
|
|
||||||
RUN --mount=type=cache,mode=0755,target=/root/.cache/pip \
|
|
||||||
pip install --index-url https://pypi.org/simple \
|
|
||||||
--extra-index-url $GITLAB_PYTHON_REGISTRY \
|
|
||||||
--extra-index-url $EXTRA_INDEX_URL \
|
|
||||||
$EXTRA_PIP_ARGS \
|
|
||||||
cic-eth-aux-erc20-demurrage-token~=0.0.2a6
|
|
||||||
|
|
||||||
|
|
||||||
COPY *requirements.txt ./
|
COPY *requirements.txt ./
|
||||||
RUN --mount=type=cache,mode=0755,target=/root/.cache/pip \
|
RUN --mount=type=cache,mode=0755,target=/root/.cache/pip \
|
||||||
pip install --index-url https://pypi.org/simple \
|
pip install --index-url https://pypi.org/simple \
|
||||||
@@ -31,21 +22,19 @@ RUN --mount=type=cache,mode=0755,target=/root/.cache/pip \
|
|||||||
$EXTRA_PIP_ARGS \
|
$EXTRA_PIP_ARGS \
|
||||||
-r requirements.txt \
|
-r requirements.txt \
|
||||||
-r services_requirements.txt \
|
-r services_requirements.txt \
|
||||||
-r admin_requirements.txt
|
-r admin_requirements.txt
|
||||||
|
|
||||||
# always install the latest signer
|
|
||||||
RUN --mount=type=cache,mode=0755,target=/root/.cache/pip \
|
|
||||||
pip install --index-url https://pypi.org/simple \
|
|
||||||
--extra-index-url $GITLAB_PYTHON_REGISTRY \
|
|
||||||
--extra-index-url $EXTRA_INDEX_URL \
|
|
||||||
$EXTRA_PIP_ARGS \
|
|
||||||
crypto-dev-signer
|
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN python setup.py install
|
RUN python setup.py install
|
||||||
|
|
||||||
ENV PYTHONPATH .
|
ENV PYTHONPATH .
|
||||||
|
|
||||||
|
RUN --mount=type=cache,mode=0755,target=/root/.cache/pip \
|
||||||
|
pip install --index-url https://pypi.org/simple \
|
||||||
|
--extra-index-url $GITLAB_PYTHON_REGISTRY \
|
||||||
|
--extra-index-url $EXTRA_INDEX_URL \
|
||||||
|
$EXTRA_PIP_ARGS \
|
||||||
|
cic-eth-aux-erc20-demurrage-token~=0.0.2a6
|
||||||
|
|
||||||
COPY docker/entrypoints/* ./
|
COPY docker/entrypoints/* ./
|
||||||
RUN chmod 755 *.sh
|
RUN chmod 755 *.sh
|
||||||
|
|||||||
71
apps/cic-eth/docker/Dockerfile_ci
Normal file
71
apps/cic-eth/docker/Dockerfile_ci
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
FROM registry.gitlab.com/grassrootseconomics/cic-base-images:python-3.8.6-dev-55da5f4e as dev
|
||||||
|
|
||||||
|
WORKDIR /usr/src/cic-eth
|
||||||
|
|
||||||
|
# Copy just the requirements and install....this _might_ give docker a hint on caching but we
|
||||||
|
# do load these all into setup.py later
|
||||||
|
# TODO can we take all the requirements out of setup.py and just do a pip install -r requirements.txt && python setup.py
|
||||||
|
#COPY cic-eth/requirements.txt .
|
||||||
|
|
||||||
|
ARG EXTRA_INDEX_URL="https://pip.grassrootseconomics.net:8433"
|
||||||
|
ARG GITLAB_PYTHON_REGISTRY="https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple"
|
||||||
|
ARG EXTRA_PIP_ARGS=""
|
||||||
|
#RUN --mount=type=cache,mode=0755,target=/root/.cache/pip \
|
||||||
|
# pip install --index-url https://pypi.org/simple \
|
||||||
|
# --force-reinstall \
|
||||||
|
# --extra-index-url $GITLAB_PYTHON_REGISTRY --extra-index-url $EXTRA_INDEX_URL \
|
||||||
|
# -r requirements.txt
|
||||||
|
COPY *requirements.txt .
|
||||||
|
RUN pip install --index-url https://pypi.org/simple \
|
||||||
|
--extra-index-url $GITLAB_PYTHON_REGISTRY \
|
||||||
|
--extra-index-url $EXTRA_INDEX_URL \
|
||||||
|
$EXTRA_PIP_ARGS \
|
||||||
|
-r requirements.txt \
|
||||||
|
-r services_requirements.txt \
|
||||||
|
-r admin_requirements.txt
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN python setup.py install
|
||||||
|
|
||||||
|
COPY docker/entrypoints/* ./
|
||||||
|
RUN chmod 755 *.sh
|
||||||
|
|
||||||
|
# # ini files in config directory defines the configurable parameters for the application
|
||||||
|
# # they can all be overridden by environment variables
|
||||||
|
# # to generate a list of environment variables from configuration, use: confini-dump -z <dir> (executable provided by confini package)
|
||||||
|
COPY config/ /usr/local/etc/cic-eth/
|
||||||
|
COPY cic_eth/db/migrations/ /usr/local/share/cic-eth/alembic/
|
||||||
|
COPY crypto_dev_signer_config/ /usr/local/etc/crypto-dev-signer/
|
||||||
|
|
||||||
|
# TODO this kind of code sharing across projects should be discouraged...can we make util a library?
|
||||||
|
#COPY util/liveness/health.sh /usr/local/bin/health.sh
|
||||||
|
ENTRYPOINT []
|
||||||
|
|
||||||
|
# ------------------ PRODUCTION CONTAINER ----------------------
|
||||||
|
#FROM python:3.8.6-slim-buster as prod
|
||||||
|
#
|
||||||
|
#RUN apt-get update && \
|
||||||
|
# apt install -y gnupg libpq-dev procps
|
||||||
|
#
|
||||||
|
#WORKDIR /root
|
||||||
|
#
|
||||||
|
#COPY --from=dev /usr/local/bin/ /usr/local/bin/
|
||||||
|
#COPY --from=dev /usr/local/lib/python3.8/site-packages/ \
|
||||||
|
# /usr/local/lib/python3.8/site-packages/
|
||||||
|
#
|
||||||
|
#COPY docker/entrypoints/* ./
|
||||||
|
#RUN chmod 755 *.sh
|
||||||
|
#
|
||||||
|
## # ini files in config directory defines the configurable parameters for the application
|
||||||
|
## # they can all be overridden by environment variables
|
||||||
|
## # to generate a list of environment variables from configuration, use: confini-dump -z <dir> (executable provided by confini package)
|
||||||
|
#COPY config/ /usr/local/etc/cic-eth/
|
||||||
|
#COPY cic_eth/db/migrations/ /usr/local/share/cic-eth/alembic/
|
||||||
|
#COPY crypto_dev_signer_config/ /usr/local/etc/crypto-dev-signer/
|
||||||
|
#COPY scripts/ scripts/
|
||||||
|
#
|
||||||
|
## TODO this kind of code sharing across projects should be discouraged...can we make util a library?
|
||||||
|
##COPY util/liveness/health.sh /usr/local/bin/health.sh
|
||||||
|
#
|
||||||
|
#ENTRYPOINT []
|
||||||
|
#
|
||||||
@@ -5,27 +5,27 @@ set -e
|
|||||||
|
|
||||||
# set CONFINI_ENV_PREFIX to override the env prefix to override env vars
|
# set CONFINI_ENV_PREFIX to override the env prefix to override env vars
|
||||||
|
|
||||||
#echo "!!! starting signer"
|
echo "!!! starting signer"
|
||||||
#python /usr/local/bin/crypto-dev-daemon -c /usr/local/etc/crypto-dev-signer -vv 2> /tmp/signer.log &
|
python /usr/local/bin/crypto-dev-daemon -c /usr/local/etc/crypto-dev-signer -vv 2> /tmp/signer.log &
|
||||||
|
|
||||||
echo "!!! starting taskerd"
|
echo "!!! starting taskerd"
|
||||||
/usr/local/bin/cic-eth-taskerd $@
|
/usr/local/bin/cic-eth-taskerd $@
|
||||||
|
|
||||||
# thanks! https://docs.docker.com/config/containers/multi-service_container/
|
# thanks! https://docs.docker.com/config/containers/multi-service_container/
|
||||||
#sleep 1;
|
sleep 1;
|
||||||
#echo "!!! entering monitor loop"
|
echo "!!! entering monitor loop"
|
||||||
#while true; do
|
while true; do
|
||||||
# ps aux | grep crypto-dev-daemon | grep -q -v grep
|
ps aux | grep crypto-dev-daemon | grep -q -v grep
|
||||||
# PROCESS_1_STATUS=$?
|
PROCESS_1_STATUS=$?
|
||||||
# ps aux | grep cic-eth-tasker |grep -q -v grep
|
ps aux | grep cic-eth-tasker |grep -q -v grep
|
||||||
# PROCESS_2_STATUS=$?
|
PROCESS_2_STATUS=$?
|
||||||
# # If the greps above find anything, they exit with 0 status
|
# If the greps above find anything, they exit with 0 status
|
||||||
# # If they are not both 0, then something is wrong
|
# If they are not both 0, then something is wrong
|
||||||
# if [ $PROCESS_1_STATUS -ne 0 -o $PROCESS_2_STATUS -ne 0 ]; then
|
if [ $PROCESS_1_STATUS -ne 0 -o $PROCESS_2_STATUS -ne 0 ]; then
|
||||||
# echo "One of the processes has already exited."
|
echo "One of the processes has already exited."
|
||||||
# exit 1
|
exit 1
|
||||||
# fi
|
fi
|
||||||
# sleep 15;
|
sleep 15;
|
||||||
#done
|
done
|
||||||
#
|
|
||||||
set +e
|
set +e
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
pip install --extra-index-url https://pip.grassrootseconomics.net:8433 --extra-index-url https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple \
|
|
||||||
-r admin_requirements.txt \
|
|
||||||
-r services_requirements.txt \
|
|
||||||
-r test_requirements.txt
|
|
||||||
|
|
||||||
export PYTHONPATH=. && pytest -x --cov=cic_eth --cov-fail-under=90 --cov-report term-missing tests
|
|
||||||
|
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
celery==4.4.7
|
celery==4.4.7
|
||||||
chainlib-eth>=0.0.9a14,<0.1.0
|
chainlib-eth>=0.0.9a7,<0.1.0
|
||||||
semver==2.13.0
|
semver==2.13.0
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
pip install --extra-index-url https://pip.grassrootseconomics.net:8433 --extra-index-url https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple
|
|
||||||
-r admin_requirements.txt
|
|
||||||
-r services_requirements.txt
|
|
||||||
-r test_requirements.txt
|
|
||||||
|
|
||||||
export PYTHONPATH=. && pytest -x --cov=cic_eth --cov-fail-under=90 --cov-report term-missing tests
|
|
||||||
@@ -75,7 +75,7 @@ def test_task_check_gas_ok(
|
|||||||
'cic_eth.eth.gas.check_gas',
|
'cic_eth.eth.gas.check_gas',
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
strip_0x(tx_hash_hex),
|
tx_hash_hex,
|
||||||
],
|
],
|
||||||
default_chain_spec.asdict(),
|
default_chain_spec.asdict(),
|
||||||
[],
|
[],
|
||||||
@@ -283,3 +283,4 @@ def test_task_resend_explicit(
|
|||||||
tx_after = unpack(bytes.fromhex(strip_0x(otx.signed_tx)), default_chain_spec)
|
tx_after = unpack(bytes.fromhex(strip_0x(otx.signed_tx)), default_chain_spec)
|
||||||
logg.debug('gasprices before {} after {}'.format(tx_before['gasPrice'], tx_after['gasPrice']))
|
logg.debug('gasprices before {} after {}'.format(tx_before['gasPrice'], tx_after['gasPrice']))
|
||||||
assert tx_after['gasPrice'] > tx_before['gasPrice']
|
assert tx_after['gasPrice'] > tx_before['gasPrice']
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
crypto-dev-signer>=0.4.15a7,<=0.4.15
|
crypto-dev-signer>=0.4.15a1,<=0.4.15
|
||||||
chainqueue>=0.0.5a1,<0.1.0
|
chainqueue>=0.0.5a1,<0.1.0
|
||||||
cic-eth-registry>=0.6.1a2,<0.7.0
|
cic-eth-registry>=0.6.1a2,<0.7.0
|
||||||
redis==3.5.3
|
redis==3.5.3
|
||||||
|
|||||||
@@ -1,16 +1,43 @@
|
|||||||
build-test-cic-meta:
|
|
||||||
stage: test
|
.cic_meta_variables:
|
||||||
tags:
|
variables:
|
||||||
- integration
|
APP_NAME: cic-meta
|
||||||
variables:
|
DOCKERFILE_PATH: docker/Dockerfile_ci
|
||||||
APP_NAME: cic-meta
|
CONTEXT: apps/$APP_NAME
|
||||||
MR_IMAGE_TAG: mr-$APP_NAME-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA
|
|
||||||
script:
|
build-mr-cic-meta:
|
||||||
- cd apps/cic-meta
|
extends:
|
||||||
- docker build -t $MR_IMAGE_TAG -f docker/Dockerfile .
|
- .py_build_merge_request
|
||||||
- docker run --entrypoint=sh $MR_IMAGE_TAG docker/run_tests.sh
|
- .cic_meta_variables
|
||||||
rules:
|
rules:
|
||||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
changes:
|
changes:
|
||||||
- apps/$APP_NAME/**/*
|
- apps/cic-meta/**/*
|
||||||
|
when: always
|
||||||
|
|
||||||
|
test-mr-cic-meta:
|
||||||
|
extends:
|
||||||
|
- .cic_meta_variables
|
||||||
|
stage: test
|
||||||
|
image: $MR_IMAGE_TAG
|
||||||
|
script:
|
||||||
|
- cd /root
|
||||||
|
- npm install --dev
|
||||||
|
- npm run test
|
||||||
|
- npm run test:coverage
|
||||||
|
needs: ["build-mr-cic-meta"]
|
||||||
|
rules:
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
|
changes:
|
||||||
|
- apps/cic-meta/**/*
|
||||||
|
when: always
|
||||||
|
|
||||||
|
build-push-cic-meta:
|
||||||
|
extends:
|
||||||
|
- .py_build_push
|
||||||
|
- .cic_meta_variables
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH == "master"
|
||||||
|
changes:
|
||||||
|
- apps/cic-meta/**/*
|
||||||
when: always
|
when: always
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
# CIC-Meta
|
|
||||||
@@ -15,10 +15,11 @@ RUN --mount=type=cache,mode=0755,target=/root/.npm \
|
|||||||
COPY webpack.config.js .
|
COPY webpack.config.js .
|
||||||
COPY tsconfig.json .
|
COPY tsconfig.json .
|
||||||
## required to build the cic-client-meta module
|
## required to build the cic-client-meta module
|
||||||
COPY . .
|
COPY src/ src/
|
||||||
|
COPY scripts/ scripts/
|
||||||
|
COPY tests/ tests/
|
||||||
COPY tests/*.asc /root/pgp/
|
COPY tests/*.asc /root/pgp/
|
||||||
|
|
||||||
|
|
||||||
## copy runtime configs
|
## copy runtime configs
|
||||||
COPY .config/ /usr/local/etc/cic-meta/
|
COPY .config/ /usr/local/etc/cic-meta/
|
||||||
#
|
#
|
||||||
|
|||||||
32
apps/cic-meta/docker/Dockerfile_ci
Normal file
32
apps/cic-meta/docker/Dockerfile_ci
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# syntax = docker/dockerfile:1.2
|
||||||
|
#FROM node:15.3.0-alpine3.10
|
||||||
|
FROM node:lts-alpine3.14
|
||||||
|
|
||||||
|
WORKDIR /root
|
||||||
|
|
||||||
|
RUN apk add --no-cache postgresql bash
|
||||||
|
|
||||||
|
# copy the dependencies
|
||||||
|
COPY package.json package-lock.json .
|
||||||
|
RUN npm set cache /root/.npm && \
|
||||||
|
npm ci
|
||||||
|
|
||||||
|
COPY webpack.config.js .
|
||||||
|
COPY tsconfig.json .
|
||||||
|
## required to build the cic-client-meta module
|
||||||
|
COPY src/ src/
|
||||||
|
COPY scripts/ scripts/
|
||||||
|
COPY tests/ tests/
|
||||||
|
COPY tests/*.asc /root/pgp/
|
||||||
|
|
||||||
|
## copy runtime configs
|
||||||
|
COPY .config/ /usr/local/etc/cic-meta/
|
||||||
|
#
|
||||||
|
## db migrations
|
||||||
|
COPY docker/db.sh ./db.sh
|
||||||
|
RUN chmod 755 ./db.sh
|
||||||
|
#
|
||||||
|
RUN alias tsc=node_modules/typescript/bin/tsc
|
||||||
|
COPY docker/start_server.sh ./start_server.sh
|
||||||
|
RUN chmod 755 ./start_server.sh
|
||||||
|
ENTRYPOINT ["sh", "./start_server.sh"]
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
npm install --dev
|
|
||||||
npm run test
|
|
||||||
npm run test:coverage
|
|
||||||
@@ -1,17 +1,52 @@
|
|||||||
build-test-cic-notify:
|
.cic_notify_variables:
|
||||||
stage: test
|
variables:
|
||||||
tags:
|
APP_NAME: cic-notify
|
||||||
- integration
|
DOCKERFILE_PATH: docker/Dockerfile_ci
|
||||||
variables:
|
CONTEXT: apps/$APP_NAME
|
||||||
APP_NAME: cic-notify
|
|
||||||
MR_IMAGE_TAG: mr-$APP_NAME-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA
|
build-mr-cic-notify:
|
||||||
script:
|
extends:
|
||||||
- cd apps/cic-notify
|
- .py_build_merge_request
|
||||||
- docker build -t $MR_IMAGE_TAG -f docker/Dockerfile .
|
- .cic_notify_variables
|
||||||
- docker run $MR_IMAGE_TAG sh docker/run_tests.sh
|
rules:
|
||||||
allow_failure: true
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
rules:
|
changes:
|
||||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
- apps/cic-notify/**/*
|
||||||
changes:
|
when: always
|
||||||
- apps/$APP_NAME/**/*
|
|
||||||
when: always
|
test-mr-cic-notify:
|
||||||
|
stage: test
|
||||||
|
extends:
|
||||||
|
- .cic_notify_variables
|
||||||
|
cache:
|
||||||
|
key:
|
||||||
|
files:
|
||||||
|
- test_requirements.txt
|
||||||
|
paths:
|
||||||
|
- /root/.cache/pip
|
||||||
|
image: $MR_IMAGE_TAG
|
||||||
|
script:
|
||||||
|
- cd apps/$APP_NAME/
|
||||||
|
- >
|
||||||
|
pip install --extra-index-url https://pip.grassrootseconomics.net:8433
|
||||||
|
--extra-index-url https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple
|
||||||
|
-r test_requirements.txt
|
||||||
|
- export PYTHONPATH=. && pytest -x --cov=cic_notify --cov-fail-under=90 --cov-report term-missing tests
|
||||||
|
needs: ["build-mr-cic-notify"]
|
||||||
|
rules:
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
|
changes:
|
||||||
|
- apps/$APP_NAME/**/*
|
||||||
|
when: always
|
||||||
|
|
||||||
|
build-push-cic-notify:
|
||||||
|
extends:
|
||||||
|
- .py_build_push
|
||||||
|
- .cic_notify_variables
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH == "master"
|
||||||
|
changes:
|
||||||
|
- apps/cic-notify/**/*
|
||||||
|
when: always
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ celery_app = celery.current_app
|
|||||||
|
|
||||||
|
|
||||||
@celery_app.task
|
@celery_app.task
|
||||||
def persist_notification(message, recipient):
|
def persist_notification(recipient, message):
|
||||||
"""
|
"""
|
||||||
:param message:
|
|
||||||
:type message:
|
|
||||||
:param recipient:
|
:param recipient:
|
||||||
:type recipient:
|
:type recipient:
|
||||||
|
:param message:
|
||||||
|
:type message:
|
||||||
:return:
|
:return:
|
||||||
:rtype:
|
:rtype:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -11,13 +11,12 @@ local_logg = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
@celery_app.task
|
@celery_app.task
|
||||||
def log(message, recipient):
|
def log(recipient, message):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:param message:
|
|
||||||
:type message:
|
|
||||||
:param recipient:
|
:param recipient:
|
||||||
:type recipient:
|
:type recipient:
|
||||||
|
:param message:
|
||||||
|
:type message:
|
||||||
:return:
|
:return:
|
||||||
:rtype:
|
:rtype:
|
||||||
"""
|
"""
|
||||||
|
|||||||
27
apps/cic-notify/docker/Dockerfile_ci
Normal file
27
apps/cic-notify/docker/Dockerfile_ci
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# syntax = docker/dockerfile:1.2
|
||||||
|
FROM registry.gitlab.com/grassrootseconomics/cic-base-images:python-3.8.6-dev-55da5f4e as dev
|
||||||
|
|
||||||
|
#RUN pip install $pip_extra_index_url_flag cic-base[full_graph]==0.1.2a62
|
||||||
|
|
||||||
|
ARG EXTRA_INDEX_URL="https://pip.grassrootseconomics.net:8433"
|
||||||
|
ARG GITLAB_PYTHON_REGISTRY="https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple"
|
||||||
|
COPY requirements.txt .
|
||||||
|
|
||||||
|
RUN pip install --index-url https://pypi.org/simple \
|
||||||
|
--extra-index-url $GITLAB_PYTHON_REGISTRY --extra-index-url $EXTRA_INDEX_URL \
|
||||||
|
-r requirements.txt
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN python setup.py install
|
||||||
|
|
||||||
|
COPY docker/*.sh .
|
||||||
|
RUN chmod +x *.sh
|
||||||
|
|
||||||
|
# ini files in config directory defines the configurable parameters for the application
|
||||||
|
# they can all be overridden by environment variables
|
||||||
|
# to generate a list of environment variables from configuration, use: confini-dump -z <dir> (executable provided by confini package)
|
||||||
|
COPY .config/ /usr/local/etc/cic-notify/
|
||||||
|
COPY cic_notify/db/migrations/ /usr/local/share/cic-notify/alembic/
|
||||||
|
|
||||||
|
ENTRYPOINT []
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
pip install --extra-index-url https://pip.grassrootseconomics.net:8433 \
|
|
||||||
--extra-index-url https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple \
|
|
||||||
-r test_requirements.txt
|
|
||||||
|
|
||||||
export PYTHONPATH=. && pytest -x --cov=cic_notify --cov-fail-under=90 --cov-report term-missing tests
|
|
||||||
@@ -1,16 +1,52 @@
|
|||||||
build-test-cic-ussd:
|
.cic_ussd_variables:
|
||||||
stage: test
|
variables:
|
||||||
tags:
|
APP_NAME: cic-ussd
|
||||||
- integration
|
DOCKERFILE_PATH: docker/Dockerfile_ci
|
||||||
variables:
|
CONTEXT: apps/$APP_NAME
|
||||||
APP_NAME: cic-ussd
|
|
||||||
MR_IMAGE_TAG: mr-$APP_NAME-$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA
|
build-mr-cic-ussd:
|
||||||
script:
|
extends:
|
||||||
- cd apps/cic-ussd
|
- .py_build_merge_request
|
||||||
- docker build -t $MR_IMAGE_TAG -f docker/Dockerfile .
|
- .cic_ussd_variables
|
||||||
- docker run $MR_IMAGE_TAG sh docker/run_tests.sh
|
rules:
|
||||||
rules:
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
changes:
|
||||||
changes:
|
- apps/cic-ussd/**/*
|
||||||
- apps/$APP_NAME/**/*
|
when: always
|
||||||
when: always
|
|
||||||
|
test-mr-cic-ussd:
|
||||||
|
stage: test
|
||||||
|
extends:
|
||||||
|
- .cic_ussd_variables
|
||||||
|
cache:
|
||||||
|
key:
|
||||||
|
files:
|
||||||
|
- test_requirements.txt
|
||||||
|
paths:
|
||||||
|
- /root/.cache/pip
|
||||||
|
image: $MR_IMAGE_TAG
|
||||||
|
script:
|
||||||
|
- cd apps/$APP_NAME/
|
||||||
|
- >
|
||||||
|
pip install --extra-index-url https://pip.grassrootseconomics.net:8433
|
||||||
|
--extra-index-url https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple
|
||||||
|
-r test_requirements.txt
|
||||||
|
- export PYTHONPATH=. && pytest -x --cov=cic_ussd --cov-fail-under=90 --cov-report term-missing tests/cic_ussd
|
||||||
|
needs: ["build-mr-cic-ussd"]
|
||||||
|
rules:
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
|
changes:
|
||||||
|
- apps/$APP_NAME/**/*
|
||||||
|
when: always
|
||||||
|
|
||||||
|
build-push-cic-ussd:
|
||||||
|
extends:
|
||||||
|
- .py_build_push
|
||||||
|
- .cic_ussd_variables
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH == "master"
|
||||||
|
changes:
|
||||||
|
- apps/cic-ussd/**/*
|
||||||
|
when: always
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
# standard imports
|
# standard imports
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
# third-party imports
|
# third-party imports
|
||||||
from cic_eth.api import Api
|
from cic_eth.api import Api
|
||||||
from cic_eth_aux.erc20_demurrage_token.api import Api as DemurrageApi
|
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from cic_ussd.account.transaction import from_wei
|
from cic_ussd.account.transaction import from_wei
|
||||||
@@ -75,24 +73,6 @@ def calculate_available_balance(balances: dict) -> float:
|
|||||||
return from_wei(value=available_balance)
|
return from_wei(value=available_balance)
|
||||||
|
|
||||||
|
|
||||||
def get_adjusted_balance(balance: int, chain_str: str, timestamp: int, token_symbol: str):
|
|
||||||
"""
|
|
||||||
:param balance:
|
|
||||||
:type balance:
|
|
||||||
:param chain_str:
|
|
||||||
:type chain_str:
|
|
||||||
:param timestamp:
|
|
||||||
:type timestamp:
|
|
||||||
:param token_symbol:
|
|
||||||
:type token_symbol:
|
|
||||||
:return:
|
|
||||||
:rtype:
|
|
||||||
"""
|
|
||||||
logg.debug(f'retrieving adjusted balance on chain: {chain_str}')
|
|
||||||
demurrage_api = DemurrageApi(chain_str=chain_str)
|
|
||||||
return demurrage_api.get_adjusted_balance(token_symbol, balance, timestamp).result
|
|
||||||
|
|
||||||
|
|
||||||
def get_cached_available_balance(blockchain_address: str) -> float:
|
def get_cached_available_balance(blockchain_address: str) -> float:
|
||||||
"""This function attempts to retrieve balance data from the redis cache.
|
"""This function attempts to retrieve balance data from the redis cache.
|
||||||
:param blockchain_address: Ethereum address of an account.
|
:param blockchain_address: Ethereum address of an account.
|
||||||
@@ -108,14 +88,3 @@ def get_cached_available_balance(blockchain_address: str) -> float:
|
|||||||
return calculate_available_balance(json.loads(cached_balances))
|
return calculate_available_balance(json.loads(cached_balances))
|
||||||
else:
|
else:
|
||||||
raise CachedDataNotFoundError(f'No cached available balance for address: {blockchain_address}')
|
raise CachedDataNotFoundError(f'No cached available balance for address: {blockchain_address}')
|
||||||
|
|
||||||
|
|
||||||
def get_cached_adjusted_balance(identifier: bytes):
|
|
||||||
"""
|
|
||||||
:param identifier:
|
|
||||||
:type identifier:
|
|
||||||
:return:
|
|
||||||
:rtype:
|
|
||||||
"""
|
|
||||||
key = cache_data_key(identifier, ':cic.adjusted_balance')
|
|
||||||
return get_cached_data(key)
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# standard import
|
# standard import
|
||||||
import decimal
|
import decimal
|
||||||
import json
|
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict, Tuple
|
from typing import Dict, Tuple
|
||||||
|
|
||||||
@@ -9,8 +8,6 @@ from cic_eth.api import Api
|
|||||||
from sqlalchemy.orm.session import Session
|
from sqlalchemy.orm.session import Session
|
||||||
|
|
||||||
# local import
|
# local import
|
||||||
from cic_ussd.account.chain import Chain
|
|
||||||
from cic_ussd.account.tokens import get_cached_default_token
|
|
||||||
from cic_ussd.db.models.account import Account
|
from cic_ussd.db.models.account import Account
|
||||||
from cic_ussd.db.models.base import SessionBase
|
from cic_ussd.db.models.base import SessionBase
|
||||||
from cic_ussd.error import UnknownUssdRecipient
|
from cic_ussd.error import UnknownUssdRecipient
|
||||||
@@ -62,9 +59,7 @@ def from_wei(value: int) -> float:
|
|||||||
:return: SRF equivalent of value in Wei
|
:return: SRF equivalent of value in Wei
|
||||||
:rtype: float
|
:rtype: float
|
||||||
"""
|
"""
|
||||||
cached_token_data = json.loads(get_cached_default_token(Chain.spec.__str__()))
|
value = float(value) / 1e+6
|
||||||
token_decimals: int = cached_token_data.get('decimals')
|
|
||||||
value = float(value) / (10**token_decimals)
|
|
||||||
return truncate(value=value, decimals=2)
|
return truncate(value=value, decimals=2)
|
||||||
|
|
||||||
|
|
||||||
@@ -75,9 +70,7 @@ def to_wei(value: int) -> int:
|
|||||||
:return: Wei equivalent of value in SRF
|
:return: Wei equivalent of value in SRF
|
||||||
:rtype: int
|
:rtype: int
|
||||||
"""
|
"""
|
||||||
cached_token_data = json.loads(get_cached_default_token(Chain.spec.__str__()))
|
return int(value * 1e+6)
|
||||||
token_decimals: int = cached_token_data.get('decimals')
|
|
||||||
return int(value * (10**token_decimals))
|
|
||||||
|
|
||||||
|
|
||||||
def truncate(value: float, decimals: int):
|
def truncate(value: float, decimals: int):
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class MetadataRequestsHandler(Metadata):
|
|||||||
|
|
||||||
def create(self, data: Union[Dict, str]):
|
def create(self, data: Union[Dict, str]):
|
||||||
""""""
|
""""""
|
||||||
data = json.dumps(data).encode('utf-8')
|
data = json.dumps(data)
|
||||||
result = make_request(method='POST', url=self.url, data=data, headers=self.headers)
|
result = make_request(method='POST', url=self.url, data=data, headers=self.headers)
|
||||||
|
|
||||||
error_handler(result=result)
|
error_handler(result=result)
|
||||||
|
|||||||
@@ -1,17 +1,13 @@
|
|||||||
# standard imports
|
# standard imports
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime, timedelta
|
|
||||||
|
|
||||||
# external imports
|
# external imports
|
||||||
import i18n.config
|
import i18n.config
|
||||||
|
from sqlalchemy.orm.session import Session
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from cic_ussd.account.balance import (calculate_available_balance,
|
from cic_ussd.account.balance import calculate_available_balance, get_balances, get_cached_available_balance
|
||||||
get_adjusted_balance,
|
|
||||||
get_balances,
|
|
||||||
get_cached_adjusted_balance,
|
|
||||||
get_cached_available_balance)
|
|
||||||
from cic_ussd.account.chain import Chain
|
from cic_ussd.account.chain import Chain
|
||||||
from cic_ussd.account.metadata import get_cached_preferred_language
|
from cic_ussd.account.metadata import get_cached_preferred_language
|
||||||
from cic_ussd.account.statement import (
|
from cic_ussd.account.statement import (
|
||||||
@@ -20,15 +16,14 @@ from cic_ussd.account.statement import (
|
|||||||
query_statement,
|
query_statement,
|
||||||
statement_transaction_set
|
statement_transaction_set
|
||||||
)
|
)
|
||||||
from cic_ussd.account.tokens import get_default_token_symbol
|
|
||||||
from cic_ussd.account.transaction import from_wei, to_wei
|
from cic_ussd.account.transaction import from_wei, to_wei
|
||||||
|
from cic_ussd.account.tokens import get_default_token_symbol
|
||||||
from cic_ussd.cache import cache_data_key, cache_data
|
from cic_ussd.cache import cache_data_key, cache_data
|
||||||
from cic_ussd.db.models.account import Account
|
from cic_ussd.db.models.account import Account
|
||||||
from cic_ussd.metadata import PersonMetadata
|
from cic_ussd.metadata import PersonMetadata
|
||||||
from cic_ussd.phone_number import Support
|
from cic_ussd.phone_number import Support
|
||||||
from cic_ussd.processor.util import parse_person_metadata
|
from cic_ussd.processor.util import latest_input, parse_person_metadata
|
||||||
from cic_ussd.translation import translation_for
|
from cic_ussd.translation import translation_for
|
||||||
from sqlalchemy.orm.session import Session
|
|
||||||
|
|
||||||
logg = logging.getLogger(__name__)
|
logg = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -48,26 +43,21 @@ class MenuProcessor:
|
|||||||
:rtype:
|
:rtype:
|
||||||
"""
|
"""
|
||||||
available_balance = get_cached_available_balance(self.account.blockchain_address)
|
available_balance = get_cached_available_balance(self.account.blockchain_address)
|
||||||
adjusted_balance = get_cached_adjusted_balance(self.identifier)
|
logg.debug('Requires call to retrieve tax and bonus amounts')
|
||||||
|
tax = ''
|
||||||
|
bonus = ''
|
||||||
token_symbol = get_default_token_symbol()
|
token_symbol = get_default_token_symbol()
|
||||||
preferred_language = get_cached_preferred_language(self.account.blockchain_address)
|
preferred_language = get_cached_preferred_language(self.account.blockchain_address)
|
||||||
if not preferred_language:
|
if not preferred_language:
|
||||||
preferred_language = i18n.config.get('fallback')
|
preferred_language = i18n.config.get('fallback')
|
||||||
with_available_balance = f'{self.display_key}.available_balance'
|
return translation_for(
|
||||||
with_fees = f'{self.display_key}.with_fees'
|
key=self.display_key,
|
||||||
if not adjusted_balance:
|
preferred_language=preferred_language,
|
||||||
return translation_for(key=with_available_balance,
|
available_balance=available_balance,
|
||||||
preferred_language=preferred_language,
|
tax=tax,
|
||||||
available_balance=available_balance,
|
bonus=bonus,
|
||||||
token_symbol=token_symbol)
|
token_symbol=token_symbol
|
||||||
adjusted_balance = json.loads(adjusted_balance)
|
)
|
||||||
tax_wei = to_wei(int(available_balance)) - int(adjusted_balance)
|
|
||||||
tax = from_wei(int(tax_wei))
|
|
||||||
return translation_for(key=with_fees,
|
|
||||||
preferred_language=preferred_language,
|
|
||||||
available_balance=available_balance,
|
|
||||||
tax=tax,
|
|
||||||
token_symbol=token_symbol)
|
|
||||||
|
|
||||||
def account_statement(self) -> str:
|
def account_statement(self) -> str:
|
||||||
"""
|
"""
|
||||||
@@ -77,7 +67,7 @@ class MenuProcessor:
|
|||||||
cached_statement = get_cached_statement(self.account.blockchain_address)
|
cached_statement = get_cached_statement(self.account.blockchain_address)
|
||||||
statement = json.loads(cached_statement)
|
statement = json.loads(cached_statement)
|
||||||
statement_transactions = parse_statement_transactions(statement)
|
statement_transactions = parse_statement_transactions(statement)
|
||||||
transaction_sets = [statement_transactions[tx:tx + 3] for tx in range(0, len(statement_transactions), 3)]
|
transaction_sets = [statement_transactions[tx:tx+3] for tx in range(0, len(statement_transactions), 3)]
|
||||||
preferred_language = get_cached_preferred_language(self.account.blockchain_address)
|
preferred_language = get_cached_preferred_language(self.account.blockchain_address)
|
||||||
if not preferred_language:
|
if not preferred_language:
|
||||||
preferred_language = i18n.config.get('fallback')
|
preferred_language = i18n.config.get('fallback')
|
||||||
@@ -159,22 +149,12 @@ class MenuProcessor:
|
|||||||
:return:
|
:return:
|
||||||
:rtype:
|
:rtype:
|
||||||
"""
|
"""
|
||||||
chain_str = Chain.spec.__str__()
|
|
||||||
token_symbol = get_default_token_symbol()
|
token_symbol = get_default_token_symbol()
|
||||||
blockchain_address = self.account.blockchain_address
|
blockchain_address = self.account.blockchain_address
|
||||||
balances = get_balances(blockchain_address, chain_str, token_symbol, False)[0]
|
balances = get_balances(blockchain_address, Chain.spec.__str__(), token_symbol, False)[0]
|
||||||
key = cache_data_key(self.identifier, ':cic.balances')
|
key = cache_data_key(self.identifier, ':cic.balances')
|
||||||
cache_data(key, json.dumps(balances))
|
cache_data(key, json.dumps(balances))
|
||||||
available_balance = calculate_available_balance(balances)
|
available_balance = calculate_available_balance(balances)
|
||||||
now = datetime.now()
|
|
||||||
if (now - self.account.created).days >= 30:
|
|
||||||
if available_balance <= 0:
|
|
||||||
logg.info(f'Not retrieving adjusted balance, available balance: {available_balance} is insufficient.')
|
|
||||||
else:
|
|
||||||
timestamp = int((now - timedelta(30)).timestamp())
|
|
||||||
adjusted_balance = get_adjusted_balance(to_wei(int(available_balance)), chain_str, timestamp, token_symbol)
|
|
||||||
key = cache_data_key(self.identifier, ':cic.adjusted_balance')
|
|
||||||
cache_data(key, json.dumps(adjusted_balance))
|
|
||||||
|
|
||||||
query_statement(blockchain_address)
|
query_statement(blockchain_address)
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ elif ssl == 0:
|
|||||||
else:
|
else:
|
||||||
ssl = True
|
ssl = True
|
||||||
|
|
||||||
valid_service_codes = config.get('USSD_SERVICE_CODE').split(",")
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
# TODO: improve url building
|
# TODO: improve url building
|
||||||
@@ -79,9 +79,9 @@ def main():
|
|||||||
session = uuid.uuid4().hex
|
session = uuid.uuid4().hex
|
||||||
data = {
|
data = {
|
||||||
'sessionId': session,
|
'sessionId': session,
|
||||||
'serviceCode': valid_service_codes[0],
|
'serviceCode': config.get('APP_SERVICE_CODE'),
|
||||||
'phoneNumber': args.phone,
|
'phoneNumber': args.phone,
|
||||||
'text': "",
|
'text': config.get('APP_SERVICE_CODE'),
|
||||||
}
|
}
|
||||||
|
|
||||||
state = "_BEGIN"
|
state = "_BEGIN"
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ def create_ussd_session(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def update_ussd_session(ussd_session: DbUssdSession,
|
def update_ussd_session(ussd_session: UssdSession,
|
||||||
user_input: str,
|
user_input: str,
|
||||||
state: str,
|
state: str,
|
||||||
data: Optional[dict] = None) -> UssdSession:
|
data: Optional[dict] = None) -> UssdSession:
|
||||||
|
|||||||
@@ -154,14 +154,15 @@ def parse_person_metadata(account: Account, metadata: dict):
|
|||||||
phone_number = account.phone_number
|
phone_number = account.phone_number
|
||||||
date_registered = int(account.created.replace().timestamp())
|
date_registered = int(account.created.replace().timestamp())
|
||||||
blockchain_address = account.blockchain_address
|
blockchain_address = account.blockchain_address
|
||||||
chain_str = Chain.spec.__str__()
|
chain_spec = f'{Chain.spec.common_name()}:{Chain.spec.engine()}: {Chain.spec.chain_id()}'
|
||||||
|
|
||||||
if isinstance(metadata.get('identities'), dict):
|
if isinstance(metadata.get('identities'), dict):
|
||||||
identities = metadata.get('identities')
|
identities = metadata.get('identities')
|
||||||
else:
|
else:
|
||||||
identities = manage_identity_data(
|
identities = manage_identity_data(
|
||||||
blockchain_address=blockchain_address,
|
blockchain_address=blockchain_address,
|
||||||
chain_str=chain_str
|
blockchain_type=Chain.spec.engine(),
|
||||||
|
chain_spec=chain_spec
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -138,14 +138,26 @@ def transaction_balances_callback(self, result: list, param: dict, status_code:
|
|||||||
balances_data = result[0]
|
balances_data = result[0]
|
||||||
available_balance = calculate_available_balance(balances_data)
|
available_balance = calculate_available_balance(balances_data)
|
||||||
transaction = param
|
transaction = param
|
||||||
|
blockchain_address = transaction.get('blockchain_address')
|
||||||
transaction['available_balance'] = available_balance
|
transaction['available_balance'] = available_balance
|
||||||
queue = self.request.delivery_info.get('routing_key')
|
queue = self.request.delivery_info.get('routing_key')
|
||||||
|
|
||||||
|
s_preferences_metadata = celery.signature(
|
||||||
|
'cic_ussd.tasks.metadata.query_preferences_metadata', [blockchain_address], queue=queue
|
||||||
|
)
|
||||||
s_process_account_metadata = celery.signature(
|
s_process_account_metadata = celery.signature(
|
||||||
'cic_ussd.tasks.processor.parse_transaction', [transaction], queue=queue
|
'cic_ussd.tasks.processor.parse_transaction', [transaction], queue=queue
|
||||||
)
|
)
|
||||||
s_notify_account = celery.signature('cic_ussd.tasks.notifications.transaction', queue=queue)
|
s_notify_account = celery.signature('cic_ussd.tasks.notifications.transaction', queue=queue)
|
||||||
celery.chain(s_process_account_metadata, s_notify_account).apply_async()
|
|
||||||
|
if transaction.get('transaction_type') == 'transfer':
|
||||||
|
celery.chain(s_preferences_metadata, s_process_account_metadata, s_notify_account).apply_async()
|
||||||
|
|
||||||
|
if transaction.get('transaction_type') == 'tokengift':
|
||||||
|
s_process_account_metadata = celery.signature(
|
||||||
|
'cic_ussd.tasks.processor.parse_transaction', [{}, transaction], queue=queue
|
||||||
|
)
|
||||||
|
celery.chain(s_process_account_metadata, s_notify_account).apply_async()
|
||||||
|
|
||||||
|
|
||||||
@celery_app.task
|
@celery_app.task
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ def transaction(notification_data: dict):
|
|||||||
:rtype:
|
:rtype:
|
||||||
"""
|
"""
|
||||||
role = notification_data.get('role')
|
role = notification_data.get('role')
|
||||||
token_value = notification_data.get('token_value')
|
amount = from_wei(notification_data.get('token_value'))
|
||||||
amount = token_value if token_value == 0 else from_wei(token_value)
|
|
||||||
balance = notification_data.get('available_balance')
|
balance = notification_data.get('available_balance')
|
||||||
phone_number = notification_data.get('phone_number')
|
phone_number = notification_data.get('phone_number')
|
||||||
preferred_language = notification_data.get('preferred_language')
|
preferred_language = notification_data.get('preferred_language')
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import i18n
|
|||||||
from chainlib.hash import strip_0x
|
from chainlib.hash import strip_0x
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from cic_ussd.account.metadata import get_cached_preferred_language
|
|
||||||
from cic_ussd.account.statement import get_cached_statement
|
from cic_ussd.account.statement import get_cached_statement
|
||||||
from cic_ussd.account.transaction import aux_transaction_data, validate_transaction_account
|
from cic_ussd.account.transaction import aux_transaction_data, validate_transaction_account
|
||||||
from cic_ussd.cache import cache_data, cache_data_key
|
from cic_ussd.cache import cache_data, cache_data_key
|
||||||
@@ -59,17 +58,19 @@ def cache_statement(parsed_transaction: dict, querying_party: str):
|
|||||||
|
|
||||||
|
|
||||||
@celery_app.task
|
@celery_app.task
|
||||||
def parse_transaction(transaction: dict) -> dict:
|
def parse_transaction(preferences: dict, transaction: dict) -> dict:
|
||||||
"""This function parses transaction objects and collates all relevant data for system use i.e:
|
"""This function parses transaction objects and collates all relevant data for system use i.e:
|
||||||
- An account's set preferred language.
|
- An account's set preferred language.
|
||||||
- Account identifier that facilitates notification.
|
- Account identifier that facilitates notification.
|
||||||
- Contextual tags i.e action and direction tags.
|
- Contextual tags i.e action and direction tags.
|
||||||
|
:param preferences: An account's set preferences.
|
||||||
|
:type preferences: dict
|
||||||
:param transaction: Transaction object.
|
:param transaction: Transaction object.
|
||||||
:type transaction: dict
|
:type transaction: dict
|
||||||
:return: Transaction object with contextual data for use in the system.
|
:return: Transaction object with contextual data for use in the system.
|
||||||
:rtype: dict
|
:rtype: dict
|
||||||
"""
|
"""
|
||||||
preferred_language = get_cached_preferred_language(transaction.get('blockchain_address'))
|
preferred_language = preferences.get('preferred_language')
|
||||||
if not preferred_language:
|
if not preferred_language:
|
||||||
preferred_language = i18n.config.get('fallback')
|
preferred_language = i18n.config.get('fallback')
|
||||||
transaction['preferred_language'] = preferred_language
|
transaction['preferred_language'] = preferred_language
|
||||||
@@ -82,8 +83,6 @@ def parse_transaction(transaction: dict) -> dict:
|
|||||||
alt_account = session.query(Account).filter_by(blockchain_address=alt_blockchain_address).first()
|
alt_account = session.query(Account).filter_by(blockchain_address=alt_blockchain_address).first()
|
||||||
if alt_account:
|
if alt_account:
|
||||||
transaction['alt_metadata_id'] = alt_account.standard_metadata_id()
|
transaction['alt_metadata_id'] = alt_account.standard_metadata_id()
|
||||||
else:
|
|
||||||
transaction['alt_metadata_id'] = 'GRASSROOTS ECONOMICS'
|
|
||||||
transaction['metadata_id'] = account.standard_metadata_id()
|
transaction['metadata_id'] = account.standard_metadata_id()
|
||||||
transaction['phone_number'] = account.phone_number
|
transaction['phone_number'] = account.phone_number
|
||||||
session.close()
|
session.close()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# standard imports
|
# standard imports
|
||||||
import semver
|
import semver
|
||||||
|
|
||||||
version = (0, 3, 1, 'alpha.5')
|
version = (0, 3, 1, 'alpha.4')
|
||||||
|
|
||||||
version_object = semver.VersionInfo(
|
version_object = semver.VersionInfo(
|
||||||
major=version[0],
|
major=version[0],
|
||||||
|
|||||||
2
apps/cic-ussd/config/client/app.ini
Normal file
2
apps/cic-ussd/config/client/app.ini
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[app]
|
||||||
|
service_code = *483*46#
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
[ussd]
|
[ussd]
|
||||||
service_code = *483*46#
|
|
||||||
user =
|
user =
|
||||||
pass =
|
pass =
|
||||||
|
|||||||
@@ -10,13 +10,6 @@ RUN mkdir -vp data
|
|||||||
|
|
||||||
ARG EXTRA_INDEX_URL="https://pip.grassrootseconomics.net:8433"
|
ARG EXTRA_INDEX_URL="https://pip.grassrootseconomics.net:8433"
|
||||||
ARG GITLAB_PYTHON_REGISTRY="https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple"
|
ARG GITLAB_PYTHON_REGISTRY="https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple"
|
||||||
|
|
||||||
RUN --mount=type=cache,mode=0755,target=/root/.cache/pip \
|
|
||||||
pip install --index-url https://pypi.org/simple \
|
|
||||||
--extra-index-url $GITLAB_PYTHON_REGISTRY \
|
|
||||||
--extra-index-url $EXTRA_INDEX_URL \
|
|
||||||
cic-eth-aux-erc20-demurrage-token~=0.0.2a6
|
|
||||||
|
|
||||||
COPY requirements.txt .
|
COPY requirements.txt .
|
||||||
|
|
||||||
RUN --mount=type=cache,mode=0755,target=/root/.cache/pip \
|
RUN --mount=type=cache,mode=0755,target=/root/.cache/pip \
|
||||||
|
|||||||
32
apps/cic-ussd/docker/Dockerfile_ci
Normal file
32
apps/cic-ussd/docker/Dockerfile_ci
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# syntax = docker/dockerfile:1.2
|
||||||
|
FROM registry.gitlab.com/grassrootseconomics/cic-base-images:python-3.8.6-dev-55da5f4e as dev
|
||||||
|
RUN apt-get install -y redis-server
|
||||||
|
|
||||||
|
# create secrets directory
|
||||||
|
RUN mkdir -vp pgp/keys
|
||||||
|
|
||||||
|
# create application directory
|
||||||
|
RUN mkdir -vp cic-ussd
|
||||||
|
RUN mkdir -vp data
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
|
||||||
|
ARG EXTRA_INDEX_URL="https://pip.grassrootseconomics.net:8433"
|
||||||
|
ARG GITLAB_PYTHON_REGISTRY="https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple"
|
||||||
|
RUN pip install --index-url https://pypi.org/simple \
|
||||||
|
--extra-index-url $GITLAB_PYTHON_REGISTRY --extra-index-url $EXTRA_INDEX_URL \
|
||||||
|
-r requirements.txt
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN python setup.py install
|
||||||
|
|
||||||
|
COPY cic_ussd/db/ussd_menu.json data/
|
||||||
|
|
||||||
|
COPY docker/*.sh .
|
||||||
|
RUN chmod +x /root/*.sh
|
||||||
|
|
||||||
|
# copy config and migration files to definitive file so they can be referenced in path definitions for running scripts
|
||||||
|
COPY config/ /usr/local/etc/cic-ussd/
|
||||||
|
COPY cic_ussd/db/migrations/ /usr/local/share/cic-ussd/alembic
|
||||||
|
|
||||||
|
ENTRYPOINT []
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
|
|
||||||
pip install --extra-index-url https://pip.grassrootseconomics.net:8433 \
|
|
||||||
--extra-index-url https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple \
|
|
||||||
-r test_requirements.txt
|
|
||||||
|
|
||||||
export PYTHONPATH=. && pytest -x --cov=cic_ussd --cov-fail-under=90 --cov-report term-missing tests/cic_ussd
|
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
alembic==1.4.2
|
alembic==1.4.2
|
||||||
attrs==21.2.0
|
|
||||||
billiard==3.6.4.0
|
|
||||||
bcrypt==3.2.0
|
bcrypt==3.2.0
|
||||||
celery==4.4.7
|
celery==4.4.7
|
||||||
cffi==1.14.6
|
|
||||||
cic-eth[services]~=0.12.4a7
|
cic-eth[services]~=0.12.4a7
|
||||||
cic-notify~=0.4.0a10
|
cic-notify~=0.4.0a10
|
||||||
cic-types~=0.1.0a15
|
cic-types~=0.1.0a14
|
||||||
confini>=0.4.1a1,<0.5.0
|
confini>=0.4.1a1,<0.5.0
|
||||||
phonenumbers==8.12.12
|
phonenumbers==8.12.12
|
||||||
psycopg2==2.8.6
|
psycopg2==2.8.6
|
||||||
|
|||||||
@@ -43,13 +43,10 @@ def test_sync_get_balances(activated_account,
|
|||||||
(5000000, 89000000, 67000000, 27.00)
|
(5000000, 89000000, 67000000, 27.00)
|
||||||
])
|
])
|
||||||
def test_calculate_available_balance(activated_account,
|
def test_calculate_available_balance(activated_account,
|
||||||
available_balance,
|
|
||||||
balance_incoming,
|
balance_incoming,
|
||||||
balance_network,
|
balance_network,
|
||||||
balance_outgoing,
|
balance_outgoing,
|
||||||
cache_balances,
|
available_balance):
|
||||||
cache_default_token_data,
|
|
||||||
load_chain_spec):
|
|
||||||
balances = {
|
balances = {
|
||||||
'address': activated_account.blockchain_address,
|
'address': activated_account.blockchain_address,
|
||||||
'converters': [],
|
'converters': [],
|
||||||
@@ -60,11 +57,7 @@ def test_calculate_available_balance(activated_account,
|
|||||||
assert calculate_available_balance(balances) == available_balance
|
assert calculate_available_balance(balances) == available_balance
|
||||||
|
|
||||||
|
|
||||||
def test_get_cached_available_balance(activated_account,
|
def test_get_cached_available_balance(activated_account, cache_balances, balances):
|
||||||
balances,
|
|
||||||
cache_balances,
|
|
||||||
cache_default_token_data,
|
|
||||||
load_chain_spec):
|
|
||||||
cached_available_balance = get_cached_available_balance(activated_account.blockchain_address)
|
cached_available_balance = get_cached_available_balance(activated_account.blockchain_address)
|
||||||
available_balance = calculate_available_balance(balances[0])
|
available_balance = calculate_available_balance(balances[0])
|
||||||
assert cached_available_balance == available_balance
|
assert cached_available_balance == available_balance
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ def test_filter_statement_transactions(transactions_list):
|
|||||||
|
|
||||||
|
|
||||||
def test_generate(activated_account,
|
def test_generate(activated_account,
|
||||||
cache_default_token_data,
|
|
||||||
cache_statement,
|
|
||||||
cache_preferences,
|
cache_preferences,
|
||||||
celery_session_worker,
|
celery_session_worker,
|
||||||
init_cache,
|
init_cache,
|
||||||
@@ -62,7 +60,7 @@ def test_get_cached_statement(activated_account, cache_statement, statement):
|
|||||||
assert cached_statement[0].get('blockchain_address') == statement[0].get('blockchain_address')
|
assert cached_statement[0].get('blockchain_address') == statement[0].get('blockchain_address')
|
||||||
|
|
||||||
|
|
||||||
def test_parse_statement_transactions(cache_default_token_data, statement):
|
def test_parse_statement_transactions(statement):
|
||||||
parsed_transactions = parse_statement_transactions(statement)
|
parsed_transactions = parse_statement_transactions(statement)
|
||||||
parsed_transaction = parsed_transactions[0]
|
parsed_transaction = parsed_transactions[0]
|
||||||
parsed_transaction.startswith('Sent')
|
parsed_transaction.startswith('Sent')
|
||||||
@@ -78,7 +76,7 @@ def test_query_statement(blockchain_address, limit, load_chain_spec, activated_a
|
|||||||
assert mock_transaction_list_query.get('limit') == limit
|
assert mock_transaction_list_query.get('limit') == limit
|
||||||
|
|
||||||
|
|
||||||
def test_statement_transaction_set(cache_default_token_data, load_chain_spec, preferences, set_locale_files, statement):
|
def test_statement_transaction_set(preferences, set_locale_files, statement):
|
||||||
parsed_transactions = parse_statement_transactions(statement)
|
parsed_transactions = parse_statement_transactions(statement)
|
||||||
preferred_language = preferences.get('preferred_language')
|
preferred_language = preferences.get('preferred_language')
|
||||||
transaction_set = statement_transaction_set(preferred_language, parsed_transactions)
|
transaction_set = statement_transaction_set(preferred_language, parsed_transactions)
|
||||||
|
|||||||
@@ -36,19 +36,19 @@ def test_aux_transaction_data(preferences, set_locale_files, transactions_list):
|
|||||||
check_aux_data('helpers.sent', 'helpers.to', preferred_language, sender_tx_aux_data)
|
check_aux_data('helpers.sent', 'helpers.to', preferred_language, sender_tx_aux_data)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("value, expected_result", [
|
@pytest.mark.parametrize("wei, expected_result", [
|
||||||
(50000000, Decimal('50.00')),
|
(50000000, Decimal('50.00')),
|
||||||
(100000, Decimal('0.10'))
|
(100000, Decimal('0.10'))
|
||||||
])
|
])
|
||||||
def test_from_wei(cache_default_token_data, expected_result, value):
|
def test_from_wei(wei, expected_result):
|
||||||
assert from_wei(value) == expected_result
|
assert from_wei(wei) == expected_result
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("value, expected_result", [
|
@pytest.mark.parametrize("value, expected_result", [
|
||||||
(50, 50000000),
|
(50, 50000000),
|
||||||
(0.10, 100000)
|
(0.10, 100000)
|
||||||
])
|
])
|
||||||
def test_to_wei(cache_default_token_data, expected_result, value):
|
def test_to_wei(value, expected_result):
|
||||||
assert to_wei(value) == expected_result
|
assert to_wei(value) == expected_result
|
||||||
|
|
||||||
|
|
||||||
@@ -96,7 +96,6 @@ def test_validate_transaction_account(activated_account, init_database, transact
|
|||||||
@pytest.mark.parametrize("amount", [50, 0.10])
|
@pytest.mark.parametrize("amount", [50, 0.10])
|
||||||
def test_outgoing_transaction_processor(activated_account,
|
def test_outgoing_transaction_processor(activated_account,
|
||||||
amount,
|
amount,
|
||||||
cache_default_token_data,
|
|
||||||
celery_session_worker,
|
celery_session_worker,
|
||||||
load_config,
|
load_config,
|
||||||
load_chain_spec,
|
load_chain_spec,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# standard imports
|
# standard imports
|
||||||
import json
|
import json
|
||||||
import datetime
|
|
||||||
|
|
||||||
# external imports
|
# external imports
|
||||||
from chainlib.hash import strip_0x
|
from chainlib.hash import strip_0x
|
||||||
@@ -15,7 +14,6 @@ from cic_ussd.account.statement import (
|
|||||||
)
|
)
|
||||||
from cic_ussd.account.tokens import get_default_token_symbol
|
from cic_ussd.account.tokens import get_default_token_symbol
|
||||||
from cic_ussd.account.transaction import from_wei, to_wei
|
from cic_ussd.account.transaction import from_wei, to_wei
|
||||||
from cic_ussd.cache import cache_data, cache_data_key
|
|
||||||
from cic_ussd.menu.ussd_menu import UssdMenu
|
from cic_ussd.menu.ussd_menu import UssdMenu
|
||||||
from cic_ussd.metadata import PersonMetadata
|
from cic_ussd.metadata import PersonMetadata
|
||||||
from cic_ussd.phone_number import Support
|
from cic_ussd.phone_number import Support
|
||||||
@@ -40,34 +38,24 @@ def test_menu_processor(activated_account,
|
|||||||
load_chain_spec,
|
load_chain_spec,
|
||||||
load_support_phone,
|
load_support_phone,
|
||||||
load_ussd_menu,
|
load_ussd_menu,
|
||||||
mock_get_adjusted_balance,
|
|
||||||
mock_sync_balance_api_query,
|
mock_sync_balance_api_query,
|
||||||
mock_transaction_list_query,
|
mock_transaction_list_query,
|
||||||
valid_recipient):
|
valid_recipient):
|
||||||
preferred_language = get_cached_preferred_language(activated_account.blockchain_address)
|
preferred_language = get_cached_preferred_language(activated_account.blockchain_address)
|
||||||
available_balance = get_cached_available_balance(activated_account.blockchain_address)
|
available_balance = get_cached_available_balance(activated_account.blockchain_address)
|
||||||
token_symbol = get_default_token_symbol()
|
token_symbol = get_default_token_symbol()
|
||||||
with_available_balance = 'ussd.kenya.account_balances.available_balance'
|
|
||||||
with_fees = 'ussd.kenya.account_balances.with_fees'
|
tax = ''
|
||||||
|
bonus = ''
|
||||||
|
display_key = 'ussd.kenya.account_balances'
|
||||||
ussd_menu = UssdMenu.find_by_name('account_balances')
|
ussd_menu = UssdMenu.find_by_name('account_balances')
|
||||||
name = ussd_menu.get('name')
|
name = ussd_menu.get('name')
|
||||||
resp = response(activated_account, 'ussd.kenya.account_balances', name, init_database, generic_ussd_session)
|
resp = response(activated_account, display_key, name, init_database, generic_ussd_session)
|
||||||
assert resp == translation_for(with_available_balance,
|
assert resp == translation_for(display_key,
|
||||||
preferred_language,
|
preferred_language,
|
||||||
available_balance=available_balance,
|
available_balance=available_balance,
|
||||||
token_symbol=token_symbol)
|
|
||||||
|
|
||||||
identifier = bytes.fromhex(strip_0x(activated_account.blockchain_address))
|
|
||||||
key = cache_data_key(identifier, ':cic.adjusted_balance')
|
|
||||||
adjusted_balance = 45931650.64654012
|
|
||||||
cache_data(key, json.dumps(adjusted_balance))
|
|
||||||
resp = response(activated_account, 'ussd.kenya.account_balances', name, init_database, generic_ussd_session)
|
|
||||||
tax_wei = to_wei(int(available_balance)) - int(adjusted_balance)
|
|
||||||
tax = from_wei(int(tax_wei))
|
|
||||||
assert resp == translation_for(key=with_fees,
|
|
||||||
preferred_language=preferred_language,
|
|
||||||
available_balance=available_balance,
|
|
||||||
tax=tax,
|
tax=tax,
|
||||||
|
bonus=bonus,
|
||||||
token_symbol=token_symbol)
|
token_symbol=token_symbol)
|
||||||
|
|
||||||
cached_statement = get_cached_statement(activated_account.blockchain_address)
|
cached_statement = get_cached_statement(activated_account.blockchain_address)
|
||||||
@@ -135,15 +123,6 @@ def test_menu_processor(activated_account,
|
|||||||
account_balance=available_balance,
|
account_balance=available_balance,
|
||||||
account_token_name=token_symbol)
|
account_token_name=token_symbol)
|
||||||
|
|
||||||
display_key = 'ussd.kenya.start'
|
|
||||||
ussd_menu = UssdMenu.find_by_name('start')
|
|
||||||
name = ussd_menu.get('name')
|
|
||||||
older_timestamp = (activated_account.created - datetime.timedelta(days=35))
|
|
||||||
activated_account.created = older_timestamp
|
|
||||||
init_database.flush()
|
|
||||||
response(activated_account, display_key, name, init_database, generic_ussd_session)
|
|
||||||
assert mock_get_adjusted_balance['timestamp'] == int((datetime.datetime.now() - datetime.timedelta(days=30)).timestamp())
|
|
||||||
|
|
||||||
display_key = 'ussd.kenya.transaction_pin_authorization'
|
display_key = 'ussd.kenya.transaction_pin_authorization'
|
||||||
ussd_menu = UssdMenu.find_by_name('transaction_pin_authorization')
|
ussd_menu = UssdMenu.find_by_name('transaction_pin_authorization')
|
||||||
name = ussd_menu.get('name')
|
name = ussd_menu.get('name')
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ def test_is_valid_transaction_amount(activated_account, amount, expected_result,
|
|||||||
])
|
])
|
||||||
def test_has_sufficient_balance(activated_account,
|
def test_has_sufficient_balance(activated_account,
|
||||||
cache_balances,
|
cache_balances,
|
||||||
cache_default_token_data,
|
|
||||||
expected_result,
|
expected_result,
|
||||||
generic_ussd_session,
|
generic_ussd_session,
|
||||||
init_database,
|
init_database,
|
||||||
|
|||||||
@@ -121,7 +121,6 @@ def test_statement_callback(activated_account, mocker, transactions_list):
|
|||||||
def test_transaction_balances_callback(activated_account,
|
def test_transaction_balances_callback(activated_account,
|
||||||
balances,
|
balances,
|
||||||
cache_balances,
|
cache_balances,
|
||||||
cache_default_token_data,
|
|
||||||
cache_person_metadata,
|
cache_person_metadata,
|
||||||
cache_preferences,
|
cache_preferences,
|
||||||
load_chain_spec,
|
load_chain_spec,
|
||||||
|
|||||||
@@ -13,8 +13,7 @@ from cic_ussd.translation import translation_for
|
|||||||
# tests imports
|
# tests imports
|
||||||
|
|
||||||
|
|
||||||
def test_transaction(cache_default_token_data,
|
def test_transaction(celery_session_worker,
|
||||||
celery_session_worker,
|
|
||||||
load_support_phone,
|
load_support_phone,
|
||||||
mock_notifier_api,
|
mock_notifier_api,
|
||||||
notification_data,
|
notification_data,
|
||||||
|
|||||||
@@ -30,11 +30,10 @@ def test_generate_statement(activated_account,
|
|||||||
|
|
||||||
|
|
||||||
def test_cache_statement(activated_account,
|
def test_cache_statement(activated_account,
|
||||||
cache_default_token_data,
|
|
||||||
cache_person_metadata,
|
cache_person_metadata,
|
||||||
cache_preferences,
|
|
||||||
celery_session_worker,
|
celery_session_worker,
|
||||||
init_database,
|
init_database,
|
||||||
|
preferences,
|
||||||
transaction_result):
|
transaction_result):
|
||||||
recipient_transaction, sender_transaction = transaction_actors(transaction_result)
|
recipient_transaction, sender_transaction = transaction_actors(transaction_result)
|
||||||
identifier = bytes.fromhex(strip_0x(activated_account.blockchain_address))
|
identifier = bytes.fromhex(strip_0x(activated_account.blockchain_address))
|
||||||
@@ -42,7 +41,7 @@ def test_cache_statement(activated_account,
|
|||||||
cached_statement = get_cached_data(key)
|
cached_statement = get_cached_data(key)
|
||||||
assert cached_statement is None
|
assert cached_statement is None
|
||||||
s_parse_transaction = celery.signature(
|
s_parse_transaction = celery.signature(
|
||||||
'cic_ussd.tasks.processor.parse_transaction', [sender_transaction])
|
'cic_ussd.tasks.processor.parse_transaction', [preferences, sender_transaction])
|
||||||
result = s_parse_transaction.apply_async().get()
|
result = s_parse_transaction.apply_async().get()
|
||||||
s_cache_statement = celery.signature(
|
s_cache_statement = celery.signature(
|
||||||
'cic_ussd.tasks.processor.cache_statement', [result, activated_account.blockchain_address]
|
'cic_ussd.tasks.processor.cache_statement', [result, activated_account.blockchain_address]
|
||||||
@@ -62,15 +61,15 @@ def test_cache_statement(activated_account,
|
|||||||
|
|
||||||
def test_parse_transaction(activated_account,
|
def test_parse_transaction(activated_account,
|
||||||
cache_person_metadata,
|
cache_person_metadata,
|
||||||
cache_preferences,
|
|
||||||
celery_session_worker,
|
celery_session_worker,
|
||||||
init_database,
|
init_database,
|
||||||
|
preferences,
|
||||||
transaction_result):
|
transaction_result):
|
||||||
recipient_transaction, sender_transaction = transaction_actors(transaction_result)
|
recipient_transaction, sender_transaction = transaction_actors(transaction_result)
|
||||||
assert sender_transaction.get('metadata_id') is None
|
assert sender_transaction.get('metadata_id') is None
|
||||||
assert sender_transaction.get('phone_number') is None
|
assert sender_transaction.get('phone_number') is None
|
||||||
s_parse_transaction = celery.signature(
|
s_parse_transaction = celery.signature(
|
||||||
'cic_ussd.tasks.processor.parse_transaction', [sender_transaction])
|
'cic_ussd.tasks.processor.parse_transaction', [preferences, sender_transaction])
|
||||||
result = s_parse_transaction.apply_async().get()
|
result = s_parse_transaction.apply_async().get()
|
||||||
assert result.get('metadata_id') == activated_account.standard_metadata_id()
|
assert result.get('metadata_id') == activated_account.standard_metadata_id()
|
||||||
assert result.get('phone_number') == activated_account.phone_number
|
assert result.get('phone_number') == activated_account.phone_number
|
||||||
|
|||||||
16
apps/cic-ussd/tests/fixtures/patches/account.py
vendored
16
apps/cic-ussd/tests/fixtures/patches/account.py
vendored
@@ -41,22 +41,6 @@ def mock_async_balance_api_query(mocker):
|
|||||||
return query_args
|
return query_args
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='function')
|
|
||||||
def mock_get_adjusted_balance(mocker, task_uuid):
|
|
||||||
query_args = {}
|
|
||||||
|
|
||||||
def get_adjusted_balance(self, token_symbol, balance, timestamp):
|
|
||||||
sync_res = mocker.patch('celery.result.AsyncResult')
|
|
||||||
sync_res.id = task_uuid
|
|
||||||
sync_res.result = 45931650.64654012
|
|
||||||
query_args['balance'] = balance
|
|
||||||
query_args['timestamp'] = timestamp
|
|
||||||
query_args['token_symbol'] = token_symbol
|
|
||||||
return sync_res
|
|
||||||
mocker.patch('cic_eth_aux.erc20_demurrage_token.api.Api.get_adjusted_balance', get_adjusted_balance)
|
|
||||||
return query_args
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='function')
|
@pytest.fixture(scope='function')
|
||||||
def mock_notifier_api(mocker):
|
def mock_notifier_api(mocker):
|
||||||
sms = {}
|
sms = {}
|
||||||
|
|||||||
@@ -141,22 +141,12 @@ en:
|
|||||||
0. Back
|
0. Back
|
||||||
retry: |-
|
retry: |-
|
||||||
%{retry_pin_entry}
|
%{retry_pin_entry}
|
||||||
account_balances:
|
account_balances: |-
|
||||||
available_balance: |-
|
CON Your balances are as follows:
|
||||||
CON Your balances are as follows:
|
balance: %{available_balance} %{token_symbol}
|
||||||
balance: %{available_balance} %{token_symbol}
|
fees: %{tax} %{token_symbol}
|
||||||
0. Back
|
rewards: %{bonus} %{token_symbol}
|
||||||
with_fees: |-
|
0. Back
|
||||||
CON Your balances are as follows:
|
|
||||||
balances: %{available_balance} %{token_symbol}
|
|
||||||
fees: %{tax} %{token_symbol}
|
|
||||||
0. Back
|
|
||||||
with_rewards: |-
|
|
||||||
CON Your balances are as follows:
|
|
||||||
balance: %{available_balance} %{token_symbol}
|
|
||||||
fees: %{tax} %{token_symbol}
|
|
||||||
rewards: %{bonus} %{token_symbol}
|
|
||||||
0. Back
|
|
||||||
first_transaction_set: |-
|
first_transaction_set: |-
|
||||||
CON %{first_transaction_set}
|
CON %{first_transaction_set}
|
||||||
1. Next
|
1. Next
|
||||||
|
|||||||
@@ -13,22 +13,22 @@ sw:
|
|||||||
CON Weka jina lako la kwanza
|
CON Weka jina lako la kwanza
|
||||||
enter_family_name: |-
|
enter_family_name: |-
|
||||||
CON Weka jina lako la mwisho
|
CON Weka jina lako la mwisho
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
enter_date_of_birth: |-
|
enter_date_of_birth: |-
|
||||||
CON Weka mwaka wa kuzaliwa
|
CON Weka mwaka wa kuzaliwa
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
enter_gender: |-
|
enter_gender: |-
|
||||||
CON Weka jinsia yako
|
CON Weka jinsia yako
|
||||||
1. Mwanaume
|
1. Mwanaume
|
||||||
2. Mwanamke
|
2. Mwanamke
|
||||||
3. Nyngine
|
3. Nyngine
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
enter_location: |-
|
enter_location: |-
|
||||||
CON Weka eneo lako
|
CON Weka eneo lako
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
enter_products: |-
|
enter_products: |-
|
||||||
CON Weka bidhaa ama huduma unauza
|
CON Weka bidhaa ama huduma unauza
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
start: |-
|
start: |-
|
||||||
CON Salio %{account_balance} %{account_token_name}
|
CON Salio %{account_balance} %{account_token_name}
|
||||||
1. Tuma
|
1. Tuma
|
||||||
@@ -36,10 +36,10 @@ sw:
|
|||||||
3. Usaidizi
|
3. Usaidizi
|
||||||
enter_transaction_recipient: |-
|
enter_transaction_recipient: |-
|
||||||
CON Weka nambari ya simu
|
CON Weka nambari ya simu
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
enter_transaction_amount: |-
|
enter_transaction_amount: |-
|
||||||
CON Weka kiwango
|
CON Weka kiwango
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
account_management: |-
|
account_management: |-
|
||||||
CON Akaunti yangu
|
CON Akaunti yangu
|
||||||
1. Wasifu wangu
|
1. Wasifu wangu
|
||||||
@@ -47,7 +47,7 @@ sw:
|
|||||||
3. Angalia salio
|
3. Angalia salio
|
||||||
4. Angalia taarifa ya matumizi
|
4. Angalia taarifa ya matumizi
|
||||||
5. Badilisha nambari ya siri
|
5. Badilisha nambari ya siri
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
metadata_management: |-
|
metadata_management: |-
|
||||||
CON Wasifu wangu
|
CON Wasifu wangu
|
||||||
1. Weka jina
|
1. Weka jina
|
||||||
@@ -56,7 +56,7 @@ sw:
|
|||||||
4. Weka eneo
|
4. Weka eneo
|
||||||
5. Weka bidhaa
|
5. Weka bidhaa
|
||||||
6. Angalia wasifu wako
|
6. Angalia wasifu wako
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
display_user_metadata: |-
|
display_user_metadata: |-
|
||||||
CON Wasifu wako una maelezo yafuatayo:
|
CON Wasifu wako una maelezo yafuatayo:
|
||||||
Jina: %{full_name}
|
Jina: %{full_name}
|
||||||
@@ -64,98 +64,88 @@ sw:
|
|||||||
Umri: %{age}
|
Umri: %{age}
|
||||||
Eneo: %{location}
|
Eneo: %{location}
|
||||||
Unauza: %{products}
|
Unauza: %{products}
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
select_preferred_language: |-
|
select_preferred_language: |-
|
||||||
CON Chagua lugha
|
CON Chagua lugha
|
||||||
1. Kingereza
|
1. Kingereza
|
||||||
2. Kiswahili
|
2. Kiswahili
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
retry_pin_entry: |-
|
retry_pin_entry: |-
|
||||||
CON Nambari uliyoweka si sahihi, jaribu tena. Una majaribio %{remaining_attempts} yaliyobaki.
|
CON Nambari uliyoweka si sahihi, jaribu tena. Una majaribio %{remaining_attempts} yaliyobaki.
|
||||||
0. Back
|
0. Back
|
||||||
enter_current_pin:
|
enter_current_pin:
|
||||||
first: |-
|
first: |-
|
||||||
CON Weka nambari ya siri.
|
CON Weka nambari ya siri.
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
retry: |-
|
retry: |-
|
||||||
%{retry_pin_entry}
|
%{retry_pin_entry}
|
||||||
enter_new_pin: |-
|
enter_new_pin: |-
|
||||||
CON Weka nambari ya siri mpya
|
CON Weka nambari ya siri mpya
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
new_pin_confirmation: |-
|
new_pin_confirmation: |-
|
||||||
CON Weka nambari yako ya siri tena
|
CON Weka nambari yako ya siri tena
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
transaction_pin_authorization:
|
transaction_pin_authorization:
|
||||||
first: |-
|
first: |-
|
||||||
CON %{recipient_information} atapokea %{transaction_amount} %{token_symbol} kutoka kwa %{sender_information}.
|
CON %{recipient_information} atapokea %{transaction_amount} %{token_symbol} kutoka kwa %{sender_information}.
|
||||||
Tafadhali weka nambari yako ya siri kudhibitisha.
|
Tafadhali weka nambari yako ya siri kudhibitisha.
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
retry: |-
|
retry: |-
|
||||||
%{retry_pin_entry}
|
%{retry_pin_entry}
|
||||||
display_metadata_pin_authorization:
|
display_metadata_pin_authorization:
|
||||||
first: |-
|
first: |-
|
||||||
CON Tafadhali weka PIN yako
|
CON Tafadhali weka PIN yako
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
retry: |-
|
retry: |-
|
||||||
%{retry_pin_entry}
|
%{retry_pin_entry}
|
||||||
account_balances_pin_authorization:
|
account_balances_pin_authorization:
|
||||||
first: |-
|
first: |-
|
||||||
CON Tafadhali weka PIN yako kuona salio.
|
CON Tafadhali weka PIN yako kuona salio.
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
retry: |-
|
retry: |-
|
||||||
%{retry_pin_entry}
|
%{retry_pin_entry}
|
||||||
account_statement_pin_authorization:
|
account_statement_pin_authorization:
|
||||||
first: |-
|
first: |-
|
||||||
CON Tafadhali weka PIN yako kuona taarifa ya matumizi.
|
CON Tafadhali weka PIN yako kuona taarifa ya matumizi.
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
retry: |-
|
retry: |-
|
||||||
%{retry_pin_entry}
|
%{retry_pin_entry}
|
||||||
name_edit_pin_authorization:
|
name_edit_pin_authorization:
|
||||||
first: |-
|
first: |-
|
||||||
CON Tafadhali weka PIN yako
|
CON Tafadhali weka PIN yako
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
retry: |-
|
retry: |-
|
||||||
%{retry_pin_entry}
|
%{retry_pin_entry}
|
||||||
dob_edit_pin_authorization:
|
dob_edit_pin_authorization:
|
||||||
first: |-
|
first: |-
|
||||||
CON Tafadhali weka PIN yako
|
CON Tafadhali weka PIN yako
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
retry: |-
|
retry: |-
|
||||||
%{retry_pin_entry}
|
%{retry_pin_entry}
|
||||||
gender_edit_pin_authorization:
|
gender_edit_pin_authorization:
|
||||||
first: |-
|
first: |-
|
||||||
CON Tafadhali weka PIN yako
|
CON Tafadhali weka PIN yako
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
retry: |-
|
retry: |-
|
||||||
%{retry_pin_entry}
|
%{retry_pin_entry}
|
||||||
location_edit_pin_authorization:
|
location_edit_pin_authorization:
|
||||||
first: |-
|
first: |-
|
||||||
CON Tafadhali weka PIN yako
|
CON Tafadhali weka PIN yako
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
retry: |-
|
retry: |-
|
||||||
%{retry_pin_entry}
|
%{retry_pin_entry}
|
||||||
products_edit_pin_authorization:
|
products_edit_pin_authorization:
|
||||||
first: |-
|
first: |-
|
||||||
CON Tafadhali weka PIN yako
|
CON Tafadhali weka PIN yako
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
retry: |-
|
retry: |-
|
||||||
%{retry_pin_entry}
|
%{retry_pin_entry}
|
||||||
account_balances:
|
account_balances: |-
|
||||||
available_balance: |-
|
CON Salio zako ni zifuatazo:
|
||||||
CON Salio zako ni zifuatazo:
|
salio: %{available_balance} %{token_symbol}
|
||||||
salio: %{available_balance} %{token_symbol}
|
ushuru: %{tax} %{token_symbol}
|
||||||
0. Rudi
|
tuzo: %{bonus} %{token_symbol}
|
||||||
with_fees: |-
|
0. Nyuma
|
||||||
CON Salio zako ni zifuatazo:
|
|
||||||
salio: %{available_balance} %{token_symbol}
|
|
||||||
ushuru: %{tax} %{token_symbol}
|
|
||||||
0. Rudi
|
|
||||||
with_rewards: |-
|
|
||||||
CON Salio zako ni zifuatazo:
|
|
||||||
salio: %{available_balance} %{token_symbol}
|
|
||||||
ushuru: %{tax} %{token_symbol}
|
|
||||||
tuzo: %{bonus} %{token_symbol}
|
|
||||||
0. Rudi
|
|
||||||
first_transaction_set: |-
|
first_transaction_set: |-
|
||||||
CON %{first_transaction_set}
|
CON %{first_transaction_set}
|
||||||
1. Mbele
|
1. Mbele
|
||||||
@@ -163,54 +153,54 @@ sw:
|
|||||||
middle_transaction_set: |-
|
middle_transaction_set: |-
|
||||||
CON %{middle_transaction_set}
|
CON %{middle_transaction_set}
|
||||||
1. Mbele
|
1. Mbele
|
||||||
2. Rudi
|
2. Nyuma
|
||||||
00. Ondoka
|
00. Ondoka
|
||||||
last_transaction_set: |-
|
last_transaction_set: |-
|
||||||
CON %{last_transaction_set}
|
CON %{last_transaction_set}
|
||||||
2. Rudi
|
2. Nyuma
|
||||||
00. Ondoka
|
00. Ondoka
|
||||||
exit: |-
|
exit: |-
|
||||||
END Asante kwa kutumia huduma
|
END Asante kwa kutumia huduma.
|
||||||
exit_invalid_request: |-
|
exit_invalid_request: |-
|
||||||
END Chaguo si sahihi.
|
END Chaguo si sahihi.
|
||||||
exit_invalid_menu_option: |-
|
exit_invalid_menu_option: |-
|
||||||
CON Chaguo lako sio sahihi. Kwa usaidizi piga simu %{support_phone}
|
CON Chaguo lako sio sahihi. Kwa usaidizi piga simu %{support_phone}
|
||||||
00. Rudi
|
00. Nyuma
|
||||||
99. Ondoka
|
99. Ondoka
|
||||||
exit_invalid_input: |-
|
exit_invalid_input: |-
|
||||||
CON Chaguo lako halipatikani. Hakuna kilichochaguliwa
|
CON Chaguo lako halipatikani. Hakuna kilichochaguliwa.
|
||||||
00. Rudi
|
00. Nyuma
|
||||||
99. Ondoka
|
99. Ondoka
|
||||||
exit_pin_blocked: |-
|
exit_pin_blocked: |-
|
||||||
END PIN yako imefungwa. Kwa usaidizi tafadhali piga simu %{support_phone}
|
END PIN yako imefungwa. Kwa usaidizi tafadhali piga simu %{support_phone}.
|
||||||
exit_invalid_pin: |-
|
exit_invalid_pin: |-
|
||||||
END PIN uliyobonyeza sio sahihi. PIN lazima iwe na nambari nne. Kwa usaidizi piga simu %{support_phone}
|
END PIN uliyobonyeza sio sahihi. PIN lazima iwe na nambari nne. Kwa usaidizi piga simu %{support_phone}.
|
||||||
exit_invalid_new_pin: |-
|
exit_invalid_new_pin: |-
|
||||||
END PIN uliyobonyeza sio sahihi. PIN lazima iwe tofauti na pin yako ya sasa. Kwa usaidizi piga simu %{support_phone}
|
END PIN uliyobonyeza sio sahihi. PIN lazima iwe tofauti na pin yako ya sasa. Kwa usaidizi piga simu %{support_phone}.
|
||||||
exit_pin_mismatch: |-
|
exit_pin_mismatch: |-
|
||||||
END PIN mpya na udhibitisho wa pin mpya hazilingani. Tafadhali jaribu tena. Kwa usaidizi piga simu %{support_phone}
|
END PIN mpya na udhibitisho wa pin mpya hazilingani. Tafadhali jaribu tena. Kwa usaidizi piga simu %{support_phone}.
|
||||||
exit_invalid_recipient: |-
|
exit_invalid_recipient: |-
|
||||||
CON Mpokeaji wa nambari hapatikani au sio sahihi.
|
CON Mpokeaji wa nambari hapatikani au sio sahihi.
|
||||||
00. Jaribu tena
|
00. Jaribu tena
|
||||||
99. Ondoka
|
99. Ondoka
|
||||||
exit_successful_transaction: |-
|
exit_successful_transaction: |-
|
||||||
CON Ombi lako limetumwa. %{recipient_information} atapokea %{transaction_amount} %{token_symbol} kutoka kwa %{sender_information}
|
CON Ombi lako limetumwa. %{recipient_information} atapokea %{transaction_amount} %{token_symbol} kutoka kwa %{sender_information}.
|
||||||
00. Rudi
|
00. Nyuma
|
||||||
99. Ondoka
|
99. Ondoka
|
||||||
exit_insufficient_balance: |-
|
exit_insufficient_balance: |-
|
||||||
CON Malipo ya %{amount} %{token_symbol} kwa %{recipient_information} halijakamilika kwa sababu salio lako haitoshi
|
CON Malipo ya %{amount} %{token_symbol} kwa %{recipient_information} halijakamilika kwa sababu salio lako haitoshi.
|
||||||
Akaunti yako ya Sarafu ina salio ifuatayo: %{token_balance}
|
Akaunti yako ya Sarafu ina salio ifuatayo: %{token_balance}
|
||||||
00. Rudi
|
00. Nyuma
|
||||||
99. Ondoka
|
99. Ondoka
|
||||||
invalid_service_code: |-
|
invalid_service_code: |-
|
||||||
Bonyeza %{valid_service_code} kutumia mtandao wa Sarafu
|
Bonyeza %{valid_service_code} kutumia mtandao wa Sarafu
|
||||||
help: |-
|
help: |-
|
||||||
CON Kwa usaidizi piga simu %{support_phone}
|
CON Kwa usaidizi piga simu %{support_phone}
|
||||||
0. Rudi
|
0. Nyuma
|
||||||
9. Ondoka
|
9. Ondoka
|
||||||
complete: |-
|
complete: |-
|
||||||
CON Ombi lako limetumwa. Utapokea uthibitishaji wa SMS kwa muda mfupi.
|
CON Ombi lako limetumwa. Utapokea uthibitishaji wa SMS kwa muda mfupi.
|
||||||
00. Rudi
|
00. Nyuma
|
||||||
99. Ondoka
|
99. Ondoka
|
||||||
account_creation_prompt: |-
|
account_creation_prompt: |-
|
||||||
END Akaunti yako ya Sarafu inatayarishwa. Utapokea ujumbe wa SMS akaunti yako ikiwa tayari.
|
END Akaunti yako ya Sarafu inatayarishwa. Utapokea ujumbe wa SMS akaunti yako ikiwa tayari.
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
#.contract_migration_variables:
|
.contract_migration_variables:
|
||||||
# variables:
|
variables:
|
||||||
# APP_NAME: contract-migration
|
APP_NAME: contract-migration
|
||||||
# DOCKERFILE_PATH: docker/Dockerfile_ci
|
DOCKERFILE_PATH: docker/Dockerfile_ci
|
||||||
# CONTEXT: apps/$APP_NAME
|
CONTEXT: apps/$APP_NAME
|
||||||
#
|
|
||||||
#build-mr-contract-migration:
|
build-mr-contract-migration:
|
||||||
# extends:
|
extends:
|
||||||
# - .py_build_merge_request
|
- .py_build_merge_request
|
||||||
# - .contract_migration_variables
|
- .contract_migration_variables
|
||||||
# rules:
|
rules:
|
||||||
# - if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
# changes:
|
changes:
|
||||||
# - apps/contract-migration/**/*
|
- apps/contract-migration/**/*
|
||||||
# when: always
|
when: always
|
||||||
#
|
|
||||||
#build-push-contract-migration:
|
build-push-contract-migration:
|
||||||
# extends:
|
extends:
|
||||||
# - .py_build_push
|
- .py_build_push
|
||||||
# - .contract_migration_variables
|
- .contract_migration_variables
|
||||||
# rules:
|
rules:
|
||||||
# - if: $CI_COMMIT_BRANCH == "master"
|
- if: $CI_COMMIT_BRANCH == "master"
|
||||||
# changes:
|
changes:
|
||||||
# - apps/contract-migration/**/*
|
- apps/contract-migration/**/*
|
||||||
# when: always
|
when: always
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -a
|
|
||||||
|
|
||||||
if [ -z $DEV_DATA_DIR ]; then
|
|
||||||
export DEV_DATA_DIR=`mktemp -d`
|
|
||||||
else
|
|
||||||
mkdir -p $DEV_DATA_DIR
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z $DEV_CONFIG_RESET ]; then
|
|
||||||
if [ -f ${DEV_DATA_DIR}/env_reset ]; then
|
|
||||||
>&2 echo "importing existing configuration values from ${DEV_DATA_DIR}/env_reset"
|
|
||||||
. ${DEV_DATA_DIR}/env_reset
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Handle wallet
|
|
||||||
export WALLET_KEY_FILE=${WALLET_KEY_FILE:-`realpath ./keystore/UTC--2021-01-08T17-18-44.521011372Z--eb3907ecad74a0013c259d5874ae7f22dcbcc95c`}
|
|
||||||
if [ ! -f $WALLET_KEY_FILE ]; then
|
|
||||||
>&2 echo "wallet path '$WALLET_KEY_FILE' does not point to a file"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
export DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER=`eth-checksum $(cat $WALLET_KEY_FILE | jq -r .address)`
|
|
||||||
|
|
||||||
# Wallet dependent variable defaults
|
|
||||||
export DEV_ETH_ACCOUNT_RESERVE_MINTER=${DEV_ETH_ACCOUNT_RESERVE_MINTER:-$DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER}
|
|
||||||
export DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER=${DEV_ETH_ACCOUNT_RESERVE_MINTER:-$DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER}
|
|
||||||
export CIC_TRUST_ADDRESS=${CIC_TRUST_ADDRESS:-$DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER}
|
|
||||||
export CIC_DEFAULT_TOKEN_SYMBOL=$TOKEN_SYMBOL
|
|
||||||
export TOKEN_SINK_ADDRESS=${TOKEN_SINK_ADDRESS:-$DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER}
|
|
||||||
|
|
||||||
|
|
||||||
# Legacy variable defaults
|
|
||||||
|
|
||||||
|
|
||||||
# Migration variable processing
|
|
||||||
confini-dump --schema-dir ./config --prefix export > ${DEV_DATA_DIR}/env_reset
|
|
||||||
echo "export CIC_TRUST_ADDRESS=$CIC_TRUST_ADDRESS
|
|
||||||
export CIC_DEFAULT_TOKEN_SYMBOL=$CIC_DEFAULT_TOKEN_SYMBOL
|
|
||||||
export WALLET_KEY_FILE=$WALLET_KEY_FILE
|
|
||||||
" >> ${DEV_DATA_DIR}/env_reset
|
|
||||||
|
|
||||||
cat ${DEV_DATA_DIR}/env_reset
|
|
||||||
|
|
||||||
set +a
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
[dev]
|
|
||||||
eth_account_contract_deployer =
|
|
||||||
eth_account_reserve_minter =
|
|
||||||
eth_account_accounts_index_writer =
|
|
||||||
reserve_amount = 10000000000000000000000000000000000
|
|
||||||
faucet_amount = 0
|
|
||||||
gas_amount = 100000000000000000000000
|
|
||||||
token_amount = 100000000000000000000000
|
|
||||||
eth_gas_price =
|
|
||||||
data_dir =
|
|
||||||
pip_extra_index_url =
|
|
||||||
eth_provider_host =
|
|
||||||
eth_provider_port =
|
|
||||||
44
apps/contract-migration/docker/Dockerfile_ci
Normal file
44
apps/contract-migration/docker/Dockerfile_ci
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# syntax = docker/dockerfile:1.2
|
||||||
|
FROM registry.gitlab.com/grassrootseconomics/cic-base-images:python-3.8.6-dev-55da5f4e
|
||||||
|
|
||||||
|
WORKDIR /root
|
||||||
|
|
||||||
|
RUN touch /etc/apt/sources.list.d/ethereum.list
|
||||||
|
RUN echo 'deb http://ppa.launchpad.net/ethereum/ethereum/ubuntu bionic main' > /etc/apt/sources.list.d/ethereum.list
|
||||||
|
RUN echo 'deb-src http://ppa.launchpad.net/ethereum/ethereum/ubuntu bionic main' >> /etc/apt/sources.list.d/ethereum.list
|
||||||
|
RUN cat /etc/apt/sources.list.d/ethereum.list
|
||||||
|
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 2A518C819BE37D2C2031944D1C52189C923F6CA9
|
||||||
|
|
||||||
|
#RUN apt-get install solc
|
||||||
|
|
||||||
|
RUN mkdir -vp /usr/local/etc/cic
|
||||||
|
|
||||||
|
ENV CONFINI_DIR /usr/local/etc/cic/
|
||||||
|
|
||||||
|
|
||||||
|
COPY config_template/ /usr/local/etc/cic/
|
||||||
|
COPY requirements.txt .
|
||||||
|
COPY override_requirements.txt .
|
||||||
|
|
||||||
|
ARG pip_index_url=https://pypi.org/simple
|
||||||
|
ARG EXTRA_INDEX_URL="https://pip.grassrootseconomics.net:8433"
|
||||||
|
ARG EXTRA_PIP_ARGS=""
|
||||||
|
ARG GITLAB_PYTHON_REGISTRY="https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple"
|
||||||
|
ARG pip_trusted_host=pypi.org
|
||||||
|
RUN pip install --index-url https://pypi.org/simple \
|
||||||
|
pip install --index-url https://pypi.org/simple \
|
||||||
|
--pre \
|
||||||
|
--force-reinstall \
|
||||||
|
--trusted-host $pip_trusted_host \
|
||||||
|
--extra-index-url $GITLAB_PYTHON_REGISTRY --extra-index-url $EXTRA_INDEX_URL $EXTRA_PIP_ARGS \
|
||||||
|
-r requirements.txt
|
||||||
|
|
||||||
|
RUN pip install --index-url https://pypi.org/simple \
|
||||||
|
--force-reinstall \
|
||||||
|
--pre \
|
||||||
|
--trusted-host $pip_trusted_host \
|
||||||
|
--extra-index-url $GITLAB_PYTHON_REGISTRY --extra-index-url $EXTRA_INDEX_URL $EXTRA_PIP_ARGS \
|
||||||
|
-r override_requirements.txt
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN chmod +x *.sh
|
||||||
@@ -56,7 +56,6 @@ ETH_PROVIDER
|
|||||||
ETH_ABI_DIR
|
ETH_ABI_DIR
|
||||||
SIGNER_SOCKET_PATH
|
SIGNER_SOCKET_PATH
|
||||||
SIGNER_SECRET
|
SIGNER_SECRET
|
||||||
SIGNER_PROVIDER
|
|
||||||
CELERY_BROKER_URL
|
CELERY_BROKER_URL
|
||||||
CELERY_RESULT_URL
|
CELERY_RESULT_URL
|
||||||
META_PROVIDER
|
META_PROVIDER
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
cic-eth[tools]==0.12.4a8
|
cic-eth[tools]==0.12.4a4
|
||||||
chainlib-eth>=0.0.9a14,<0.1.0
|
chainlib-eth>=0.0.9a7,<0.1.0
|
||||||
eth-erc20>=0.1.2a3,<0.2.0
|
eth-erc20>=0.1.2a2,<0.2.0
|
||||||
erc20-demurrage-token>=0.0.5a2,<0.1.0
|
erc20-demurrage-token>=0.0.5a2,<0.1.0
|
||||||
eth-accounts-index>=0.1.2a2,<0.2.0
|
eth-accounts-index>=0.1.2a2,<0.2.0
|
||||||
eth-address-index>=0.2.3a4,<0.3.0
|
eth-address-index>=0.2.3a4,<0.3.0
|
||||||
@@ -8,5 +8,3 @@ cic-eth-registry>=0.6.1a2,<0.7.0
|
|||||||
erc20-transfer-authorization>=0.3.5a2,<0.4.0
|
erc20-transfer-authorization>=0.3.5a2,<0.4.0
|
||||||
erc20-faucet>=0.3.2a2,<0.4.0
|
erc20-faucet>=0.3.2a2,<0.4.0
|
||||||
sarafu-faucet>=0.0.7a2,<0.1.0
|
sarafu-faucet>=0.0.7a2,<0.1.0
|
||||||
confini>=0.4.2rc3,<1.0.0
|
|
||||||
crypto-dev-signer>=0.4.15a7,<=0.4.15
|
|
||||||
|
|||||||
@@ -2,122 +2,179 @@
|
|||||||
|
|
||||||
set -a
|
set -a
|
||||||
|
|
||||||
. ${DEV_DATA_DIR}/env_reset
|
default_token=giftable_erc20_token
|
||||||
|
TOKEN_SYMBOL=${CIC_DEFAULT_TOKEN_SYMBOL}
|
||||||
|
TOKEN_NAME=${TOKEN_NAME}
|
||||||
|
TOKEN_TYPE=${TOKEN_TYPE:-$default_token}
|
||||||
|
cat <<EOF
|
||||||
|
external token settings:
|
||||||
|
token_type: $TOKEN_TYPE
|
||||||
|
token_symbol: $TOKEN_SYMBOL
|
||||||
|
token_name: $TOKEN_NAME
|
||||||
|
token_decimals: $TOKEN_DECIMALS
|
||||||
|
token_demurrage: $TOKEN_DEMURRAGE_LEVEL
|
||||||
|
token_redistribution_period: $TOKEN_REDISTRIBUTION_PERIOD
|
||||||
|
token_supply_limit: $TOKEN_SUPPLY_LIMIT
|
||||||
|
EOF
|
||||||
|
|
||||||
WAIT_FOR_TIMEOUT=${WAIT_FOR_TIMEOUT:-60}
|
CHAIN_SPEC=${CHAIN_SPEC:-$CIC_CHAIN_SPEC}
|
||||||
|
RPC_HTTP_PROVIDER=${RPC_HTTP_PROVIDER:-$ETH_PROVIDER}
|
||||||
|
|
||||||
|
DEV_ETH_ACCOUNT_RESERVE_MINTER=${DEV_ETH_ACCOUNT_RESERVE_MINTER:-$DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER}
|
||||||
|
DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER=${DEV_ETH_ACCOUNT_RESERVE_MINTER:-$DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER}
|
||||||
|
DEV_RESERVE_AMOUNT=${DEV_ETH_RESERVE_AMOUNT:-""10000000000000000000000000000000000}
|
||||||
|
DEV_FAUCET_AMOUNT=${DEV_FAUCET_AMOUNT:-0}
|
||||||
|
DEV_ETH_KEYSTORE_FILE=${DEV_ETH_KEYSTORE_FILE:-`realpath ./keystore/UTC--2021-01-08T17-18-44.521011372Z--eb3907ecad74a0013c259d5874ae7f22dcbcc95c`}
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER=`eth-checksum $(cat $DEV_ETH_KEYSTORE_FILE | jq -r .address)`
|
||||||
|
|
||||||
if [ ! -z $DEV_ETH_GAS_PRICE ]; then
|
if [ ! -z $DEV_ETH_GAS_PRICE ]; then
|
||||||
gas_price_arg="--gas-price $DEV_ETH_GAS_PRICE"
|
gas_price_arg="--gas-price $DEV_ETH_GAS_PRICE"
|
||||||
fee_price_arg="--fee-price $DEV_ETH_GAS_PRICE"
|
fee_price_arg="--fee-price $DEV_ETH_GAS_PRICE"
|
||||||
|
>&2 echo using static gas price $DEV_ETH_GAS_PRICE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "environment:"
|
||||||
|
printenv
|
||||||
|
echo \n
|
||||||
|
|
||||||
|
echo "using wallet address '$DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER' from keystore file $DEV_ETH_KEYSTORE_FILE"
|
||||||
|
|
||||||
|
# This is a grassroots team convention for building the Bancor contracts using the bancor protocol repository truffle setup
|
||||||
|
# Running this in docker-internal dev container (built from Docker folder in this repo) will write a
|
||||||
|
# source-able env file to CIC_DATA_DIR. Services dependent on these contracts can mount this file OR
|
||||||
|
# define these parameters at runtime
|
||||||
|
# pushd /usr/src
|
||||||
|
|
||||||
|
if [ -z $CIC_DATA_DIR ]; then
|
||||||
|
CIC_DATA_DIR=`mktemp -d`
|
||||||
|
fi
|
||||||
|
>&2 echo using data dir $CIC_DATA_DIR
|
||||||
|
|
||||||
|
init_level_file=${CIC_DATA_DIR}/.init
|
||||||
|
if [ ! -f ${CIC_DATA_DIR}/.init ]; then
|
||||||
|
echo "Creating .init file..."
|
||||||
|
mkdir -p $CIC_DATA_DIR
|
||||||
|
touch $CIC_DATA_DIR/.init
|
||||||
|
# touch $init_level_file
|
||||||
|
fi
|
||||||
|
echo -n 1 > $init_level_file
|
||||||
|
|
||||||
|
# Abort on any error (including if wait-for-it fails).
|
||||||
|
|
||||||
# Wait for the backend to be up, if we know where it is.
|
# Wait for the backend to be up, if we know where it is.
|
||||||
if [ -z "${RPC_PROVIDER}" ]; then
|
if [[ -n "${ETH_PROVIDER}" ]]; then
|
||||||
echo "\$RPC_PROVIDER not set!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
unset CONFINI_DIR
|
export CONFINI_DIR=$_CONFINI_DIR
|
||||||
|
unset CONFINI_DIR
|
||||||
|
|
||||||
if [ ! -z "$DEV_USE_DOCKER_WAIT_SCRIPT" ]; then
|
if [ ! -z "$DEV_USE_DOCKER_WAIT_SCRIPT" ]; then
|
||||||
IFS=: read -a p <<< "$RPC_PROVIDER"
|
echo "waiting for ${ETH_PROVIDER}..."
|
||||||
read -i "/" rpc_provider_port <<< "${p[2]}"
|
./wait-for-it.sh "${ETH_PROVIDER_HOST}:${ETH_PROVIDER_PORT}"
|
||||||
rpc_provider_host=${p[1]:2}
|
|
||||||
echo "waiting for provider host $rpc_provider_host port $rpc_provider_port..."
|
|
||||||
./wait-for-it.sh "$rpc_provider_host:$rpc_provider_port" -t $WAIT_FOR_TIMEOUT
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$TOKEN_TYPE" == "giftable_erc20_token" ]; then
|
|
||||||
if [ -z "$TOKEN_SYMBOL" ]; then
|
|
||||||
>&2 echo token symbol not set, setting defaults for type $TOKEN_TYPE
|
|
||||||
TOKEN_SYMBOL="GFT"
|
|
||||||
TOKEN_NAME="Giftable Token"
|
|
||||||
elif [ -z "$TOKEN_NAME" ]; then
|
|
||||||
>&2 echo token name not set, setting same as symbol for type $TOKEN_TYPE
|
|
||||||
TOKEN_NAME=$TOKEN_SYMBOL
|
|
||||||
fi
|
fi
|
||||||
>&2 echo deploying default token $TOKEN_TYPE
|
|
||||||
echo giftable-token-deploy $fee_price_arg -p $RPC_PROVIDER -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -vv -s -ww --name "$TOKEN_NAME" --symbol $TOKEN_SYMBOL --decimals 6 -vv
|
if [ "$TOKEN_TYPE" == "$default_token" ]; then
|
||||||
DEV_RESERVE_ADDRESS=`giftable-token-deploy $fee_price_arg -p $RPC_PROVIDER -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -vv -s -ww --name "$TOKEN_NAME" --symbol $TOKEN_SYMBOL --decimals 6 -vv`
|
if [ -z "$TOKEN_SYMBOL" ]; then
|
||||||
elif [ "$TOKEN_TYPE" == "erc20_demurrage_token" ]; then
|
>&2 echo token symbol not set, setting defaults for type $TOKEN_TYPE
|
||||||
if [ -z "$TOKEN_SYMBOL" ]; then
|
TOKEN_SYMBOL="GFT"
|
||||||
>&2 echo token symbol not set, setting defaults for type $TOKEN_TYPE
|
TOKEN_NAME="Giftable Token"
|
||||||
TOKEN_SYMBOL="DET"
|
elif [ -z "$TOKEN_NAME" ]; then
|
||||||
TOKEN_NAME="Demurrage Token"
|
>&2 echo token name not set, setting same as symbol for type $TOKEN_TYPE
|
||||||
elif [ -z "$TOKEN_NAME" ]; then
|
TOKEN_NAME=$TOKEN_SYMBOL
|
||||||
>&2 echo token name not set, setting same as symbol for type $TOKEN_TYPE
|
|
||||||
TOKEN_NAME=$TOKEN_SYMBOL
|
|
||||||
fi
|
|
||||||
>&2 echo deploying token $TOKEN_TYPE
|
|
||||||
if [ -z $TOKEN_SINK_ADDRESS ]; then
|
|
||||||
if [ ! -z $TOKEN_REDISTRIBUTION_PERIOD ]; then
|
|
||||||
>&2 echo -e "\033[;93mtoken sink address not set, so redistribution will be BURNED\033[;39m"
|
|
||||||
fi
|
fi
|
||||||
|
>&2 echo deploying default token $TOKEN_TYPE
|
||||||
|
echo giftable-token-deploy $fee_price_arg -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -vv -s -ww --name "$TOKEN_NAME" --symbol $TOKEN_SYMBOL --decimals 6 -vv
|
||||||
|
DEV_RESERVE_ADDRESS=`giftable-token-deploy $fee_price_arg -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -vv -s -ww --name "$TOKEN_NAME" --symbol $TOKEN_SYMBOL --decimals 6 -vv`
|
||||||
|
elif [ "$TOKEN_TYPE" == "erc20_demurrage_token" ]; then
|
||||||
|
if [ -z "$TOKEN_SYMBOL" ]; then
|
||||||
|
>&2 echo token symbol not set, setting defaults for type $TOKEN_TYPE
|
||||||
|
TOKEN_SYMBOL="SARAFU"
|
||||||
|
TOKEN_NAME="Sarafu Token"
|
||||||
|
elif [ -z "$TOKEN_NAME" ]; then
|
||||||
|
>&2 echo token name not set, setting same as symbol for type $TOKEN_TYPE
|
||||||
|
TOKEN_NAME=$TOKEN_SYMBOL
|
||||||
|
fi
|
||||||
|
>&2 echo deploying token $TOKEN_TYPE
|
||||||
|
if [ -z $TOKEN_SINK_ADDRESS ]; then
|
||||||
|
if [ ! -z $TOKEN_REDISTRIBUTION_PERIOD ]; then
|
||||||
|
>&2 echo -e "\033[;93mtoken sink address not set, so redistribution will be BURNED\033[;39m"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
DEV_RESERVE_ADDRESS=`erc20-demurrage-token-deploy $fee_price_arg -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC --name "$TOKEN_NAME" --symbol $TOKEN_SYMBOL -vv -ww -s`
|
||||||
|
else
|
||||||
|
>&2 echo unknown token type $TOKEN_TYPE
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
DEV_RESERVE_ADDRESS=`erc20-demurrage-token-deploy $fee_price_arg -p $RPC_PROVIDER -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC --name "$TOKEN_NAME" --symbol $TOKEN_SYMBOL -vv -ww -s`
|
|
||||||
|
echo "giftable-token-gift $fee_price_arg -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -vv -w -e $DEV_RESERVE_ADDRESS $DEV_RESERVE_AMOUNT"
|
||||||
|
giftable-token-gift $fee_price_arg -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -u -vv -s -w -e $DEV_RESERVE_ADDRESS $DEV_RESERVE_AMOUNT
|
||||||
|
|
||||||
|
>&2 echo "deploy account index contract"
|
||||||
|
DEV_ACCOUNT_INDEX_ADDRESS=`eth-accounts-index-deploy $fee_price_arg -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -vv -s -u -w`
|
||||||
|
>&2 echo "add deployer address as account index writer"
|
||||||
|
eth-accounts-index-writer $fee_price_arg -s -u -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -e $DEV_ACCOUNT_INDEX_ADDRESS -ww -vv $debug $DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER
|
||||||
|
|
||||||
|
>&2 echo "deploy contract registry contract"
|
||||||
|
CIC_REGISTRY_ADDRESS=`eth-contract-registry-deploy $fee_price_arg -i $CIC_CHAIN_SPEC -y $DEV_ETH_KEYSTORE_FILE --identifier AccountRegistry --identifier TokenRegistry --identifier AddressDeclarator --identifier Faucet --identifier TransferAuthorization --identifier ContractRegistry -p $ETH_PROVIDER -vv -s -u -w`
|
||||||
|
eth-contract-registry-set $fee_price_arg -s -u -w -y $DEV_ETH_KEYSTORE_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv --identifier ContractRegistry $CIC_REGISTRY_ADDRESS
|
||||||
|
eth-contract-registry-set $fee_price_arg -s -u -w -y $DEV_ETH_KEYSTORE_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv --identifier AccountRegistry $DEV_ACCOUNT_INDEX_ADDRESS
|
||||||
|
|
||||||
|
# Deploy address declarator registry
|
||||||
|
>&2 echo "deploy address declarator contract"
|
||||||
|
declarator_description=0x546869732069732074686520434943206e6574776f726b000000000000000000
|
||||||
|
DEV_DECLARATOR_ADDRESS=`eth-address-declarator-deploy -s -u -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w -vv $declarator_description`
|
||||||
|
eth-contract-registry-set $fee_price_arg -s -u -w -y $DEV_ETH_KEYSTORE_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv --identifier AddressDeclarator $DEV_DECLARATOR_ADDRESS
|
||||||
|
|
||||||
|
# Deploy transfer authorization contact
|
||||||
|
>&2 echo "deploy transfer auth contract"
|
||||||
|
DEV_TRANSFER_AUTHORIZATION_ADDRESS=`erc20-transfer-auth-deploy $gas_price_arg -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w -vv`
|
||||||
|
eth-contract-registry-set $fee_price_arg -s -u -w -y $DEV_ETH_KEYSTORE_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv --identifier TransferAuthorization $DEV_TRANSFER_AUTHORIZATION_ADDRESS
|
||||||
|
|
||||||
|
# Deploy token index contract
|
||||||
|
>&2 echo "deploy token index contract"
|
||||||
|
DEV_TOKEN_INDEX_ADDRESS=`eth-token-index-deploy -s -u $fee_price_arg -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w -vv`
|
||||||
|
eth-contract-registry-set $fee_price_arg -s -u -w -y $DEV_ETH_KEYSTORE_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv --identifier TokenRegistry $DEV_TOKEN_INDEX_ADDRESS
|
||||||
|
>&2 echo "add reserve token to token index"
|
||||||
|
eth-token-index-add $fee_price_arg -s -u -w -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv -e $DEV_TOKEN_INDEX_ADDRESS $DEV_RESERVE_ADDRESS
|
||||||
|
|
||||||
|
# Sarafu faucet contract
|
||||||
|
>&2 echo "deploy token faucet contract"
|
||||||
|
DEV_FAUCET_ADDRESS=`sarafu-faucet-deploy $fee_price_arg -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w -vv --account-index-address $DEV_ACCOUNT_INDEX_ADDRESS $DEV_RESERVE_ADDRESS -s`
|
||||||
|
|
||||||
|
>&2 echo "set token faucet amount"
|
||||||
|
sarafu-faucet-set $fee_price_arg -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -e $DEV_FAUCET_ADDRESS -vv -s --fee-limit 100000 $DEV_FAUCET_AMOUNT
|
||||||
|
|
||||||
|
>&2 echo "register faucet in registry"
|
||||||
|
eth-contract-registry-set -s -u $fee_price_arg -w -y $DEV_ETH_KEYSTORE_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv --identifier Faucet $DEV_FAUCET_ADDRESS
|
||||||
|
|
||||||
|
>&2 echo "set faucet as token minter"
|
||||||
|
giftable-token-minter -s -u $fee_price_arg -w -y $DEV_ETH_KEYSTORE_FILE -e $DEV_RESERVE_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv $DEV_FAUCET_ADDRESS
|
||||||
|
|
||||||
|
export CONFINI_DIR=$_CONFINI_DIR
|
||||||
else
|
else
|
||||||
>&2 echo unknown token type $TOKEN_TYPE
|
echo "\$ETH_PROVIDER not set!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "giftable-token-gift $fee_price_arg -p $RPC_PROVIDER -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -vv -w -e $DEV_RESERVE_ADDRESS $DEV_RESERVE_AMOUNT"
|
mkdir -p $CIC_DATA_DIR
|
||||||
giftable-token-gift $fee_price_arg -p $RPC_PROVIDER -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -u -vv -s -w -e $DEV_RESERVE_ADDRESS $DEV_RESERVE_AMOUNT
|
>&2 echo using data dir $CIC_DATA_DIR for environment variable dump
|
||||||
|
|
||||||
>&2 echo "deploy account index contract"
|
# this is consumed in downstream services to set environment variables
|
||||||
DEV_ACCOUNT_INDEX_ADDRESS=`eth-accounts-index-deploy $fee_price_arg -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -y $WALLET_KEY_FILE -vv -s -u -w`
|
cat << EOF > $CIC_DATA_DIR/.env
|
||||||
>&2 echo "add deployer address as account index writer"
|
export CIC_REGISTRY_ADDRESS=$CIC_REGISTRY_ADDRESS
|
||||||
eth-accounts-index-writer $fee_price_arg -s -u -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -e $DEV_ACCOUNT_INDEX_ADDRESS -ww -vv $debug $DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER
|
export CIC_TRUST_ADDRESS=$DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER
|
||||||
|
export CIC_DECLARATOR_ADDRESS=$CIC_DECLARATOR_ADDRESS
|
||||||
|
EOF
|
||||||
|
|
||||||
>&2 echo "deploy contract registry contract"
|
cat ./envlist | bash from_env.sh > $CIC_DATA_DIR/.env_all
|
||||||
CIC_REGISTRY_ADDRESS=`eth-contract-registry-deploy $fee_price_arg -i $CIC_CHAIN_SPEC -y $WALLET_KEY_FILE --identifier AccountRegistry --identifier TokenRegistry --identifier AddressDeclarator --identifier Faucet --identifier TransferAuthorization --identifier ContractRegistry -p $RPC_PROVIDER -vv -s -u -w`
|
cat ./envlist
|
||||||
eth-contract-registry-set $fee_price_arg -s -u -w -y $WALLET_KEY_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -vv --identifier ContractRegistry $CIC_REGISTRY_ADDRESS
|
# popd
|
||||||
eth-contract-registry-set $fee_price_arg -s -u -w -y $WALLET_KEY_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -vv --identifier AccountRegistry $DEV_ACCOUNT_INDEX_ADDRESS
|
|
||||||
|
|
||||||
# Deploy address declarator registry
|
|
||||||
>&2 echo "deploy address declarator contract"
|
|
||||||
declarator_description=0x546869732069732074686520434943206e6574776f726b000000000000000000
|
|
||||||
DEV_DECLARATOR_ADDRESS=`eth-address-declarator-deploy -s -u -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -w -vv $declarator_description`
|
|
||||||
eth-contract-registry-set $fee_price_arg -s -u -w -y $WALLET_KEY_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -vv --identifier AddressDeclarator $DEV_DECLARATOR_ADDRESS
|
|
||||||
|
|
||||||
# Deploy transfer authorization contact
|
|
||||||
>&2 echo "deploy transfer auth contract"
|
|
||||||
DEV_TRANSFER_AUTHORIZATION_ADDRESS=`erc20-transfer-auth-deploy $gas_price_arg -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -w -vv`
|
|
||||||
eth-contract-registry-set $fee_price_arg -s -u -w -y $WALLET_KEY_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -vv --identifier TransferAuthorization $DEV_TRANSFER_AUTHORIZATION_ADDRESS
|
|
||||||
|
|
||||||
# Deploy token index contract
|
|
||||||
>&2 echo "deploy token index contract"
|
|
||||||
DEV_TOKEN_INDEX_ADDRESS=`eth-token-index-deploy -s -u $fee_price_arg -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -w -vv`
|
|
||||||
eth-contract-registry-set $fee_price_arg -s -u -w -y $WALLET_KEY_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -vv --identifier TokenRegistry $DEV_TOKEN_INDEX_ADDRESS
|
|
||||||
>&2 echo "add reserve token to token index"
|
|
||||||
eth-token-index-add $fee_price_arg -s -u -w -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -vv -e $DEV_TOKEN_INDEX_ADDRESS $DEV_RESERVE_ADDRESS
|
|
||||||
|
|
||||||
# Sarafu faucet contract
|
|
||||||
>&2 echo "deploy token faucet contract"
|
|
||||||
DEV_FAUCET_ADDRESS=`sarafu-faucet-deploy $fee_price_arg -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -w -vv --account-index-address $DEV_ACCOUNT_INDEX_ADDRESS $DEV_RESERVE_ADDRESS -s`
|
|
||||||
|
|
||||||
>&2 echo "set token faucet amount"
|
|
||||||
sarafu-faucet-set $fee_price_arg -w -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -e $DEV_FAUCET_ADDRESS -vv -s --fee-limit 100000 $DEV_FAUCET_AMOUNT
|
|
||||||
|
|
||||||
>&2 echo "register faucet in registry"
|
|
||||||
eth-contract-registry-set -s -u $fee_price_arg -w -y $WALLET_KEY_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -vv --identifier Faucet $DEV_FAUCET_ADDRESS
|
|
||||||
|
|
||||||
>&2 echo "set faucet as token minter"
|
|
||||||
giftable-token-minter -s -u $fee_price_arg -w -y $WALLET_KEY_FILE -e $DEV_RESERVE_ADDRESS -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -vv $DEV_FAUCET_ADDRESS
|
|
||||||
|
|
||||||
|
|
||||||
#echo "export CIC_DEFAULT_TOKEN_SYMBOL=$TOKEN_SYMBOL" >> ${DEV_DATA_DIR}/env_reset
|
|
||||||
export CIC_DEFAULT_TOKEN_SYMBOL=$TOKEN_SYMBOL
|
|
||||||
|
|
||||||
echo "Writing env_reset file ..."
|
|
||||||
|
|
||||||
echo "export CIC_REGISTRY_ADDRESS=$CIC_REGISTRY_ADDRESS
|
|
||||||
export CIC_DEFAULT_TOKEN_SYMBOL=$CIC_DEFAULT_TOKEN_SYMBOL
|
|
||||||
export TOKEN_NAME=$TOKEN_NAME
|
|
||||||
" >> "${DEV_DATA_DIR}"/env_reset
|
|
||||||
|
|
||||||
set +a
|
set +a
|
||||||
set +e
|
set +e
|
||||||
|
|
||||||
|
echo -n 2 > $init_level_file
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|||||||
@@ -1,13 +1,5 @@
|
|||||||
#! /bin/bash
|
#! /bin/bash
|
||||||
|
|
||||||
>&2 echo -e "\033[;96mRUNNING\033[;39m configurations"
|
|
||||||
./config.sh
|
|
||||||
if [ $? -ne "0" ]; then
|
|
||||||
>&2 echo -e "\033[;31mFAILED\033[;39m configurations"
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
>&2 echo -e "\033[;32mSUCCEEDED\033[;39m configurations"
|
|
||||||
|
|
||||||
if [[ $((RUN_MASK & 1)) -eq 1 ]]
|
if [[ $((RUN_MASK & 1)) -eq 1 ]]
|
||||||
then
|
then
|
||||||
>&2 echo -e "\033[;96mRUNNING\033[;39m RUN_MASK 1 - contract deployment"
|
>&2 echo -e "\033[;96mRUNNING\033[;39m RUN_MASK 1 - contract deployment"
|
||||||
|
|||||||
@@ -1,40 +1,68 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# defaults
|
# defaults
|
||||||
source ${DEV_DATA_DIR}/env_reset
|
#initlevel=`cat ${CIC_DATA_DIR}/.init`
|
||||||
cat ${DEV_DATA_DIR}/env_reset
|
#echo $inilevel
|
||||||
|
#if [ $initlevel -lt 2 ]; then
|
||||||
|
# >&2 echo "initlevel too low $initlevel"
|
||||||
|
# exit 1
|
||||||
|
#fi
|
||||||
|
source ${CIC_DATA_DIR}/.env
|
||||||
|
source ${CIC_DATA_DIR}/.env_all
|
||||||
|
DEV_PIP_EXTRA_INDEX_URL=${DEV_PIP_EXTRA_INDEX_URL:-https://pip.grassrootseconomics.net:8433}
|
||||||
|
DEV_DATABASE_NAME_CIC_ETH=${DEV_DATABASE_NAME_CIC_ETH:-"cic-eth"}
|
||||||
|
CIC_DATA_DIR=${CIC_DATA_DIR:-/tmp/cic}
|
||||||
|
ETH_PASSPHRASE=''
|
||||||
|
CIC_DEFAULT_TOKEN_SYMBOL=${CIC_DEFAULT_TOKEN_SYMBOL:-GFT}
|
||||||
|
TOKEN_SYMBOL=$CIC_DEFAULT_TOKEN_SYMBOL
|
||||||
|
|
||||||
|
CHAIN_SPEC=${CHAIN_SPEC:-$CIC_CHAIN_SPEC}
|
||||||
|
RPC_HTTP_PROVIDER=${RPC_HTTP_PROVIDER:-$ETH_PROVIDER}
|
||||||
|
|
||||||
# Debug flag
|
# Debug flag
|
||||||
|
DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER=0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C
|
||||||
|
keystore_file=./keystore/UTC--2021-01-08T17-18-44.521011372Z--eb3907ecad74a0013c259d5874ae7f22dcbcc95c
|
||||||
debug='-vv'
|
debug='-vv'
|
||||||
|
gas_amount=100000000000000000000000
|
||||||
|
token_amount=${gas_amount}
|
||||||
|
env_out_file=${CIC_DATA_DIR}/.env_seed
|
||||||
|
init_level_file=${CIC_DATA_DIR}/.init
|
||||||
empty_config_dir=$CONFINI_DIR/empty
|
empty_config_dir=$CONFINI_DIR/empty
|
||||||
|
truncate $env_out_file -s 0
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
set -a
|
set -a
|
||||||
|
|
||||||
|
#pip install --extra-index-url $DEV_PIP_EXTRA_INDEX_URL eth-address-index==0.1.1a7
|
||||||
|
|
||||||
|
export CONFINI_DIR=$_CONFINI_DIR
|
||||||
unset CONFINI_DIR
|
unset CONFINI_DIR
|
||||||
|
|
||||||
# get required addresses from registries
|
# get required addresses from registries
|
||||||
token_index_address=`eth-contract-registry-list -u -i $CHAIN_SPEC -p $RPC_PROVIDER -e $CIC_REGISTRY_ADDRESS -vv --raw TokenRegistry`
|
DEV_TOKEN_INDEX_ADDRESS=`eth-contract-registry-list -u -i $CHAIN_SPEC -p $ETH_PROVIDER -e $CIC_REGISTRY_ADDRESS -vv --raw TokenRegistry`
|
||||||
account_index_address=`eth-contract-registry-list -u -i $CHAIN_SPEC -p $RPC_PROVIDER -e $CIC_REGISTRY_ADDRESS -vv --raw AccountRegistry`
|
DEV_ACCOUNT_INDEX_ADDRESS=`eth-contract-registry-list -u -i $CHAIN_SPEC -p $ETH_PROVIDER -e $CIC_REGISTRY_ADDRESS -vv --raw AccountRegistry`
|
||||||
reserve_address=`eth-token-index-list -i $CHAIN_SPEC -u -p $RPC_PROVIDER -e $token_index_address -vv --raw $CIC_DEFAULT_TOKEN_SYMBOL`
|
DEV_RESERVE_ADDRESS=`eth-token-index-list -i $CHAIN_SPEC -u -p $ETH_PROVIDER -e $DEV_TOKEN_INDEX_ADDRESS -vv --raw $CIC_DEFAULT_TOKEN_SYMBOL`
|
||||||
|
cat <<EOF
|
||||||
>&2 echo "Token registry: $token_index_address"
|
Token registry: $DEV_TOKEN_INDEX_ADDRESS
|
||||||
>&2 echo "Account registry: $account_index_address"
|
Account reigstry: $DEV_ACCOUNT_INDEX_ADDRESS
|
||||||
>&2 echo "Reserve address: $reserve_address ($TOKEN_SYMBOL)"
|
Reserve address: $DEV_RESERVE_ADDRESS ($CIC_DEFAULT_TOKEN_SYMBOL)
|
||||||
|
EOF
|
||||||
|
|
||||||
>&2 echo "create account for gas gifter"
|
>&2 echo "create account for gas gifter"
|
||||||
old_gas_provider=$DEV_ETH_ACCOUNT_GAS_PROVIDER
|
old_gas_provider=$DEV_ETH_ACCOUNT_GAS_PROVIDER
|
||||||
#DEV_ETH_ACCOUNT_GAS_GIFTER=`CONFINI_DIR=$empty_config_dir cic-eth-create --redis-timeout 120 $debug --redis-host $REDIS_HOST --redis-host-callback=$REDIS_HOST --redis-port-callback=$REDIS_PORT --no-register`
|
DEV_ETH_ACCOUNT_GAS_GIFTER=`CONFINI_DIR=$empty_config_dir cic-eth-create --redis-timeout 120 $debug --redis-host $REDIS_HOST --redis-host-callback=$REDIS_HOST --redis-port-callback=$REDIS_PORT --no-register`
|
||||||
DEV_ETH_ACCOUNT_GAS_GIFTER=`cic-eth-create --redis-timeout 120 $debug --redis-host $REDIS_HOST --redis-host-callback=$REDIS_HOST --redis-port-callback=$REDIS_PORT --no-register`
|
echo DEV_ETH_ACCOUNT_GAS_GIFTER=$DEV_ETH_ACCOUNT_GAS_GIFTER >> $env_out_file
|
||||||
cic-eth-tag -i $CHAIN_SPEC GAS_GIFTER $DEV_ETH_ACCOUNT_GAS_GIFTER
|
cic-eth-tag -i $CHAIN_SPEC GAS_GIFTER $DEV_ETH_ACCOUNT_GAS_GIFTER
|
||||||
|
|
||||||
|
|
||||||
>&2 echo "create account for sarafu gifter"
|
>&2 echo "create account for sarafu gifter"
|
||||||
DEV_ETH_ACCOUNT_SARAFU_GIFTER=`CONFINI_DIR=$empty_config_dir cic-eth-create $debug --redis-host $REDIS_HOST --redis-host-callback=$REDIS_HOST --redis-port-callback=$REDIS_PORT --no-register`
|
DEV_ETH_ACCOUNT_SARAFU_GIFTER=`CONFINI_DIR=$empty_config_dir cic-eth-create $debug --redis-host $REDIS_HOST --redis-host-callback=$REDIS_HOST --redis-port-callback=$REDIS_PORT --no-register`
|
||||||
|
echo DEV_ETH_ACCOUNT_SARAFU_GIFTER=$DEV_ETH_ACCOUNT_SARAFU_GIFTER >> $env_out_file
|
||||||
cic-eth-tag -i $CHAIN_SPEC SARAFU_GIFTER $DEV_ETH_ACCOUNT_SARAFU_GIFTER
|
cic-eth-tag -i $CHAIN_SPEC SARAFU_GIFTER $DEV_ETH_ACCOUNT_SARAFU_GIFTER
|
||||||
|
|
||||||
>&2 echo "create account for approval escrow owner"
|
>&2 echo "create account for approval escrow owner"
|
||||||
DEV_ETH_ACCOUNT_TRANSFER_AUTHORIZATION_OWNER=`CONFINI_DIR=$empty_config_dir cic-eth-create $debug --redis-host $REDIS_HOST --redis-host-callback=$REDIS_HOST --redis-port-callback=$REDIS_PORT --no-register`
|
DEV_ETH_ACCOUNT_TRANSFER_AUTHORIZATION_OWNER=`CONFINI_DIR=$empty_config_dir cic-eth-create $debug --redis-host $REDIS_HOST --redis-host-callback=$REDIS_HOST --redis-port-callback=$REDIS_PORT --no-register`
|
||||||
|
echo DEV_ETH_ACCOUNT_TRANSFER_AUTHORIZATION_OWNER=$DEV_ETH_ACCOUNT_TRANSFER_AUTHORIZATION_OWNER >> $env_out_file
|
||||||
cic-eth-tag -i $CHAIN_SPEC TRANSFER_AUTHORIZATION_OWNER $DEV_ETH_ACCOUNT_TRANSFER_AUTHORIZATION_OWNER
|
cic-eth-tag -i $CHAIN_SPEC TRANSFER_AUTHORIZATION_OWNER $DEV_ETH_ACCOUNT_TRANSFER_AUTHORIZATION_OWNER
|
||||||
|
|
||||||
#>&2 echo "create account for faucet owner"
|
#>&2 echo "create account for faucet owner"
|
||||||
@@ -44,45 +72,50 @@ cic-eth-tag -i $CHAIN_SPEC TRANSFER_AUTHORIZATION_OWNER $DEV_ETH_ACCOUNT_TRANSFE
|
|||||||
|
|
||||||
>&2 echo "create account for accounts index writer"
|
>&2 echo "create account for accounts index writer"
|
||||||
DEV_ETH_ACCOUNT_ACCOUNT_REGISTRY_WRITER=`CONFINI_DIR=$empty_config_dir cic-eth-create $debug --redis-host $REDIS_HOST --redis-host-callback=$REDIS_HOST --redis-port-callback=$REDIS_PORT --no-register`
|
DEV_ETH_ACCOUNT_ACCOUNT_REGISTRY_WRITER=`CONFINI_DIR=$empty_config_dir cic-eth-create $debug --redis-host $REDIS_HOST --redis-host-callback=$REDIS_HOST --redis-port-callback=$REDIS_PORT --no-register`
|
||||||
|
echo DEV_ETH_ACCOUNT_ACCOUNT_REGISTRY_WRITER=$DEV_ETH_ACCOUNT_ACCOUNT_REGISTRY_WRITER >> $env_out_file
|
||||||
cic-eth-tag -i $CHAIN_SPEC ACCOUNT_REGISTRY_WRITER $DEV_ETH_ACCOUNT_ACCOUNT_REGISTRY_WRITER
|
cic-eth-tag -i $CHAIN_SPEC ACCOUNT_REGISTRY_WRITER $DEV_ETH_ACCOUNT_ACCOUNT_REGISTRY_WRITER
|
||||||
>&2 echo "add acccounts index writer account as writer on contract"
|
>&2 echo "add acccounts index writer account as writer on contract"
|
||||||
eth-accounts-index-writer -s -u -y $WALLET_KEY_FILE -i $CHAIN_SPEC -p $RPC_PROVIDER -e $account_index_address -ww $debug $DEV_ETH_ACCOUNT_ACCOUNT_REGISTRY_WRITER
|
eth-accounts-index-writer -s -u -y $keystore_file -i $CHAIN_SPEC -p $ETH_PROVIDER -e $DEV_ACCOUNT_INDEX_ADDRESS -ww $debug $DEV_ETH_ACCOUNT_ACCOUNT_REGISTRY_WRITER
|
||||||
|
|
||||||
# Transfer gas to custodial gas provider adddress
|
# Transfer gas to custodial gas provider adddress
|
||||||
_CONFINI_DIR=$CONFINI_DIR
|
_CONFINI_DIR=$CONFINI_DIR
|
||||||
unset CONFINI_DIR
|
unset CONFINI_DIR
|
||||||
>&2 echo gift gas to gas gifter
|
>&2 echo gift gas to gas gifter
|
||||||
>&2 eth-gas -s -u -y $WALLET_KEY_FILE -i $CHAIN_SPEC -p $RPC_PROVIDER -w $debug -a $DEV_ETH_ACCOUNT_GAS_GIFTER $DEV_GAS_AMOUNT
|
>&2 eth-gas -s -u -y $keystore_file -i $CHAIN_SPEC -p $ETH_PROVIDER -w $debug -a $DEV_ETH_ACCOUNT_GAS_GIFTER $gas_amount
|
||||||
|
|
||||||
>&2 echo gift gas to sarafu token owner
|
>&2 echo gift gas to sarafu token owner
|
||||||
>&2 eth-gas -s -u -y $WALLET_KEY_FILE -i $CHAIN_SPEC -p $RPC_PROVIDER -w $debug -a $DEV_ETH_ACCOUNT_SARAFU_GIFTER $DEV_GAS_AMOUNT
|
>&2 eth-gas -s -u -y $keystore_file -i $CHAIN_SPEC -p $ETH_PROVIDER -w $debug -a $DEV_ETH_ACCOUNT_SARAFU_GIFTER $gas_amount
|
||||||
|
|
||||||
>&2 echo gift gas to account index owner
|
>&2 echo gift gas to account index owner
|
||||||
>&2 eth-gas -s -u -y $WALLET_KEY_FILE -i $CHAIN_SPEC -p $RPC_PROVIDER -w $debug -a $DEV_ETH_ACCOUNT_ACCOUNT_REGISTRY_WRITER $DEV_GAS_AMOUNT
|
>&2 eth-gas -s -u -y $keystore_file -i $CHAIN_SPEC -p $ETH_PROVIDER -w $debug -a $DEV_ETH_ACCOUNT_ACCOUNT_REGISTRY_WRITER $gas_amount
|
||||||
|
|
||||||
|
|
||||||
# Send token to token creator
|
# Send token to token creator
|
||||||
>&2 echo "gift tokens to sarafu owner"
|
>&2 echo "gift tokens to sarafu owner"
|
||||||
echo "giftable-token-gift -s -u -y $WALLET_KEY_FILE -i $CHAIN_SPEC -p $RPC_PROVIDER -e $reserve_address -a $DEV_ETH_ACCOUNT_SARAFU_GIFTER -w $debug $DEV_TOKEN_AMOUNT"
|
echo "giftable-token-gift -s -u -y $keystore_file -i $CHAIN_SPEC -p $ETH_PROVIDER -e $DEV_RESERVE_ADDRESS -a $DEV_ETH_ACCOUNT_SARAFU_GIFTER -w $debug $token_amount"
|
||||||
>&2 giftable-token-gift -s -u -y $WALLET_KEY_FILE -i $CHAIN_SPEC -p $RPC_PROVIDER -e $reserve_address -a $DEV_ETH_ACCOUNT_SARAFU_GIFTER -w $debug $DEV_TOKEN_AMOUNT
|
>&2 giftable-token-gift -s -u -y $keystore_file -i $CHAIN_SPEC -p $ETH_PROVIDER -e $DEV_RESERVE_ADDRESS -a $DEV_ETH_ACCOUNT_SARAFU_GIFTER -w $debug $token_amount
|
||||||
|
|
||||||
# Send token to token gifter
|
# Send token to token gifter
|
||||||
>&2 echo "gift tokens to keystore address"
|
>&2 echo "gift tokens to keystore address"
|
||||||
>&2 giftable-token-gift -s -u -y $WALLET_KEY_FILE -i $CHAIN_SPEC -p $RPC_PROVIDER -e $reserve_address -a $DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER -w $debug $DEV_TOKEN_AMOUNT
|
>&2 giftable-token-gift -s -u -y $keystore_file -i $CHAIN_SPEC -p $ETH_PROVIDER -e $DEV_RESERVE_ADDRESS -a $DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER -w $debug $token_amount
|
||||||
|
|
||||||
>&2 echo "set sarafu token to reserve token (temporarily while bancor contracts are not connected)"
|
>&2 echo "set sarafu token to reserve token (temporarily while bancor contracts are not connected)"
|
||||||
|
echo DEV_ETH_SARAFU_TOKEN_ADDRESS=$DEV_ETH_RESERVE_ADDRESS >> $env_out_file
|
||||||
export DEV_ETH_SARAFU_TOKEN_ADDRESS=$DEV_ETH_RESERVE_ADDRESS
|
export DEV_ETH_SARAFU_TOKEN_ADDRESS=$DEV_ETH_RESERVE_ADDRESS
|
||||||
|
|
||||||
# Transfer tokens to gifter address
|
# Transfer tokens to gifter address
|
||||||
>&2 echo "transfer tokens to token gifter address"
|
>&2 echo "transfer tokens to token gifter address"
|
||||||
>&2 erc20-transfer -s -u -y $WALLET_KEY_FILE -i $CHAIN_SPEC -p $RPC_PROVIDER --fee-limit 100000 -e $reserve_address -w $debug -a $DEV_ETH_ACCOUNT_SARAFU_GIFTER ${DEV_TOKEN_AMOUNT:0:-1}
|
>&2 erc20-transfer -s -u -y $keystore_file -i $CHAIN_SPEC -p $ETH_PROVIDER --fee-limit 100000 -e $DEV_RESERVE_ADDRESS -w $debug -a $DEV_ETH_ACCOUNT_SARAFU_GIFTER ${token_amount:0:-1}
|
||||||
|
|
||||||
|
#echo -n 0 > $init_level_file
|
||||||
|
|
||||||
|
#CONFINI_DIR=$_CONFINI_DIR
|
||||||
# Remove the SEND (8), QUEUE (16) and INIT (2) locks (or'ed), set by default at migration
|
# Remove the SEND (8), QUEUE (16) and INIT (2) locks (or'ed), set by default at migration
|
||||||
cic-eth-ctl -i $CHAIN_SPEC unlock INIT
|
cic-eth-ctl -i $CHAIN_SPEC unlock INIT
|
||||||
cic-eth-ctl -i $CHAIN_SPEC unlock SEND
|
cic-eth-ctl -i $CHAIN_SPEC unlock SEND
|
||||||
cic-eth-ctl -i $CHAIN_SPEC unlock QUEUE
|
cic-eth-ctl -i $CHAIN_SPEC unlock QUEUE
|
||||||
|
|
||||||
#confini-dump --schema-module chainlib.eth.data.config --schema-module cic_eth.data.config --schema-dir ./config
|
export CONFINI_DIR=$_CONFINI_DIR
|
||||||
|
|
||||||
set +a
|
set +a
|
||||||
set +e
|
set +e
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
.cache
|
.cache
|
||||||
.dot
|
.dot
|
||||||
**/doc
|
**/doc
|
||||||
node_modules/
|
**/node_modules
|
||||||
**/venv
|
**/venv
|
||||||
**/.venv
|
**/.venv
|
||||||
|
|
||||||
|
|||||||
@@ -1,61 +1,64 @@
|
|||||||
|
# standard imports
|
||||||
import argparse
|
import argparse
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
# external imports
|
# external imports
|
||||||
import celery
|
import celery
|
||||||
|
import confini
|
||||||
|
import redis
|
||||||
from chainlib.chain import ChainSpec
|
from chainlib.chain import ChainSpec
|
||||||
from chainlib.eth.address import to_checksum_address
|
from chainlib.eth.address import to_checksum_address
|
||||||
from chainlib.eth.connection import EthHTTPConnection
|
from chainlib.eth.connection import EthHTTPConnection
|
||||||
from confini import Config
|
|
||||||
from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer
|
from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer
|
||||||
from crypto_dev_signer.keystore.dict import DictKeystore
|
from crypto_dev_signer.keystore.dict import DictKeystore
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from import_util import BalanceProcessor, get_celery_worker_status
|
|
||||||
from import_task import ImportTask, MetadataTask
|
from import_task import ImportTask, MetadataTask
|
||||||
|
from import_util import BalanceProcessor, get_celery_worker_status
|
||||||
|
|
||||||
default_config_dir = '/usr/local/etc/data-seeding/'
|
logging.basicConfig(level=logging.WARNING)
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
|
|
||||||
arg_parser = argparse.ArgumentParser(description='Daemon worker that handles data seeding tasks.')
|
config_dir = './config'
|
||||||
arg_parser.add_argument('-c', type=str, default=default_config_dir, help='config root to use.')
|
|
||||||
arg_parser.add_argument('--env-prefix',
|
|
||||||
default=os.environ.get('CONFINI_ENV_PREFIX'),
|
|
||||||
dest='env_prefix',
|
|
||||||
type=str,
|
|
||||||
help='environment prefix for variables to overwrite configuration.')
|
|
||||||
arg_parser.add_argument('--head', action='store_true', help='start at current block height (overrides --offset)')
|
|
||||||
arg_parser.add_argument('-i', '--chain-spec', type=str, dest='i', help='chain spec')
|
|
||||||
arg_parser.add_argument('--include-balances', dest='include_balances', help='include opening balance transactions',
|
|
||||||
action='store_true')
|
|
||||||
arg_parser.add_argument('--meta-host', dest='meta_host', type=str, help='metadata server host')
|
|
||||||
arg_parser.add_argument('--meta-port', dest='meta_port', type=int, help='metadata server host')
|
|
||||||
arg_parser.add_argument('-p', '--provider', dest='p', type=str, help='chain rpc provider address')
|
|
||||||
arg_parser.add_argument('-q', type=str, default='cic-import-ussd', help='celery queue to submit data seeding tasks to.')
|
|
||||||
arg_parser.add_argument('-r', '--registry-address', type=str, dest='r', help='CIC Registry address')
|
|
||||||
arg_parser.add_argument('--redis-db', dest='redis_db', type=int, help='redis db to use for task submission and callback')
|
|
||||||
arg_parser.add_argument('--redis-host', dest='redis_host', type=str, help='redis host to use for task submission')
|
|
||||||
arg_parser.add_argument('--redis-port', dest='redis_port', type=int, help='redis host to use for task submission')
|
|
||||||
arg_parser.add_argument('--token-symbol', default='GFT', type=str, dest='token_symbol',
|
|
||||||
help='Token symbol to use for transactions')
|
|
||||||
arg_parser.add_argument('-v', help='be verbose', action='store_true')
|
|
||||||
arg_parser.add_argument('-vv', help='be more verbose', action='store_true')
|
|
||||||
arg_parser.add_argument('-y', '--key-file', dest='y', type=str, help='Ethereum keystore file to use for signing')
|
|
||||||
arg_parser.add_argument('--offset', type=int, default=0, help='block offset to start syncer from')
|
|
||||||
arg_parser.add_argument('--old-chain-spec', type=str, dest='old_chain_spec', default='evm:oldchain:1',
|
|
||||||
help='chain spec')
|
|
||||||
arg_parser.add_argument('import_dir', default='out', type=str, help='user export directory')
|
|
||||||
args = arg_parser.parse_args()
|
|
||||||
|
|
||||||
if args.vv:
|
argparser = argparse.ArgumentParser(description='daemon that monitors transactions in new blocks')
|
||||||
logging.getLogger().setLevel(logging.DEBUG)
|
argparser.add_argument('-p', '--provider', dest='p', type=str, help='chain rpc provider address')
|
||||||
elif args.v:
|
argparser.add_argument('-y', '--key-file', dest='y', type=str, help='Ethereum keystore file to use for signing')
|
||||||
|
argparser.add_argument('-c', type=str, default=config_dir, help='config root to use')
|
||||||
|
argparser.add_argument('--old-chain-spec', type=str, dest='old_chain_spec', default='evm:oldchain:1', help='chain spec')
|
||||||
|
argparser.add_argument('-i', '--chain-spec', type=str, dest='i', help='chain spec')
|
||||||
|
argparser.add_argument('-r', '--registry-address', type=str, dest='r', help='CIC Registry address')
|
||||||
|
argparser.add_argument('--meta-host', dest='meta_host', type=str, help='metadata server host')
|
||||||
|
argparser.add_argument('--meta-port', dest='meta_port', type=int, help='metadata server host')
|
||||||
|
argparser.add_argument('--redis-host', dest='redis_host', type=str, help='redis host to use for task submission')
|
||||||
|
argparser.add_argument('--redis-port', dest='redis_port', type=int, help='redis host to use for task submission')
|
||||||
|
argparser.add_argument('--redis-db', dest='redis_db', type=int, help='redis db to use for task submission and callback')
|
||||||
|
argparser.add_argument('--token-symbol', default='GFT', type=str, dest='token_symbol',
|
||||||
|
help='Token symbol to use for transactions')
|
||||||
|
argparser.add_argument('--head', action='store_true', help='start at current block height (overrides --offset)')
|
||||||
|
argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str,
|
||||||
|
help='environment prefix for variables to overwrite configuration')
|
||||||
|
argparser.add_argument('-q', type=str, default='cic-import-ussd', help='celery queue to submit transaction tasks to')
|
||||||
|
argparser.add_argument('--offset', type=int, default=0, help='block offset to start syncer from')
|
||||||
|
argparser.add_argument('-v', help='be verbose', action='store_true')
|
||||||
|
argparser.add_argument('-vv', help='be more verbose', action='store_true')
|
||||||
|
argparser.add_argument('user_dir', default='out', type=str, help='user export directory')
|
||||||
|
args = argparser.parse_args(sys.argv[1:])
|
||||||
|
|
||||||
|
if args.v:
|
||||||
logging.getLogger().setLevel(logging.INFO)
|
logging.getLogger().setLevel(logging.INFO)
|
||||||
|
|
||||||
config = Config(args.c, args.env_prefix)
|
elif args.vv:
|
||||||
|
logging.getLogger().setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
config_dir = os.path.join(args.c)
|
||||||
|
os.makedirs(config_dir, 0o777, True)
|
||||||
|
config = confini.Config(config_dir, args.env_prefix)
|
||||||
config.process()
|
config.process()
|
||||||
|
|
||||||
|
# override args
|
||||||
args_override = {
|
args_override = {
|
||||||
'CIC_CHAIN_SPEC': getattr(args, 'i'),
|
'CIC_CHAIN_SPEC': getattr(args, 'i'),
|
||||||
'ETH_PROVIDER': getattr(args, 'p'),
|
'ETH_PROVIDER': getattr(args, 'p'),
|
||||||
@@ -70,76 +73,88 @@ args_override = {
|
|||||||
config.dict_override(args_override, 'cli flag')
|
config.dict_override(args_override, 'cli flag')
|
||||||
config.censor('PASSWORD', 'DATABASE')
|
config.censor('PASSWORD', 'DATABASE')
|
||||||
config.censor('PASSWORD', 'SSL')
|
config.censor('PASSWORD', 'SSL')
|
||||||
logg.debug(f'config loaded from {args.c}:\n{config}')
|
logg.debug('config loaded from {}:\n{}'.format(config_dir, config))
|
||||||
|
|
||||||
db_config = {
|
redis_host = config.get('REDIS_HOST')
|
||||||
'database': config.get('DATABASE_NAME'),
|
redis_port = config.get('REDIS_PORT')
|
||||||
'host': config.get('DATABASE_HOST'),
|
redis_db = config.get('REDIS_DB')
|
||||||
'port': config.get('DATABASE_PORT'),
|
r = redis.Redis(redis_host, redis_port, redis_db)
|
||||||
'user': config.get('DATABASE_USER'),
|
|
||||||
'password': config.get('DATABASE_PASSWORD')
|
|
||||||
}
|
|
||||||
ImportTask.db_config = db_config
|
|
||||||
|
|
||||||
|
# create celery apps
|
||||||
|
celery_app = celery.Celery(backend=config.get('CELERY_RESULT_URL'), broker=config.get('CELERY_BROKER_URL'))
|
||||||
|
status = get_celery_worker_status(celery_app=celery_app)
|
||||||
|
|
||||||
|
signer_address = None
|
||||||
keystore = DictKeystore()
|
keystore = DictKeystore()
|
||||||
os.path.isfile(args.y)
|
if args.y is not None:
|
||||||
logg.debug(f'loading keystore file {args.y}')
|
logg.debug('loading keystore file {}'.format(args.y))
|
||||||
signer_address = keystore.import_keystore_file(args.y)
|
signer_address = keystore.import_keystore_file(args.y)
|
||||||
logg.debug(f'now have key for signer address {signer_address}')
|
logg.debug('now have key for signer address {}'.format(signer_address))
|
||||||
|
|
||||||
|
# define signer
|
||||||
signer = EIP155Signer(keystore)
|
signer = EIP155Signer(keystore)
|
||||||
|
|
||||||
block_offset = -1 if args.head else args.offset
|
queue = args.q
|
||||||
|
|
||||||
chain_str = config.get('CIC_CHAIN_SPEC')
|
chain_str = config.get('CIC_CHAIN_SPEC')
|
||||||
|
block_offset = 0
|
||||||
|
if args.head:
|
||||||
|
block_offset = -1
|
||||||
|
else:
|
||||||
|
block_offset = args.offset
|
||||||
|
|
||||||
chain_spec = ChainSpec.from_chain_str(chain_str)
|
chain_spec = ChainSpec.from_chain_str(chain_str)
|
||||||
ImportTask.chain_spec = chain_spec
|
|
||||||
old_chain_spec_str = args.old_chain_spec
|
old_chain_spec_str = args.old_chain_spec
|
||||||
old_chain_spec = ChainSpec.from_chain_str(old_chain_spec_str)
|
old_chain_spec = ChainSpec.from_chain_str(old_chain_spec_str)
|
||||||
|
|
||||||
|
user_dir = args.user_dir # user_out_dir from import_users.py
|
||||||
|
|
||||||
|
token_symbol = args.token_symbol
|
||||||
|
|
||||||
MetadataTask.meta_host = config.get('META_HOST')
|
MetadataTask.meta_host = config.get('META_HOST')
|
||||||
MetadataTask.meta_port = config.get('META_PORT')
|
MetadataTask.meta_port = config.get('META_PORT')
|
||||||
|
ImportTask.chain_spec = chain_spec
|
||||||
txs_dir = os.path.join(args.import_dir, 'txs')
|
|
||||||
os.makedirs(txs_dir, exist_ok=True)
|
|
||||||
sys.stdout.write(f'created txs dir: {txs_dir}')
|
|
||||||
|
|
||||||
celery_app = celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL'))
|
|
||||||
get_celery_worker_status(celery_app)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
conn = EthHTTPConnection(config.get('ETH_PROVIDER'))
|
conn = EthHTTPConnection(config.get('ETH_PROVIDER'))
|
||||||
ImportTask.balance_processor = BalanceProcessor(conn,
|
|
||||||
chain_spec,
|
ImportTask.balance_processor = BalanceProcessor(conn, chain_spec, config.get('CIC_REGISTRY_ADDRESS'),
|
||||||
config.get('CIC_REGISTRY_ADDRESS'),
|
signer_address, signer)
|
||||||
signer_address,
|
ImportTask.balance_processor.init(token_symbol)
|
||||||
signer)
|
|
||||||
ImportTask.balance_processor.init(args.token_symbol)
|
# TODO get decimals from token
|
||||||
balances = {}
|
balances = {}
|
||||||
accuracy = 10 ** 6
|
f = open('{}/balances.csv'.format(user_dir, 'r'))
|
||||||
count = 0
|
remove_zeros = 10 ** 6
|
||||||
with open(f'{args.import_dir}/balances.csv', 'r') as balances_file:
|
i = 0
|
||||||
while True:
|
while True:
|
||||||
line = balances_file.readline()
|
l = f.readline()
|
||||||
if line is None:
|
if l is None:
|
||||||
break
|
break
|
||||||
balance_data = line.split(',')
|
r = l.split(',')
|
||||||
try:
|
try:
|
||||||
blockchain_address = to_checksum_address(balance_data[0])
|
address = to_checksum_address(r[0])
|
||||||
logg.info(
|
sys.stdout.write('loading balance {} {} {}'.format(i, address, r[1]).ljust(200) + "\r")
|
||||||
'loading balance: {} {} {}'.format(count, blockchain_address, balance_data[1].ljust(200) + "\r"))
|
except ValueError:
|
||||||
except ValueError:
|
break
|
||||||
break
|
balance = int(int(r[1].rstrip()) / remove_zeros)
|
||||||
balance = int(int(balance_data[1].rstrip()) / accuracy)
|
balances[address] = balance
|
||||||
balances[blockchain_address] = balance
|
i += 1
|
||||||
count += 1
|
|
||||||
|
f.close()
|
||||||
|
|
||||||
ImportTask.balances = balances
|
ImportTask.balances = balances
|
||||||
ImportTask.count = count
|
ImportTask.count = i
|
||||||
ImportTask.include_balances = args.include_balances is True
|
ImportTask.import_dir = user_dir
|
||||||
ImportTask.import_dir = args.import_dir
|
|
||||||
s_send_txs = celery.signature(
|
s = celery.signature(
|
||||||
'import_task.send_txs', [ImportTask.balance_processor.nonce_offset], queue=args.q)
|
'import_task.send_txs',
|
||||||
s_send_txs.apply_async()
|
[
|
||||||
|
MetadataTask.balance_processor.nonce_offset,
|
||||||
|
],
|
||||||
|
queue=queue,
|
||||||
|
)
|
||||||
|
s.apply_async()
|
||||||
|
|
||||||
argv = ['worker']
|
argv = ['worker']
|
||||||
if args.vv:
|
if args.vv:
|
||||||
@@ -150,7 +165,6 @@ def main():
|
|||||||
argv.append(args.q)
|
argv.append(args.q)
|
||||||
argv.append('-n')
|
argv.append('-n')
|
||||||
argv.append(args.q)
|
argv.append(args.q)
|
||||||
argv.append(f'--pidfile={args.q}.pid')
|
|
||||||
celery_app.worker_main(argv)
|
celery_app.worker_main(argv)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,63 +1,71 @@
|
|||||||
# standard imports
|
# standard import
|
||||||
import argparse
|
import argparse
|
||||||
import csv
|
import csv
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import psycopg2
|
|
||||||
|
|
||||||
# external imports
|
# third-party imports
|
||||||
from confini import Config
|
import celery
|
||||||
|
import confini
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
|
from import_util import get_celery_worker_status
|
||||||
|
|
||||||
|
|
||||||
default_config_dir = './config'
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
logging.basicConfig(level=logging.WARNING)
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
|
|
||||||
arg_parser = argparse.ArgumentParser(description='Pins import script.')
|
default_config_dir = './config'
|
||||||
arg_parser.add_argument('-c', type=str, default=default_config_dir, help='config root to use.')
|
|
||||||
|
arg_parser = argparse.ArgumentParser()
|
||||||
|
arg_parser.add_argument('-c', type=str, default=default_config_dir, help='config root to use')
|
||||||
arg_parser.add_argument('--env-prefix',
|
arg_parser.add_argument('--env-prefix',
|
||||||
default=os.environ.get('CONFINI_ENV_PREFIX'),
|
default=os.environ.get('CONFINI_ENV_PREFIX'),
|
||||||
dest='env_prefix',
|
dest='env_prefix',
|
||||||
type=str,
|
type=str,
|
||||||
help='environment prefix for variables to overwrite configuration.')
|
help='environment prefix for variables to overwrite configuration')
|
||||||
arg_parser.add_argument('import_dir', default='out', type=str, help='user export directory')
|
arg_parser.add_argument('-q', type=str, default='cic-import-ussd', help='celery queue to submit transaction tasks to')
|
||||||
arg_parser.add_argument('-v', help='be verbose', action='store_true')
|
arg_parser.add_argument('-v', help='be verbose', action='store_true')
|
||||||
arg_parser.add_argument('-vv', help='be more verbose', action='store_true')
|
arg_parser.add_argument('-vv', help='be more verbose', action='store_true')
|
||||||
|
arg_parser.add_argument('pins_dir', default='out', type=str, help='user export directory')
|
||||||
args = arg_parser.parse_args()
|
args = arg_parser.parse_args()
|
||||||
|
|
||||||
if args.vv:
|
# set log levels
|
||||||
logging.getLogger().setLevel(logging.DEBUG)
|
if args.v:
|
||||||
elif args.v:
|
logg.setLevel(logging.INFO)
|
||||||
logging.getLogger().setLevel(logging.INFO)
|
elif args.vv:
|
||||||
|
logg.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
config = Config(args.c, args.env_prefix)
|
# process configs
|
||||||
|
config_dir = args.c
|
||||||
|
config = confini.Config(config_dir, os.environ.get('CONFINI_ENV_PREFIX'))
|
||||||
config.process()
|
config.process()
|
||||||
config.censor('PASSWORD', 'DATABASE')
|
config.censor('PASSWORD', 'DATABASE')
|
||||||
logg.debug(f'config loaded from {args.c}:\n{config}')
|
logg.debug('config loaded from {}:\n{}'.format(args.c, config))
|
||||||
|
|
||||||
|
celery_app = celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL'))
|
||||||
|
status = get_celery_worker_status(celery_app=celery_app)
|
||||||
|
|
||||||
|
|
||||||
|
db_configs = {
|
||||||
|
'database': config.get('DATABASE_NAME'),
|
||||||
|
'host': config.get('DATABASE_HOST'),
|
||||||
|
'port': config.get('DATABASE_PORT'),
|
||||||
|
'user': config.get('DATABASE_USER'),
|
||||||
|
'password': config.get('DATABASE_PASSWORD')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
with open(f'{args.import_dir}/pins.csv') as pins_file:
|
with open(f'{args.pins_dir}/pins.csv') as pins_file:
|
||||||
phone_to_pins = [tuple(row) for row in csv.reader(pins_file)]
|
phone_to_pins = [tuple(row) for row in csv.reader(pins_file)]
|
||||||
|
|
||||||
db_conn = psycopg2.connect(
|
s_import_pins = celery.signature(
|
||||||
database=config.get('DATABASE_NAME'),
|
'import_task.set_pins',
|
||||||
host=config.get('DATABASE_HOST'),
|
(db_configs, phone_to_pins),
|
||||||
port=config.get('DATABASE_PORT'),
|
queue=args.q
|
||||||
user=config.get('DATABASE_USER'),
|
|
||||||
password=config.get('DATABASE_PASSWORD')
|
|
||||||
)
|
)
|
||||||
db_cursor = db_conn.cursor()
|
result = s_import_pins.apply_async()
|
||||||
sql = 'UPDATE account SET password_hash = %s WHERE phone_number = %s'
|
logg.debug(f'TASK: {result.id}, STATUS: {result.status}')
|
||||||
for element in phone_to_pins:
|
|
||||||
db_cursor.execute(sql, (element[1], element[0]))
|
|
||||||
logg.debug(f'Updating account: {element[0]} with: {element[1]}')
|
|
||||||
db_conn.commit()
|
|
||||||
db_cursor.close()
|
|
||||||
db_conn.close()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -1,37 +1,38 @@
|
|||||||
# standard imports
|
# standard imports
|
||||||
import csv
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import uuid
|
import urllib.error
|
||||||
from urllib import error, parse, request
|
import urllib.parse
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
# external imports
|
# external imports
|
||||||
import celery
|
import celery
|
||||||
import psycopg2
|
import psycopg2
|
||||||
from celery import Task
|
|
||||||
from chainlib.chain import ChainSpec
|
|
||||||
from chainlib.eth.address import to_checksum_address
|
from chainlib.eth.address import to_checksum_address
|
||||||
from chainlib.eth.tx import raw, unpack
|
from chainlib.eth.tx import (
|
||||||
from cic_types.models.person import Person, generate_metadata_pointer
|
unpack,
|
||||||
from hexathon import add_0x, strip_0x
|
raw,
|
||||||
|
)
|
||||||
|
from cic_types.models.person import Person
|
||||||
|
from cic_types.processor import generate_metadata_pointer
|
||||||
|
from hexathon import (
|
||||||
|
strip_0x,
|
||||||
|
add_0x,
|
||||||
|
)
|
||||||
|
|
||||||
# local imports
|
|
||||||
|
|
||||||
|
|
||||||
celery_app = celery.current_app
|
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
|
|
||||||
|
celery_app = celery.current_app
|
||||||
|
|
||||||
class ImportTask(Task):
|
|
||||||
|
class ImportTask(celery.Task):
|
||||||
balances = None
|
balances = None
|
||||||
balance_processor = None
|
import_dir = 'out'
|
||||||
chain_spec: ChainSpec = None
|
|
||||||
count = 0
|
count = 0
|
||||||
db_config: dict = None
|
chain_spec = None
|
||||||
import_dir = ''
|
balance_processor = None
|
||||||
include_balances = False
|
|
||||||
max_retries = None
|
max_retries = None
|
||||||
|
|
||||||
|
|
||||||
@@ -40,70 +41,121 @@ class MetadataTask(ImportTask):
|
|||||||
meta_port = None
|
meta_port = None
|
||||||
meta_path = ''
|
meta_path = ''
|
||||||
meta_ssl = False
|
meta_ssl = False
|
||||||
autoretry_for = (error.HTTPError, OSError,)
|
autoretry_for = (
|
||||||
|
urllib.error.HTTPError,
|
||||||
|
OSError,
|
||||||
|
)
|
||||||
retry_jitter = True
|
retry_jitter = True
|
||||||
retry_backoff = True
|
retry_backoff = True
|
||||||
retry_backoff_max = 60
|
retry_backoff_max = 60
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def meta_url(cls):
|
def meta_url(self):
|
||||||
scheme = 'http'
|
scheme = 'http'
|
||||||
if cls.meta_ssl:
|
if self.meta_ssl:
|
||||||
scheme += 's'
|
scheme += 's'
|
||||||
url = parse.urlparse(f'{scheme}://{cls.meta_host}:{cls.meta_port}/{cls.meta_path}')
|
url = urllib.parse.urlparse('{}://{}:{}/{}'.format(scheme, self.meta_host, self.meta_port, self.meta_path))
|
||||||
return parse.urlunparse(url)
|
return urllib.parse.urlunparse(url)
|
||||||
|
|
||||||
|
|
||||||
def old_address_from_phone(base_path: str, phone_number: str):
|
def old_address_from_phone(base_path, phone):
|
||||||
pid_x = generate_metadata_pointer(phone_number.encode('utf-8'), ':cic.phone')
|
pidx = generate_metadata_pointer(phone.encode('utf-8'), ':cic.phone')
|
||||||
phone_idx_path = os.path.join(f'{base_path}/phone/{pid_x[:2]}/{pid_x[2:4]}/{pid_x}')
|
phone_idx_path = os.path.join('{}/phone/{}/{}/{}'.format(
|
||||||
with open(phone_idx_path, 'r') as f:
|
base_path,
|
||||||
old_address = f.read()
|
pidx[:2],
|
||||||
|
pidx[2:4],
|
||||||
|
pidx,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
f = open(phone_idx_path, 'r')
|
||||||
|
old_address = f.read()
|
||||||
|
f.close()
|
||||||
|
|
||||||
return old_address
|
return old_address
|
||||||
|
|
||||||
|
|
||||||
@celery_app.task(bind=True, base=MetadataTask)
|
@celery_app.task(bind=True, base=MetadataTask)
|
||||||
def generate_person_metadata(self, blockchain_address: str, phone_number: str):
|
def resolve_phone(self, phone):
|
||||||
logg.debug(f'blockchain address: {blockchain_address}')
|
identifier = generate_metadata_pointer(phone.encode('utf-8'), ':cic.phone')
|
||||||
old_blockchain_address = old_address_from_phone(self.import_dir, phone_number)
|
url = urllib.parse.urljoin(self.meta_url(), identifier)
|
||||||
old_address_upper = strip_0x(old_blockchain_address).upper()
|
logg.debug('attempt getting phone pointer at {} for phone {}'.format(url, phone))
|
||||||
metadata_path = f'{self.import_dir}/old/{old_address_upper[:2]}/{old_address_upper[2:4]}/{old_address_upper}.json'
|
r = urllib.request.urlopen(url)
|
||||||
with open(metadata_path, 'r') as metadata_file:
|
address = json.load(r)
|
||||||
person_metadata = json.load(metadata_file)
|
address = address.replace('"', '')
|
||||||
person = Person.deserialize(person_metadata)
|
logg.debug('address {} for phone {}'.format(address, phone))
|
||||||
if not person.identities.get('evm'):
|
|
||||||
person.identities['evm'] = {}
|
return address
|
||||||
sub_chain_str = f'{self.chain_spec.common_name()}:{self.chain_spec.network_id()}'
|
|
||||||
person.identities['evm'][sub_chain_str] = [add_0x(blockchain_address)]
|
|
||||||
blockchain_address = strip_0x(blockchain_address)
|
|
||||||
file_path = os.path.join(
|
|
||||||
self.import_dir,
|
|
||||||
'new',
|
|
||||||
blockchain_address[:2].upper(),
|
|
||||||
blockchain_address[2:4].upper(),
|
|
||||||
blockchain_address.upper() + '.json'
|
|
||||||
)
|
|
||||||
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
|
||||||
serialized_person_metadata = person.serialize()
|
|
||||||
with open(file_path, 'w') as metadata_file:
|
|
||||||
metadata_file.write(json.dumps(serialized_person_metadata))
|
|
||||||
logg.debug(f'written person metadata for address: {blockchain_address}')
|
|
||||||
meta_filepath = os.path.join(
|
|
||||||
self.import_dir,
|
|
||||||
'meta',
|
|
||||||
'{}.json'.format(blockchain_address.upper()),
|
|
||||||
)
|
|
||||||
os.symlink(os.path.realpath(file_path), meta_filepath)
|
|
||||||
return blockchain_address
|
|
||||||
|
|
||||||
|
|
||||||
@celery_app.task(bind=True, base=MetadataTask)
|
@celery_app.task(bind=True, base=MetadataTask)
|
||||||
def generate_preferences_data(self, data: tuple):
|
def generate_metadata(self, address, phone):
|
||||||
blockchain_address: str = data[0]
|
old_address = old_address_from_phone(self.import_dir, phone)
|
||||||
preferences = data[1]
|
|
||||||
|
logg.debug('address {}'.format(address))
|
||||||
|
old_address_upper = strip_0x(old_address).upper()
|
||||||
|
metadata_path = '{}/old/{}/{}/{}.json'.format(
|
||||||
|
self.import_dir,
|
||||||
|
old_address_upper[:2],
|
||||||
|
old_address_upper[2:4],
|
||||||
|
old_address_upper,
|
||||||
|
)
|
||||||
|
|
||||||
|
f = open(metadata_path, 'r')
|
||||||
|
o = json.load(f)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
u = Person.deserialize(o)
|
||||||
|
|
||||||
|
if u.identities.get('evm') == None:
|
||||||
|
u.identities['evm'] = {}
|
||||||
|
sub_chain_str = '{}:{}'.format(self.chain_spec.common_name(), self.chain_spec.network_id())
|
||||||
|
u.identities['evm'][sub_chain_str] = [add_0x(address)]
|
||||||
|
|
||||||
|
new_address_clean = strip_0x(address)
|
||||||
|
filepath = os.path.join(
|
||||||
|
self.import_dir,
|
||||||
|
'new',
|
||||||
|
new_address_clean[:2].upper(),
|
||||||
|
new_address_clean[2:4].upper(),
|
||||||
|
new_address_clean.upper() + '.json',
|
||||||
|
)
|
||||||
|
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
||||||
|
|
||||||
|
o = u.serialize()
|
||||||
|
f = open(filepath, 'w')
|
||||||
|
f.write(json.dumps(o))
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
meta_key = generate_metadata_pointer(bytes.fromhex(new_address_clean), ':cic.person')
|
||||||
|
meta_filepath = os.path.join(
|
||||||
|
self.import_dir,
|
||||||
|
'meta',
|
||||||
|
'{}.json'.format(new_address_clean.upper()),
|
||||||
|
)
|
||||||
|
os.symlink(os.path.realpath(filepath), meta_filepath)
|
||||||
|
|
||||||
|
# write ussd data
|
||||||
|
ussd_data = {
|
||||||
|
'phone': phone,
|
||||||
|
'is_activated': 1,
|
||||||
|
'preferred_language': random.sample(['en', 'sw'], 1)[0],
|
||||||
|
'is_disabled': False
|
||||||
|
}
|
||||||
|
ussd_data_dir = os.path.join(self.import_dir, 'ussd')
|
||||||
|
ussd_data_file_path = os.path.join(ussd_data_dir, f'{old_address}.json')
|
||||||
|
f = open(ussd_data_file_path, 'w')
|
||||||
|
f.write(json.dumps(ussd_data))
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
# write preferences data
|
||||||
preferences_dir = os.path.join(self.import_dir, 'preferences')
|
preferences_dir = os.path.join(self.import_dir, 'preferences')
|
||||||
preferences_key = generate_metadata_pointer(bytes.fromhex(strip_0x(blockchain_address)), ':cic.preferences')
|
preferences_data = {
|
||||||
|
'preferred_language': ussd_data['preferred_language']
|
||||||
|
}
|
||||||
|
|
||||||
|
preferences_key = generate_metadata_pointer(bytes.fromhex(new_address_clean[2:]), ':cic.preferences')
|
||||||
preferences_filepath = os.path.join(preferences_dir, 'meta', preferences_key)
|
preferences_filepath = os.path.join(preferences_dir, 'meta', preferences_key)
|
||||||
|
|
||||||
filepath = os.path.join(
|
filepath = os.path.join(
|
||||||
preferences_dir,
|
preferences_dir,
|
||||||
'new',
|
'new',
|
||||||
@@ -112,95 +164,95 @@ def generate_preferences_data(self, data: tuple):
|
|||||||
preferences_key.upper() + '.json'
|
preferences_key.upper() + '.json'
|
||||||
)
|
)
|
||||||
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
||||||
with open(filepath, 'w') as preferences_file:
|
|
||||||
preferences_file.write(json.dumps(preferences))
|
f = open(filepath, 'w')
|
||||||
logg.debug(f'written preferences metadata: {preferences} for address: {blockchain_address}')
|
f.write(json.dumps(preferences_data))
|
||||||
|
f.close()
|
||||||
os.symlink(os.path.realpath(filepath), preferences_filepath)
|
os.symlink(os.path.realpath(filepath), preferences_filepath)
|
||||||
return blockchain_address
|
|
||||||
|
|
||||||
|
logg.debug('found metadata {} for phone {}'.format(o, phone))
|
||||||
|
|
||||||
@celery_app.task(bind=True, base=MetadataTask)
|
|
||||||
def generate_pins_data(self, blockchain_address: str, phone_number: str):
|
|
||||||
pins_file = f'{self.import_dir}/pins.csv'
|
|
||||||
file_op = 'a' if os.path.exists(pins_file) else 'w'
|
|
||||||
with open(pins_file, file_op) as pins_file:
|
|
||||||
password_hash = uuid.uuid4().hex
|
|
||||||
pins_file.write(f'{phone_number},{password_hash}\n')
|
|
||||||
logg.debug(f'written pin data for address: {blockchain_address}')
|
|
||||||
return blockchain_address
|
|
||||||
|
|
||||||
|
|
||||||
@celery_app.task(bind=True, base=MetadataTask)
|
|
||||||
def generate_ussd_data(self, blockchain_address: str, phone_number: str):
|
|
||||||
ussd_data_file = f'{self.import_dir}/ussd_data.csv'
|
|
||||||
file_op = 'a' if os.path.exists(ussd_data_file) else 'w'
|
|
||||||
preferred_language = random.sample(["en", "sw"], 1)[0]
|
|
||||||
preferences = {'preferred_language': preferred_language}
|
|
||||||
with open(ussd_data_file, file_op) as ussd_data_file:
|
|
||||||
ussd_data_file.write(f'{phone_number}, { 1}, {preferred_language}, {False}\n')
|
|
||||||
logg.debug(f'written ussd data for address: {blockchain_address}')
|
|
||||||
return blockchain_address, preferences
|
|
||||||
|
|
||||||
|
|
||||||
@celery_app.task(bind=True, base=MetadataTask)
|
|
||||||
def opening_balance_tx(self, blockchain_address: str, phone_number: str, serial: str):
|
|
||||||
old_blockchain_address = old_address_from_phone(self.import_dir, phone_number)
|
|
||||||
address = to_checksum_address(strip_0x(old_blockchain_address))
|
|
||||||
balance = self.balances[address]
|
|
||||||
logg.debug(f'found balance: {balance} for address: {address} phone: {phone_number}')
|
|
||||||
decimal_balance = self.balance_processor.get_decimal_amount(int(balance))
|
|
||||||
tx_hash_hex, o = self.balance_processor.get_rpc_tx(blockchain_address, decimal_balance, serial)
|
|
||||||
tx = unpack(bytes.fromhex(strip_0x(o)), self.chain_spec)
|
|
||||||
logg.debug(f'generated tx token value: {decimal_balance}: {blockchain_address} tx hash {tx_hash_hex}')
|
|
||||||
tx_path = os.path.join(self.import_dir, 'txs', strip_0x(tx_hash_hex))
|
|
||||||
with open(tx_path, 'w') as tx_file:
|
|
||||||
tx_file.write(strip_0x(o))
|
|
||||||
logg.debug(f'written tx with tx hash: {tx["hash"]} for address: {blockchain_address}')
|
|
||||||
tx_nonce_path = os.path.join(self.import_dir, 'txs', '.' + str(tx['nonce']))
|
|
||||||
os.symlink(os.path.realpath(tx_path), tx_nonce_path)
|
|
||||||
return tx['hash']
|
|
||||||
|
|
||||||
|
|
||||||
@celery_app.task(bind=True, base=MetadataTask)
|
|
||||||
def resolve_phone(self, phone_number: str):
|
|
||||||
identifier = generate_metadata_pointer(phone_number.encode('utf-8'), ':cic.phone')
|
|
||||||
url = parse.urljoin(self.meta_url(), identifier)
|
|
||||||
logg.debug(f'attempt getting phone pointer at: {url} for phone: {phone_number}')
|
|
||||||
r = request.urlopen(url)
|
|
||||||
address = json.load(r)
|
|
||||||
address = address.replace('"', '')
|
|
||||||
logg.debug(f'address: {address} for phone: {phone_number}')
|
|
||||||
return address
|
return address
|
||||||
|
|
||||||
|
|
||||||
@celery_app.task(autoretry_for=(FileNotFoundError,),
|
@celery_app.task(bind=True, base=MetadataTask)
|
||||||
bind=True,
|
def opening_balance_tx(self, address, phone, serial):
|
||||||
base=ImportTask,
|
old_address = old_address_from_phone(self.import_dir, phone)
|
||||||
max_retries=None,
|
|
||||||
|
k = to_checksum_address(strip_0x(old_address))
|
||||||
|
balance = self.balances[k]
|
||||||
|
logg.debug('found balance {} for address {} phone {}'.format(balance, old_address, phone))
|
||||||
|
|
||||||
|
decimal_balance = self.balance_processor.get_decimal_amount(int(balance))
|
||||||
|
|
||||||
|
(tx_hash_hex, o) = self.balance_processor.get_rpc_tx(address, decimal_balance, serial)
|
||||||
|
|
||||||
|
tx = unpack(bytes.fromhex(strip_0x(o)), self.chain_spec)
|
||||||
|
logg.debug('generated tx token value {} to {} tx hash {}'.format(decimal_balance, address, tx_hash_hex))
|
||||||
|
|
||||||
|
tx_path = os.path.join(
|
||||||
|
self.import_dir,
|
||||||
|
'txs',
|
||||||
|
strip_0x(tx_hash_hex),
|
||||||
|
)
|
||||||
|
|
||||||
|
f = open(tx_path, 'w')
|
||||||
|
f.write(strip_0x(o))
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
tx_nonce_path = os.path.join(
|
||||||
|
self.import_dir,
|
||||||
|
'txs',
|
||||||
|
'.' + str(tx['nonce']),
|
||||||
|
)
|
||||||
|
os.symlink(os.path.realpath(tx_path), tx_nonce_path)
|
||||||
|
|
||||||
|
return tx['hash']
|
||||||
|
|
||||||
|
|
||||||
|
@celery_app.task(bind=True, base=ImportTask, autoretry_for=(FileNotFoundError,), max_retries=None,
|
||||||
default_retry_delay=0.1)
|
default_retry_delay=0.1)
|
||||||
def send_txs(self, nonce):
|
def send_txs(self, nonce):
|
||||||
queue = self.request.delivery_info.get('routing_key')
|
|
||||||
if nonce == self.count + self.balance_processor.nonce_offset:
|
if nonce == self.count + self.balance_processor.nonce_offset:
|
||||||
logg.info(f'reached nonce {nonce} (offset {self.balance_processor.nonce_offset} + count {self.count}).')
|
logg.info('reached nonce {} (offset {} + count {}) exiting'.format(nonce, self.balance_processor.nonce_offset,
|
||||||
celery_app.control.broadcast('shutdown', destination=[f'celery@{queue}'])
|
self.count))
|
||||||
|
return
|
||||||
|
|
||||||
|
logg.debug('attempt to open symlink for nonce {}'.format(nonce))
|
||||||
|
tx_nonce_path = os.path.join(
|
||||||
|
self.import_dir,
|
||||||
|
'txs',
|
||||||
|
'.' + str(nonce),
|
||||||
|
)
|
||||||
|
f = open(tx_nonce_path, 'r')
|
||||||
|
tx_signed_raw_hex = f.read()
|
||||||
|
f.close()
|
||||||
|
|
||||||
logg.debug(f'attempt to open symlink for nonce {nonce}')
|
|
||||||
tx_nonce_path = os.path.join(self.import_dir, 'txs', '.' + str(nonce))
|
|
||||||
with open(tx_nonce_path, 'r') as tx_nonce_file:
|
|
||||||
tx_signed_raw_hex = tx_nonce_file.read()
|
|
||||||
os.unlink(tx_nonce_path)
|
os.unlink(tx_nonce_path)
|
||||||
|
|
||||||
o = raw(add_0x(tx_signed_raw_hex))
|
o = raw(add_0x(tx_signed_raw_hex))
|
||||||
if self.include_balances:
|
tx_hash_hex = self.balance_processor.conn.do(o)
|
||||||
tx_hash_hex = self.balance_processor.conn.do(o)
|
|
||||||
logg.info(f'sent nonce {nonce} tx hash {tx_hash_hex}')
|
logg.info('sent nonce {} tx hash {}'.format(nonce, tx_hash_hex)) # tx_signed_raw_hex))
|
||||||
|
|
||||||
nonce += 1
|
nonce += 1
|
||||||
s = celery.signature('import_task.send_txs', [nonce], queue=queue)
|
|
||||||
|
queue = self.request.delivery_info.get('routing_key')
|
||||||
|
s = celery.signature(
|
||||||
|
'import_task.send_txs',
|
||||||
|
[
|
||||||
|
nonce,
|
||||||
|
],
|
||||||
|
queue=queue,
|
||||||
|
)
|
||||||
s.apply_async()
|
s.apply_async()
|
||||||
|
|
||||||
return nonce
|
return nonce
|
||||||
|
|
||||||
|
|
||||||
@celery_app.task()
|
@celery_app.task
|
||||||
def set_pin_data(config: dict, phone_to_pins: list):
|
def set_pins(config: dict, phone_to_pins: list):
|
||||||
|
# define db connection
|
||||||
db_conn = psycopg2.connect(
|
db_conn = psycopg2.connect(
|
||||||
database=config.get('database'),
|
database=config.get('database'),
|
||||||
host=config.get('host'),
|
host=config.get('host'),
|
||||||
@@ -209,17 +261,24 @@ def set_pin_data(config: dict, phone_to_pins: list):
|
|||||||
password=config.get('password')
|
password=config.get('password')
|
||||||
)
|
)
|
||||||
db_cursor = db_conn.cursor()
|
db_cursor = db_conn.cursor()
|
||||||
sql = 'UPDATE account SET password_hash = %s WHERE phone_number = %s'
|
|
||||||
|
# update db
|
||||||
for element in phone_to_pins:
|
for element in phone_to_pins:
|
||||||
|
sql = 'UPDATE account SET password_hash = %s WHERE phone_number = %s'
|
||||||
db_cursor.execute(sql, (element[1], element[0]))
|
db_cursor.execute(sql, (element[1], element[0]))
|
||||||
logg.debug(f'Updating: {element[0]} with: {element[1]}')
|
logg.debug(f'Updating: {element[0]} with: {element[1]}')
|
||||||
|
|
||||||
|
# commit changes
|
||||||
db_conn.commit()
|
db_conn.commit()
|
||||||
|
|
||||||
|
# close connections
|
||||||
db_cursor.close()
|
db_cursor.close()
|
||||||
db_conn.close()
|
db_conn.close()
|
||||||
|
|
||||||
|
|
||||||
@celery_app.task
|
@celery_app.task
|
||||||
def set_ussd_data(config: dict, ussd_data: list):
|
def set_ussd_data(config: dict, ussd_data: dict):
|
||||||
|
# define db connection
|
||||||
db_conn = psycopg2.connect(
|
db_conn = psycopg2.connect(
|
||||||
database=config.get('database'),
|
database=config.get('database'),
|
||||||
host=config.get('host'),
|
host=config.get('host'),
|
||||||
@@ -228,12 +287,20 @@ def set_ussd_data(config: dict, ussd_data: list):
|
|||||||
password=config.get('password')
|
password=config.get('password')
|
||||||
)
|
)
|
||||||
db_cursor = db_conn.cursor()
|
db_cursor = db_conn.cursor()
|
||||||
|
|
||||||
|
# process ussd_data
|
||||||
|
account_status = 1
|
||||||
|
if ussd_data['is_activated'] == 1:
|
||||||
|
account_status = 2
|
||||||
|
preferred_language = ussd_data['preferred_language']
|
||||||
|
phone_number = ussd_data['phone']
|
||||||
|
|
||||||
sql = 'UPDATE account SET status = %s, preferred_language = %s WHERE phone_number = %s'
|
sql = 'UPDATE account SET status = %s, preferred_language = %s WHERE phone_number = %s'
|
||||||
for element in ussd_data:
|
db_cursor.execute(sql, (account_status, preferred_language, phone_number))
|
||||||
status = 2 if int(element[1]) == 1 else 1
|
|
||||||
preferred_language = element[2]
|
# commit changes
|
||||||
phone_number = element[0]
|
|
||||||
db_cursor.execute(sql, (status, preferred_language, phone_number))
|
|
||||||
db_conn.commit()
|
db_conn.commit()
|
||||||
|
|
||||||
|
# close connections
|
||||||
db_cursor.close()
|
db_cursor.close()
|
||||||
db_conn.close()
|
db_conn.close()
|
||||||
|
|||||||
@@ -3,61 +3,56 @@ import argparse
|
|||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import redis
|
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
import urllib.request
|
||||||
import uuid
|
import uuid
|
||||||
from urllib import request
|
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
|
|
||||||
# external imports
|
# external imports
|
||||||
import celery
|
import celery
|
||||||
|
import confini
|
||||||
import phonenumbers
|
import phonenumbers
|
||||||
|
import redis
|
||||||
|
from chainlib.chain import ChainSpec
|
||||||
from cic_types.models.person import Person
|
from cic_types.models.person import Person
|
||||||
from confini import Config
|
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from import_util import get_celery_worker_status
|
from import_util import get_celery_worker_status
|
||||||
|
|
||||||
default_config_dir = './config'
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
logging.basicConfig(level=logging.WARNING)
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
|
|
||||||
arg_parser = argparse.ArgumentParser(description='Daemon worker that handles data seeding tasks.')
|
default_config_dir = '/usr/local/etc/cic'
|
||||||
# batch size should be slightly below cumulative gas limit worth, eg 80000 gas txs with 8000000 limit is a bit less than 100 batch size
|
|
||||||
arg_parser.add_argument('--batch-size',
|
|
||||||
dest='batch_size',
|
|
||||||
default=100,
|
|
||||||
type=int,
|
|
||||||
help='burst size of sending transactions to node')
|
|
||||||
arg_parser.add_argument('--batch-delay', dest='batch_delay', default=3, type=int, help='seconds delay between batches')
|
|
||||||
arg_parser.add_argument('-c', type=str, default=default_config_dir, help='config root to use.')
|
|
||||||
arg_parser.add_argument('--env-prefix',
|
|
||||||
default=os.environ.get('CONFINI_ENV_PREFIX'),
|
|
||||||
dest='env_prefix',
|
|
||||||
type=str,
|
|
||||||
help='environment prefix for variables to overwrite configuration.')
|
|
||||||
arg_parser.add_argument('-i', '--chain-spec', type=str, dest='i', help='chain spec')
|
|
||||||
arg_parser.add_argument('-q', type=str, default='cic-import-ussd', help='celery queue to submit data seeding tasks to.')
|
|
||||||
arg_parser.add_argument('--redis-db', dest='redis_db', type=int, help='redis db to use for task submission and callback')
|
|
||||||
arg_parser.add_argument('--redis-host', dest='redis_host', type=str, help='redis host to use for task submission')
|
|
||||||
arg_parser.add_argument('--redis-port', dest='redis_port', type=int, help='redis host to use for task submission')
|
|
||||||
arg_parser.add_argument('--ussd-host', dest='ussd_host', type=str,
|
|
||||||
help="host to ussd app responsible for processing ussd requests.")
|
|
||||||
arg_parser.add_argument('--ussd-no-ssl', dest='ussd_no_ssl', help='do not use ssl (careful)', action='store_true')
|
|
||||||
arg_parser.add_argument('--ussd-port', dest='ussd_port', type=str,
|
|
||||||
help="port to ussd app responsible for processing ussd requests.")
|
|
||||||
arg_parser.add_argument('-v', help='be verbose', action='store_true')
|
|
||||||
arg_parser.add_argument('-vv', help='be more verbose', action='store_true')
|
|
||||||
arg_parser.add_argument('import_dir', default='out', type=str, help='user export directory')
|
|
||||||
args = arg_parser.parse_args()
|
|
||||||
|
|
||||||
if args.vv:
|
argparser = argparse.ArgumentParser()
|
||||||
logging.getLogger().setLevel(logging.DEBUG)
|
argparser.add_argument('-c', type=str, default=default_config_dir, help='config file')
|
||||||
elif args.v:
|
argparser.add_argument('-i', '--chain-spec', dest='i', type=str, help='Chain specification string')
|
||||||
logging.getLogger().setLevel(logging.INFO)
|
argparser.add_argument('--redis-host', dest='redis_host', type=str, help='redis host to use for task submission')
|
||||||
|
argparser.add_argument('--redis-port', dest='redis_port', type=int, help='redis host to use for task submission')
|
||||||
|
argparser.add_argument('--redis-db', dest='redis_db', type=int, help='redis db to use for task submission and callback')
|
||||||
|
argparser.add_argument('--batch-size', dest='batch_size', default=100, type=int,
|
||||||
|
help='burst size of sending transactions to node') # batch size should be slightly below cumulative gas limit worth, eg 80000 gas txs with 8000000 limit is a bit less than 100 batch size
|
||||||
|
argparser.add_argument('--batch-delay', dest='batch_delay', default=3, type=int, help='seconds delay between batches')
|
||||||
|
argparser.add_argument('--timeout', default=60.0, type=float, help='Callback timeout')
|
||||||
|
argparser.add_argument('--ussd-host', dest='ussd_host', type=str,
|
||||||
|
help="host to ussd app responsible for processing ussd requests.")
|
||||||
|
argparser.add_argument('--ussd-port', dest='ussd_port', type=str,
|
||||||
|
help="port to ussd app responsible for processing ussd requests.")
|
||||||
|
argparser.add_argument('--ussd-no-ssl', dest='ussd_no_ssl', help='do not use ssl (careful)', action='store_true')
|
||||||
|
argparser.add_argument('-q', type=str, default='cic-eth', help='Task queue')
|
||||||
|
argparser.add_argument('-v', action='store_true', help='Be verbose')
|
||||||
|
argparser.add_argument('-vv', action='store_true', help='Be more verbose')
|
||||||
|
argparser.add_argument('user_dir', type=str, help='path to users export dir tree')
|
||||||
|
args = argparser.parse_args()
|
||||||
|
|
||||||
config = Config(args.c, args.env_prefix)
|
if args.v:
|
||||||
|
logg.setLevel(logging.INFO)
|
||||||
|
elif args.vv:
|
||||||
|
logg.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
config_dir = args.c
|
||||||
|
config = confini.Config(config_dir, os.environ.get('CONFINI_ENV_PREFIX'))
|
||||||
config.process()
|
config.process()
|
||||||
args_override = {
|
args_override = {
|
||||||
'CIC_CHAIN_SPEC': getattr(args, 'i'),
|
'CIC_CHAIN_SPEC': getattr(args, 'i'),
|
||||||
@@ -65,29 +60,44 @@ args_override = {
|
|||||||
'REDIS_PORT': getattr(args, 'redis_port'),
|
'REDIS_PORT': getattr(args, 'redis_port'),
|
||||||
'REDIS_DB': getattr(args, 'redis_db'),
|
'REDIS_DB': getattr(args, 'redis_db'),
|
||||||
}
|
}
|
||||||
config.dict_override(args_override, 'cli flag')
|
config.dict_override(args_override, 'cli')
|
||||||
config.censor('PASSWORD', 'DATABASE')
|
logg.debug('config loaded from {}:\n{}'.format(args.c, config))
|
||||||
config.censor('PASSWORD', 'SSL')
|
|
||||||
logg.debug(f'config loaded from {args.c}:\n{config}')
|
|
||||||
|
|
||||||
old_account_dir = os.path.join(args.import_dir, 'old')
|
celery_app = celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL'))
|
||||||
os.stat(old_account_dir)
|
get_celery_worker_status(celery_app=celery_app)
|
||||||
logg.debug(f'created old system data dir: {old_account_dir}')
|
|
||||||
|
|
||||||
new_account_dir = os.path.join(args.import_dir, 'new')
|
redis_host = config.get('REDIS_HOST')
|
||||||
os.makedirs(new_account_dir, exist_ok=True)
|
redis_port = config.get('REDIS_PORT')
|
||||||
logg.debug(f'created new system data dir: {new_account_dir}')
|
redis_db = config.get('REDIS_DB')
|
||||||
|
r = redis.Redis(redis_host, redis_port, redis_db)
|
||||||
|
|
||||||
person_metadata_dir = os.path.join(args.import_dir, 'meta')
|
ps = r.pubsub()
|
||||||
os.makedirs(person_metadata_dir, exist_ok=True)
|
|
||||||
logg.debug(f'created person metadata dir: {person_metadata_dir}')
|
|
||||||
|
|
||||||
preferences_dir = os.path.join(args.import_dir, 'preferences')
|
user_new_dir = os.path.join(args.user_dir, 'new')
|
||||||
|
os.makedirs(user_new_dir, exist_ok=True)
|
||||||
|
|
||||||
|
ussd_data_dir = os.path.join(args.user_dir, 'ussd')
|
||||||
|
os.makedirs(ussd_data_dir, exist_ok=True)
|
||||||
|
|
||||||
|
preferences_dir = os.path.join(args.user_dir, 'preferences')
|
||||||
os.makedirs(os.path.join(preferences_dir, 'meta'), exist_ok=True)
|
os.makedirs(os.path.join(preferences_dir, 'meta'), exist_ok=True)
|
||||||
logg.debug(f'created preferences metadata dir: {preferences_dir}')
|
|
||||||
|
|
||||||
valid_service_codes = config.get('USSD_SERVICE_CODE').split(",")
|
meta_dir = os.path.join(args.user_dir, 'meta')
|
||||||
|
os.makedirs(meta_dir, exist_ok=True)
|
||||||
|
|
||||||
|
user_old_dir = os.path.join(args.user_dir, 'old')
|
||||||
|
os.stat(user_old_dir)
|
||||||
|
|
||||||
|
txs_dir = os.path.join(args.user_dir, 'txs')
|
||||||
|
os.makedirs(txs_dir, exist_ok=True)
|
||||||
|
|
||||||
|
chain_spec = ChainSpec.from_chain_str(config.get('CIC_CHAIN_SPEC'))
|
||||||
|
chain_str = str(chain_spec)
|
||||||
|
|
||||||
|
batch_size = args.batch_size
|
||||||
|
batch_delay = args.batch_delay
|
||||||
|
ussd_port = args.ussd_port
|
||||||
|
ussd_host = args.ussd_host
|
||||||
ussd_no_ssl = args.ussd_no_ssl
|
ussd_no_ssl = args.ussd_no_ssl
|
||||||
if ussd_no_ssl is True:
|
if ussd_no_ssl is True:
|
||||||
ussd_ssl = False
|
ussd_ssl = False
|
||||||
@@ -95,17 +105,7 @@ else:
|
|||||||
ussd_ssl = True
|
ussd_ssl = True
|
||||||
|
|
||||||
|
|
||||||
celery_app = celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL'))
|
def build_ussd_request(phone, host, port, service_code, username, password, ssl=False):
|
||||||
get_celery_worker_status(celery_app)
|
|
||||||
|
|
||||||
|
|
||||||
def build_ussd_request(host: str,
|
|
||||||
password: str,
|
|
||||||
phone_number: str,
|
|
||||||
port: str,
|
|
||||||
service_code: str,
|
|
||||||
username: str,
|
|
||||||
ssl: bool = False):
|
|
||||||
url = 'http'
|
url = 'http'
|
||||||
if ssl:
|
if ssl:
|
||||||
url += 's'
|
url += 's'
|
||||||
@@ -115,16 +115,16 @@ def build_ussd_request(host: str,
|
|||||||
url += '/?username={}&password={}'.format(username, password)
|
url += '/?username={}&password={}'.format(username, password)
|
||||||
|
|
||||||
logg.info('ussd service url {}'.format(url))
|
logg.info('ussd service url {}'.format(url))
|
||||||
logg.info('ussd phone {}'.format(phone_number))
|
logg.info('ussd phone {}'.format(phone))
|
||||||
|
|
||||||
session = uuid.uuid4().hex
|
session = uuid.uuid4().hex
|
||||||
data = {
|
data = {
|
||||||
'sessionId': session,
|
'sessionId': session,
|
||||||
'serviceCode': service_code,
|
'serviceCode': service_code,
|
||||||
'phoneNumber': phone_number,
|
'phoneNumber': phone,
|
||||||
'text': service_code,
|
'text': service_code,
|
||||||
}
|
}
|
||||||
req = request.Request(url)
|
req = urllib.request.Request(url)
|
||||||
req.method = 'POST'
|
req.method = 'POST'
|
||||||
data_str = urlencode(data)
|
data_str = urlencode(data)
|
||||||
data_bytes = data_str.encode('utf-8')
|
data_bytes = data_str.encode('utf-8')
|
||||||
@@ -134,77 +134,85 @@ def build_ussd_request(host: str,
|
|||||||
return req
|
return req
|
||||||
|
|
||||||
|
|
||||||
def e164_phone_number(phone_number: str):
|
def register_ussd(i, u):
|
||||||
phone_object = phonenumbers.parse(phone_number)
|
phone_object = phonenumbers.parse(u.tel)
|
||||||
return phonenumbers.format_number(phone_object, phonenumbers.PhoneNumberFormat.E164)
|
phone = phonenumbers.format_number(phone_object, phonenumbers.PhoneNumberFormat.E164)
|
||||||
|
logg.debug('tel {} {}'.format(u.tel, phone))
|
||||||
|
req = build_ussd_request(
|
||||||
def register_account(person: Person):
|
phone,
|
||||||
phone_number = e164_phone_number(person.tel)
|
ussd_host,
|
||||||
logg.debug(f'tel: {phone_number}')
|
ussd_port,
|
||||||
req = build_ussd_request(args.ussd_host,
|
config.get('APP_SERVICE_CODE'),
|
||||||
'',
|
'',
|
||||||
phone_number,
|
'',
|
||||||
args.ussd_port,
|
ussd_ssl
|
||||||
valid_service_codes[0],
|
)
|
||||||
'',
|
response = urllib.request.urlopen(req)
|
||||||
ussd_ssl)
|
|
||||||
response = request.urlopen(req)
|
|
||||||
response_data = response.read().decode('utf-8')
|
response_data = response.read().decode('utf-8')
|
||||||
logg.debug(f'ussd response: {response_data[4:]}')
|
state = response_data[:3]
|
||||||
|
out = response_data[4:]
|
||||||
|
logg.debug('ussd reponse: {}'.format(out))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
j = 0
|
j = 0
|
||||||
for x in os.walk(old_account_dir):
|
for x in os.walk(user_old_dir):
|
||||||
for y in x[2]:
|
for y in x[2]:
|
||||||
if y[len(y) - 5:] != '.json':
|
if y[len(y) - 5:] != '.json':
|
||||||
continue
|
continue
|
||||||
|
# handle json containing person object
|
||||||
|
filepath = os.path.join(x[0], y)
|
||||||
|
f = open(filepath, 'r')
|
||||||
|
try:
|
||||||
|
o = json.load(f)
|
||||||
|
except json.decoder.JSONDecodeError as e:
|
||||||
|
f.close()
|
||||||
|
logg.error('load error for {}: {}'.format(y, e))
|
||||||
|
continue
|
||||||
|
f.close()
|
||||||
|
u = Person.deserialize(o)
|
||||||
|
|
||||||
file_path = os.path.join(x[0], y)
|
register_ussd(i, u)
|
||||||
with open(file_path, 'r') as account_file:
|
|
||||||
try:
|
phone_object = phonenumbers.parse(u.tel)
|
||||||
account_data = json.load(account_file)
|
phone = phonenumbers.format_number(phone_object, phonenumbers.PhoneNumberFormat.E164)
|
||||||
except json.decoder.JSONDecodeError as e:
|
|
||||||
logg.error('load error for {}: {}'.format(y, e))
|
s_phone = celery.signature(
|
||||||
continue
|
'import_task.resolve_phone',
|
||||||
person = Person.deserialize(account_data)
|
[
|
||||||
register_account(person)
|
phone,
|
||||||
phone_number = e164_phone_number(person.tel)
|
],
|
||||||
s_resolve_phone = celery.signature(
|
queue='cic-import-ussd',
|
||||||
'import_task.resolve_phone', [phone_number], queue=args.q
|
|
||||||
)
|
)
|
||||||
|
|
||||||
s_person_metadata = celery.signature(
|
s_meta = celery.signature(
|
||||||
'import_task.generate_person_metadata', [phone_number], queue=args.q
|
'import_task.generate_metadata',
|
||||||
|
[
|
||||||
|
phone,
|
||||||
|
],
|
||||||
|
queue='cic-import-ussd',
|
||||||
)
|
)
|
||||||
|
|
||||||
s_ussd_data = celery.signature(
|
s_balance = celery.signature(
|
||||||
'import_task.generate_ussd_data', [phone_number], queue=args.q
|
'import_task.opening_balance_tx',
|
||||||
|
[
|
||||||
|
phone,
|
||||||
|
i,
|
||||||
|
],
|
||||||
|
queue='cic-import-ussd',
|
||||||
)
|
)
|
||||||
|
|
||||||
s_preferences_metadata = celery.signature(
|
s_meta.link(s_balance)
|
||||||
'import_task.generate_preferences_data', [], queue=args.q
|
s_phone.link(s_meta)
|
||||||
)
|
# block time plus a bit of time for ussd processing
|
||||||
|
s_phone.apply_async(countdown=7)
|
||||||
s_pins_data = celery.signature(
|
|
||||||
'import_task.generate_pins_data', [phone_number], queue=args.q
|
|
||||||
)
|
|
||||||
|
|
||||||
s_opening_balance = celery.signature(
|
|
||||||
'import_task.opening_balance_tx', [phone_number, i], queue=args.q
|
|
||||||
)
|
|
||||||
celery.chain(s_resolve_phone,
|
|
||||||
s_person_metadata,
|
|
||||||
s_ussd_data,
|
|
||||||
s_preferences_metadata,
|
|
||||||
s_pins_data,
|
|
||||||
s_opening_balance).apply_async(countdown=7)
|
|
||||||
|
|
||||||
i += 1
|
i += 1
|
||||||
sys.stdout.write('imported: {} {}'.format(i, person).ljust(200) + "\r\n")
|
sys.stdout.write('imported {} {}'.format(i, u).ljust(200) + "\r")
|
||||||
|
|
||||||
j += 1
|
j += 1
|
||||||
if j == args.batch_size:
|
if j == batch_size:
|
||||||
time.sleep(args.batch_delay)
|
time.sleep(batch_delay)
|
||||||
j = 0
|
j = 0
|
||||||
|
|||||||
@@ -1,67 +1,67 @@
|
|||||||
# standard imports
|
# standard imports
|
||||||
import argparse
|
import argparse
|
||||||
import csv
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import psycopg2
|
|
||||||
|
|
||||||
# external imports
|
# external imports
|
||||||
|
import celery
|
||||||
from confini import Config
|
from confini import Config
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
|
|
||||||
|
|
||||||
default_config_dir = './config'
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
logging.basicConfig(level=logging.WARNING)
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
|
|
||||||
arg_parser = argparse.ArgumentParser(description='Pins import script.')
|
default_config_dir = '/usr/local/etc/cic'
|
||||||
arg_parser.add_argument('-c', type=str, default=default_config_dir, help='config root to use.')
|
|
||||||
arg_parser.add_argument('--env-prefix',
|
|
||||||
default=os.environ.get('CONFINI_ENV_PREFIX'),
|
|
||||||
dest='env_prefix',
|
|
||||||
type=str,
|
|
||||||
help='environment prefix for variables to overwrite configuration.')
|
|
||||||
arg_parser.add_argument('import_dir', default='out', type=str, help='user export directory')
|
|
||||||
arg_parser.add_argument('-v', help='be verbose', action='store_true')
|
|
||||||
arg_parser.add_argument('-vv', help='be more verbose', action='store_true')
|
|
||||||
|
|
||||||
|
arg_parser = argparse.ArgumentParser()
|
||||||
|
arg_parser.add_argument('-c', type=str, default=default_config_dir, help='config file')
|
||||||
|
arg_parser.add_argument('-q', type=str, default='cic-import-ussd', help='Task queue')
|
||||||
|
arg_parser.add_argument('-v', action='store_true', help='Be verbose')
|
||||||
|
arg_parser.add_argument('-vv', action='store_true', help='Be more verbose')
|
||||||
|
arg_parser.add_argument('user_dir', type=str, help='path to users export dir tree')
|
||||||
args = arg_parser.parse_args()
|
args = arg_parser.parse_args()
|
||||||
|
|
||||||
if args.vv:
|
if args.v:
|
||||||
logging.getLogger().setLevel(logging.DEBUG)
|
logg.setLevel(logging.INFO)
|
||||||
elif args.v:
|
elif args.vv:
|
||||||
logging.getLogger().setLevel(logging.INFO)
|
logg.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
config = Config(args.c, args.env_prefix)
|
config_dir = args.c
|
||||||
|
config = Config(config_dir, os.environ.get('CONFINI_ENV_PREFIX'))
|
||||||
config.process()
|
config.process()
|
||||||
config.censor('PASSWORD', 'DATABASE')
|
logg.debug('config loaded from {}:\n{}'.format(args.c, config))
|
||||||
logg.debug(f'config loaded from {args.c}:\n{config}')
|
|
||||||
|
|
||||||
|
ussd_data_dir = os.path.join(args.user_dir, 'ussd')
|
||||||
|
|
||||||
def main():
|
db_configs = {
|
||||||
with open(f'{args.import_dir}/ussd_data.csv') as ussd_data_file:
|
'database': config.get('DATABASE_NAME'),
|
||||||
ussd_data = [tuple(row) for row in csv.reader(ussd_data_file)]
|
'host': config.get('DATABASE_HOST'),
|
||||||
|
'port': config.get('DATABASE_PORT'),
|
||||||
db_conn = psycopg2.connect(
|
'user': config.get('DATABASE_USER'),
|
||||||
database=config.get('DATABASE_NAME'),
|
'password': config.get('DATABASE_PASSWORD')
|
||||||
host=config.get('DATABASE_HOST'),
|
}
|
||||||
port=config.get('DATABASE_PORT'),
|
celery_app = celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL'))
|
||||||
user=config.get('DATABASE_USER'),
|
|
||||||
password=config.get('DATABASE_PASSWORD')
|
|
||||||
)
|
|
||||||
db_cursor = db_conn.cursor()
|
|
||||||
sql = 'UPDATE account SET status = %s, preferred_language = %s WHERE phone_number = %s'
|
|
||||||
for element in ussd_data:
|
|
||||||
status = 2 if int(element[1]) == 1 else 1
|
|
||||||
preferred_language = element[2]
|
|
||||||
phone_number = element[0]
|
|
||||||
db_cursor.execute(sql, (status, preferred_language, phone_number))
|
|
||||||
logg.debug(f'Updating account:{phone_number} with: preferred language: {preferred_language} status: {status}.')
|
|
||||||
db_conn.commit()
|
|
||||||
db_cursor.close()
|
|
||||||
db_conn.close()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
for x in os.walk(ussd_data_dir):
|
||||||
|
for y in x[2]:
|
||||||
|
|
||||||
|
if y[len(y) - 5:] == '.json':
|
||||||
|
filepath = os.path.join(x[0], y)
|
||||||
|
f = open(filepath, 'r')
|
||||||
|
try:
|
||||||
|
ussd_data = json.load(f)
|
||||||
|
logg.debug(f'LOADING USSD DATA: {ussd_data}')
|
||||||
|
except json.decoder.JSONDecodeError as e:
|
||||||
|
f.close()
|
||||||
|
logg.error('load error for {}: {}'.format(y, e))
|
||||||
|
continue
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
s_set_ussd_data = celery.signature(
|
||||||
|
'import_task.set_ussd_data',
|
||||||
|
[db_configs, ussd_data]
|
||||||
|
)
|
||||||
|
s_set_ussd_data.apply_async(queue='cic-import-ussd')
|
||||||
|
|||||||
@@ -1,4 +1,27 @@
|
|||||||
[app]
|
[app]
|
||||||
allowed_ip=0.0.0.0/0
|
ALLOWED_IP=0.0.0.0/0
|
||||||
max_body_length=1024
|
LOCALE_FALLBACK=en
|
||||||
password_pepper=
|
LOCALE_PATH=/usr/src/cic-ussd/var/lib/locale/
|
||||||
|
MAX_BODY_LENGTH=1024
|
||||||
|
PASSWORD_PEPPER=QYbzKff6NhiQzY3ygl2BkiKOpER8RE/Upqs/5aZWW+I=
|
||||||
|
SERVICE_CODE=*483*46#
|
||||||
|
|
||||||
|
[phone_number]
|
||||||
|
REGION=KE
|
||||||
|
|
||||||
|
[ussd]
|
||||||
|
MENU_FILE=/usr/src/data/ussd_menu.json
|
||||||
|
user =
|
||||||
|
pass =
|
||||||
|
|
||||||
|
[statemachine]
|
||||||
|
STATES=/usr/src/cic-ussd/states/
|
||||||
|
TRANSITIONS=/usr/src/cic-ussd/transitions/
|
||||||
|
|
||||||
|
[client]
|
||||||
|
host =
|
||||||
|
port =
|
||||||
|
ssl =
|
||||||
|
|
||||||
|
[keystore]
|
||||||
|
file_path = keystore/UTC--2021-01-08T17-18-44.521011372Z--eb3907ecad74a0013c259d5874ae7f22dcbcc95c
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
[cic]
|
[cic]
|
||||||
registry_address =
|
registry_address = 0x32E860c2A0645d1B7B005273696905F5D6DC5D05
|
||||||
token_index_address =
|
token_index_address =
|
||||||
accounts_index_address =
|
accounts_index_address =
|
||||||
declarator_address =
|
declarator_address =
|
||||||
approval_escrow_address =
|
approval_escrow_address =
|
||||||
chain_spec =
|
chain_spec = evm:bloxberg:8996
|
||||||
tx_retry_delay =
|
tx_retry_delay =
|
||||||
trust_address =
|
trust_address = 0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C
|
||||||
user_ussd_svc_service_port =
|
user_ussd_svc_service_port =
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
[database]
|
[database]
|
||||||
name=cic_ussd
|
NAME=sempo
|
||||||
user=postgres
|
USER=postgres
|
||||||
password=
|
PASSWORD=
|
||||||
host=localhost
|
HOST=localhost
|
||||||
port=5432
|
PORT=5432
|
||||||
engine=postgresql
|
ENGINE=postgresql
|
||||||
driver=psycopg2
|
DRIVER=psycopg2
|
||||||
debug=0
|
DEBUG=0
|
||||||
pool_size=1
|
POOL_SIZE=1
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
[ussd]
|
|
||||||
menu_file=data/ussd_menu.json
|
|
||||||
service_code=*483*46#,*483*061#,*384*96#
|
|
||||||
user =
|
|
||||||
pass =
|
|
||||||
91
apps/data-seeding/create_import_pins.py
Normal file
91
apps/data-seeding/create_import_pins.py
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
# standard imports
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
# third-party imports
|
||||||
|
import bcrypt
|
||||||
|
import celery
|
||||||
|
import confini
|
||||||
|
import phonenumbers
|
||||||
|
import random
|
||||||
|
from cic_types.models.person import Person
|
||||||
|
from cryptography.fernet import Fernet
|
||||||
|
|
||||||
|
# local imports
|
||||||
|
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.WARNING)
|
||||||
|
logg = logging.getLogger()
|
||||||
|
|
||||||
|
script_dir = os.path.realpath(os.path.dirname(__file__))
|
||||||
|
default_config_dir = os.environ.get('CONFINI_DIR', os.path.join(script_dir, 'config'))
|
||||||
|
|
||||||
|
arg_parser = argparse.ArgumentParser()
|
||||||
|
arg_parser.add_argument('-c', type=str, default=default_config_dir, help='Config dir')
|
||||||
|
arg_parser.add_argument('-v', action='store_true', help='Be verbose')
|
||||||
|
arg_parser.add_argument('-vv', action='store_true', help='Be more verbose')
|
||||||
|
arg_parser.add_argument('--userdir', type=str, help='path to users export dir tree')
|
||||||
|
arg_parser.add_argument('pins_dir', type=str, help='path to pin export dir tree')
|
||||||
|
|
||||||
|
|
||||||
|
args = arg_parser.parse_args()
|
||||||
|
|
||||||
|
if args.v:
|
||||||
|
logg.setLevel(logging.INFO)
|
||||||
|
elif args.vv:
|
||||||
|
logg.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
config = confini.Config(args.c, os.environ.get('CONFINI_ENV_PREFIX'))
|
||||||
|
config.process()
|
||||||
|
logg.info('loaded config\n{}'.format(config))
|
||||||
|
|
||||||
|
celery_app = celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL'))
|
||||||
|
|
||||||
|
user_dir = args.userdir
|
||||||
|
pins_dir = args.pins_dir
|
||||||
|
|
||||||
|
|
||||||
|
def generate_password_hash():
|
||||||
|
key = Fernet.generate_key()
|
||||||
|
fnt = Fernet(key)
|
||||||
|
pin = str(random.randint(1000, 9999))
|
||||||
|
return fnt.encrypt(bcrypt.hashpw(pin.encode('utf-8'), bcrypt.gensalt())).decode()
|
||||||
|
|
||||||
|
|
||||||
|
user_old_dir = os.path.join(user_dir, 'old')
|
||||||
|
logg.debug(f'reading user data from: {user_old_dir}')
|
||||||
|
|
||||||
|
pins_file = open(f'{pins_dir}/pins.csv', 'w')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
for x in os.walk(user_old_dir):
|
||||||
|
for y in x[2]:
|
||||||
|
# skip non-json files
|
||||||
|
if y[len(y) - 5:] != '.json':
|
||||||
|
continue
|
||||||
|
|
||||||
|
# define file path for
|
||||||
|
filepath = None
|
||||||
|
if y[:15] != '_ussd_data.json':
|
||||||
|
filepath = os.path.join(x[0], y)
|
||||||
|
f = open(filepath, 'r')
|
||||||
|
try:
|
||||||
|
o = json.load(f)
|
||||||
|
except json.decoder.JSONDecodeError as e:
|
||||||
|
f.close()
|
||||||
|
logg.error('load error for {}: {}'.format(y, e))
|
||||||
|
continue
|
||||||
|
f.close()
|
||||||
|
u = Person.deserialize(o)
|
||||||
|
|
||||||
|
phone_object = phonenumbers.parse(u.tel)
|
||||||
|
phone = phonenumbers.format_number(phone_object, phonenumbers.PhoneNumberFormat.E164)
|
||||||
|
password_hash = uuid.uuid4().hex
|
||||||
|
pins_file.write(f'{phone},{password_hash}\n')
|
||||||
|
logg.info(f'Writing phone: {phone}, password_hash: {password_hash}')
|
||||||
|
|
||||||
|
pins_file.close()
|
||||||
@@ -28,11 +28,12 @@ logg = logging.getLogger()
|
|||||||
|
|
||||||
fake = Faker(['sl', 'en_US', 'no', 'de', 'ro'])
|
fake = Faker(['sl', 'en_US', 'no', 'de', 'ro'])
|
||||||
|
|
||||||
default_config_dir = './config'
|
script_dir = os.path.realpath(os.path.dirname(__file__))
|
||||||
|
# config_dir = os.environ.get('CONFINI_DIR', '/usr/local/etc/cic')
|
||||||
|
config_dir = os.environ.get('CONFINI_DIR', os.path.join(script_dir, 'config'))
|
||||||
|
|
||||||
argparser = argparse.ArgumentParser()
|
argparser = argparse.ArgumentParser()
|
||||||
argparser.add_argument('-c', type=str, default=default_config_dir, help='Config dir')
|
argparser.add_argument('-c', type=str, default=config_dir, help='Config dir')
|
||||||
argparser.add_argument('--tag', type=str, action='append',
|
argparser.add_argument('--tag', type=str, action='append',
|
||||||
help='Tags to add to record')
|
help='Tags to add to record')
|
||||||
argparser.add_argument('--gift-threshold', type=int,
|
argparser.add_argument('--gift-threshold', type=int,
|
||||||
@@ -52,7 +53,7 @@ elif args.vv:
|
|||||||
|
|
||||||
config = confini.Config(args.c, os.environ.get('CONFINI_ENV_PREFIX'))
|
config = confini.Config(args.c, os.environ.get('CONFINI_ENV_PREFIX'))
|
||||||
config.process()
|
config.process()
|
||||||
logg.debug('loaded config\n{}'.format(config))
|
logg.info('loaded config\n{}'.format(config))
|
||||||
|
|
||||||
|
|
||||||
dt_now = datetime.datetime.utcnow()
|
dt_now = datetime.datetime.utcnow()
|
||||||
|
|||||||
@@ -9,12 +9,9 @@ COPY package.json \
|
|||||||
package-lock.json \
|
package-lock.json \
|
||||||
.
|
.
|
||||||
|
|
||||||
|
RUN --mount=type=cache,mode=0755,target=/root/node_modules npm install
|
||||||
|
|
||||||
RUN npm ci --production
|
COPY requirements.txt .
|
||||||
#RUN --mount=type=cache,mode=0755,target=/root/node_modules npm install
|
|
||||||
|
|
||||||
COPY requirements.txt .
|
|
||||||
COPY config/ /usr/local/etc/data-seeding
|
|
||||||
|
|
||||||
ARG EXTRA_INDEX_URL="https://pip.grassrootseconomics.net:8433"
|
ARG EXTRA_INDEX_URL="https://pip.grassrootseconomics.net:8433"
|
||||||
ARG GITLAB_PYTHON_REGISTRY="https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple"
|
ARG GITLAB_PYTHON_REGISTRY="https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple"
|
||||||
|
|||||||
24
apps/data-seeding/docker/Dockerfile_ci
Normal file
24
apps/data-seeding/docker/Dockerfile_ci
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# syntax = docker/dockerfile:1.2
|
||||||
|
FROM registry.gitlab.com/grassrootseconomics/cic-base-images:python-3.8.6-dev-5ab8bf45
|
||||||
|
|
||||||
|
WORKDIR /root
|
||||||
|
|
||||||
|
RUN mkdir -vp /usr/local/etc/cic
|
||||||
|
|
||||||
|
COPY package.json \
|
||||||
|
package-lock.json \
|
||||||
|
.
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
|
||||||
|
ARG EXTRA_INDEX_URL="https://pip.grassrootseconomics.net:8433"
|
||||||
|
ARG GITLAB_PYTHON_REGISTRY="https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple"
|
||||||
|
RUN pip install \
|
||||||
|
--extra-index-url $GITLAB_PYTHON_REGISTRY \
|
||||||
|
--extra-index-url $EXTRA_INDEX_URL -r requirements.txt
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
ENTRYPOINT [ ]
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
if [[ -d "$OUT_DIR" ]]
|
|
||||||
then
|
|
||||||
echo "found existing IMPORT DIR cleaning up..."
|
|
||||||
rm -rf "$OUT_DIR"
|
|
||||||
mkdir -p "$OUT_DIR"
|
|
||||||
else
|
|
||||||
echo "IMPORT DIR does not exist creating it."
|
|
||||||
mkdir -p "$OUT_DIR"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# using timeout because the timeout flag for celery inspect does not work
|
|
||||||
timeout 5 celery inspect ping -b "$CELERY_BROKER_URL"
|
|
||||||
if [[ $? -eq 124 ]]
|
|
||||||
then
|
|
||||||
>&2 echo "Celery workers not available. Is the CELERY_BROKER_URL ($CELERY_BROKER_URL) correct?"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Creating seed data..."
|
|
||||||
python create_import_users.py -vv -c "$CONFIG" --dir "$OUT_DIR" "$NUMBER_OF_USERS"
|
|
||||||
wait $!
|
|
||||||
|
|
||||||
echo "Check for running celery workers ..."
|
|
||||||
if [ -f ./cic-ussd-import.pid ];
|
|
||||||
then
|
|
||||||
echo "Found a running worker. Killing ..."
|
|
||||||
kill -9 $(<cic-ussd-import.pid)
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Purge tasks from celery worker"
|
|
||||||
celery -A cic_ussd.import_task purge -Q "$CELERY_QUEUE" --broker redis://"$REDIS_HOST":"$REDIS_PORT" -f
|
|
||||||
|
|
||||||
echo "Start celery work and import balance job"
|
|
||||||
if [ "$INCLUDE_BALANCES" != "y" ]
|
|
||||||
then
|
|
||||||
echo "Running worker without opening balance transactions"
|
|
||||||
TARGET_TX_COUNT=$NUMBER_OF_USERS
|
|
||||||
nohup python cic_ussd/import_balance.py -vv -c "$CONFIG" -p "$ETH_PROVIDER" -r "$CIC_REGISTRY_ADDRESS" --token-symbol "$TOKEN_SYMBOL" -y "$KEYSTORE_PATH" "$OUT_DIR" > nohup.out 2> nohup.err < /dev/null &
|
|
||||||
else
|
|
||||||
echo "Running worker with opening balance transactions"
|
|
||||||
TARGET_TX_COUNT=$((NUMBER_OF_USERS*2))
|
|
||||||
nohup python cic_ussd/import_balance.py -vv -c "$CONFIG" -p "$ETH_PROVIDER" -r "$CIC_REGISTRY_ADDRESS" --include-balances --token-symbol "$TOKEN_SYMBOL" -y "$KEYSTORE_PATH" "$OUT_DIR" &
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Target count set to ${TARGET_TX_COUNT}"
|
|
||||||
until [ -f ./cic-import-ussd.pid ]
|
|
||||||
do
|
|
||||||
echo "Polling for celery worker pid file..."
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
IMPORT_BALANCE_JOB=$(<cic-import-ussd.pid)
|
|
||||||
|
|
||||||
echo "Start import users job"
|
|
||||||
if [ "$USSD_SSL" == "y" ]
|
|
||||||
then
|
|
||||||
echo "Targeting secure ussd-user server"
|
|
||||||
python cic_ussd/import_users.py -vv -c "$CONFIG" --ussd-host "$USSD_HOST" --ussd-port "$USSD_PORT" "$OUT_DIR"
|
|
||||||
else
|
|
||||||
python cic_ussd/import_users.py -vv -c "$CONFIG" --ussd-host "$USSD_HOST" --ussd-port "$USSD_PORT" --ussd-no-ssl "$OUT_DIR"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Waiting for import balance job to complete ..."
|
|
||||||
tail --pid="$IMPORT_BALANCE_JOB" -f /dev/null
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "Importing pins"
|
|
||||||
python cic_ussd/import_pins.py -c "$CONFIG" -vv "$OUT_DIR"
|
|
||||||
set +e
|
|
||||||
wait $!
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "Importing ussd data"
|
|
||||||
python cic_ussd/import_ussd_data.py -c "$CONFIG" -vv "$OUT_DIR"
|
|
||||||
set +e
|
|
||||||
wait $!
|
|
||||||
|
|
||||||
echo "Importing person metadata"
|
|
||||||
node cic_meta/import_meta.js "$OUT_DIR" "$NUMBER_OF_USERS"
|
|
||||||
|
|
||||||
echo "Import preferences metadata"
|
|
||||||
node cic_meta/import_meta_preferences.js "$OUT_DIR" "$NUMBER_OF_USERS"
|
|
||||||
|
|
||||||
CIC_NOTIFY_DATABASE=postgres://$DATABASE_USER:$DATABASE_PASSWORD@$DATABASE_HOST:$DATABASE_PORT/$NOTIFY_DATABASE_NAME
|
|
||||||
NOTIFICATION_COUNT=$(psql -qtA "$CIC_NOTIFY_DATABASE" -c 'SELECT COUNT(message) FROM notification WHERE message IS NOT NULL')
|
|
||||||
while [[ "$NOTIFICATION_COUNT" < "$TARGET_TX_COUNT" ]]
|
|
||||||
do
|
|
||||||
NOTIFICATION_COUNT=$(psql -qtA "$CIC_NOTIFY_DATABASE" -c 'SELECT COUNT(message) FROM notification WHERE message IS NOT NULL')
|
|
||||||
sleep 5
|
|
||||||
echo "Notification count is: ${NOTIFICATION_COUNT} of ${TARGET_TX_COUNT}. Checking after 5 ..."
|
|
||||||
done
|
|
||||||
echo "Running verify script."
|
|
||||||
python verify.py -c "$CONFIG" -v -p "$ETH_PROVIDER" -r "$CIC_REGISTRY_ADDRESS" --exclude "$EXCLUSIONS" --meta-provider "$META_URL" --token-symbol "$TOKEN_SYMBOL" --ussd-provider "$USSD_PROVIDER" "$OUT_DIR"
|
|
||||||
2216
apps/data-seeding/package-lock.json
generated
2216
apps/data-seeding/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,13 @@
|
|||||||
sarafu-faucet~=0.0.7a2
|
sarafu-faucet~=0.0.7a1
|
||||||
cic-eth[tools]~=0.12.4a8
|
cic-eth[tools]~=0.12.4a7
|
||||||
cic-types~=0.1.0a15
|
cic-types~=0.1.0a14
|
||||||
crypto-dev-signer~=0.4.15a7
|
crypto-dev-signer>=0.4.15a1,<=0.4.15
|
||||||
faker==4.17.1
|
faker==4.17.1
|
||||||
chainsyncer~=0.0.6a3
|
chainsyncer~=0.0.6a3
|
||||||
chainlib-eth~=0.0.9a14
|
chainlib-eth~=0.0.9a7
|
||||||
eth-address-index~=0.2.3a4
|
eth-address-index~=0.2.3a4
|
||||||
eth-contract-registry~=0.6.3a3
|
eth-contract-registry~=0.6.3a3
|
||||||
eth-accounts-index~=0.1.2a3
|
eth-accounts-index~=0.1.2a3
|
||||||
eth-erc20~=0.1.2a3
|
eth-erc20~=0.1.2a2
|
||||||
erc20-faucet~=0.3.2a2
|
erc20-faucet~=0.3.2a2
|
||||||
psycopg2==2.8.6
|
psycopg2==2.8.6
|
||||||
liveness~=0.0.1a7
|
|
||||||
|
|||||||
@@ -64,10 +64,6 @@ phone_tests = [
|
|||||||
'ussd_pins'
|
'ussd_pins'
|
||||||
]
|
]
|
||||||
|
|
||||||
admin_tests = [
|
|
||||||
'local_key',
|
|
||||||
]
|
|
||||||
|
|
||||||
all_tests = eth_tests + custodial_tests + metadata_tests + phone_tests
|
all_tests = eth_tests + custodial_tests + metadata_tests + phone_tests
|
||||||
|
|
||||||
argparser = argparse.ArgumentParser(description='daemon that monitors transactions in new blocks')
|
argparser = argparse.ArgumentParser(description='daemon that monitors transactions in new blocks')
|
||||||
@@ -78,7 +74,6 @@ argparser.add_argument('-i', '--chain-spec', type=str, dest='i', help='chain spe
|
|||||||
argparser.add_argument('--meta-provider', type=str, dest='meta_provider', default='http://localhost:63380', help='cic-meta url')
|
argparser.add_argument('--meta-provider', type=str, dest='meta_provider', default='http://localhost:63380', help='cic-meta url')
|
||||||
argparser.add_argument('--ussd-provider', type=str, dest='ussd_provider', default='http://localhost:63315', help='cic-ussd url')
|
argparser.add_argument('--ussd-provider', type=str, dest='ussd_provider', default='http://localhost:63315', help='cic-ussd url')
|
||||||
argparser.add_argument('--skip-custodial', dest='skip_custodial', action='store_true', help='skip all custodial verifications')
|
argparser.add_argument('--skip-custodial', dest='skip_custodial', action='store_true', help='skip all custodial verifications')
|
||||||
argparser.add_argument('--skip-ussd', dest='skip_ussd', action='store_true', help='skip all ussd verifications')
|
|
||||||
argparser.add_argument('--skip-metadata', dest='skip_metadata', action='store_true', help='skip all metadata verifications')
|
argparser.add_argument('--skip-metadata', dest='skip_metadata', action='store_true', help='skip all metadata verifications')
|
||||||
argparser.add_argument('--exclude', action='append', type=str, default=[], help='skip specified verification')
|
argparser.add_argument('--exclude', action='append', type=str, default=[], help='skip specified verification')
|
||||||
argparser.add_argument('--include', action='append', type=str, help='include specified verification')
|
argparser.add_argument('--include', action='append', type=str, help='include specified verification')
|
||||||
@@ -139,11 +134,6 @@ if args.skip_custodial:
|
|||||||
for t in custodial_tests:
|
for t in custodial_tests:
|
||||||
if t not in exclude:
|
if t not in exclude:
|
||||||
exclude.append(t)
|
exclude.append(t)
|
||||||
if args.skip_ussd:
|
|
||||||
logg.info('will skip all ussd verifications ({})'.format(','.join(phone_tests)))
|
|
||||||
for t in phone_tests:
|
|
||||||
if t not in exclude:
|
|
||||||
exclude.append(t)
|
|
||||||
if args.skip_metadata:
|
if args.skip_metadata:
|
||||||
logg.info('will skip all metadata verifications ({})'.format(','.join(metadata_tests)))
|
logg.info('will skip all metadata verifications ({})'.format(','.join(metadata_tests)))
|
||||||
for t in metadata_tests:
|
for t in metadata_tests:
|
||||||
@@ -164,8 +154,20 @@ for t in custodial_tests:
|
|||||||
logg.info('activating custodial module'.format(t))
|
logg.info('activating custodial module'.format(t))
|
||||||
break
|
break
|
||||||
|
|
||||||
|
cols = os.get_terminal_size().columns
|
||||||
|
|
||||||
outfunc = logg.debug
|
|
||||||
|
def to_terminalwidth(s):
|
||||||
|
ss = s.ljust(int(cols)-1)
|
||||||
|
ss += "\r"
|
||||||
|
return ss
|
||||||
|
|
||||||
|
def default_outfunc(s):
|
||||||
|
ss = to_terminalwidth(s)
|
||||||
|
sys.stdout.write(ss)
|
||||||
|
outfunc = default_outfunc
|
||||||
|
if logg.isEnabledFor(logging.DEBUG):
|
||||||
|
outfunc = logg.debug
|
||||||
|
|
||||||
|
|
||||||
def send_ussd_request(address, data_dir):
|
def send_ussd_request(address, data_dir):
|
||||||
@@ -185,10 +187,9 @@ def send_ussd_request(address, data_dir):
|
|||||||
phone = p.tel
|
phone = p.tel
|
||||||
|
|
||||||
session = uuid.uuid4().hex
|
session = uuid.uuid4().hex
|
||||||
valid_service_codes = config.get('USSD_SERVICE_CODE').split(",")
|
|
||||||
data = {
|
data = {
|
||||||
'sessionId': session,
|
'sessionId': session,
|
||||||
'serviceCode': valid_service_codes[0],
|
'serviceCode': config.get('APP_SERVICE_CODE'),
|
||||||
'phoneNumber': phone,
|
'phoneNumber': phone,
|
||||||
'text': '',
|
'text': '',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
|
image:
|
||||||
|
name: gcr.io/kaniko-project/executor:debug
|
||||||
|
entrypoint: [""]
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
KANIKO_CACHE_ARGS: "--cache=true --cache-copy-layers=true --cache-ttl=24h"
|
KANIKO_CACHE_ARGS: "--cache=true --cache-copy-layers=true --cache-ttl=24h"
|
||||||
MR_IMAGE_TAG: $CI_REGISTRY_IMAGE/mergerequest/$APP_NAME:$CI_COMMIT_SHORT_SHA
|
MR_IMAGE_TAG: $CI_REGISTRY_IMAGE/mergerequest/$APP_NAME:$CI_COMMIT_SHORT_SHA
|
||||||
|
|
||||||
.py_build_merge_request:
|
.py_build_merge_request:
|
||||||
image:
|
|
||||||
name: gcr.io/kaniko-project/executor:debug
|
|
||||||
entrypoint: [""]
|
|
||||||
stage: build
|
stage: build
|
||||||
script:
|
script:
|
||||||
- mkdir -p /kaniko/.docker
|
- mkdir -p /kaniko/.docker
|
||||||
@@ -16,9 +16,6 @@ variables:
|
|||||||
--cache-repo $CI_REGISTRY_IMAGE --destination $MR_IMAGE_TAG
|
--cache-repo $CI_REGISTRY_IMAGE --destination $MR_IMAGE_TAG
|
||||||
|
|
||||||
.py_build_target_dev:
|
.py_build_target_dev:
|
||||||
image:
|
|
||||||
name: gcr.io/kaniko-project/executor:debug
|
|
||||||
entrypoint: [""]
|
|
||||||
stage: build
|
stage: build
|
||||||
variables:
|
variables:
|
||||||
IMAGE_TAG_BASE: $CI_REGISTRY_IMAGE/$APP_NAME:mr-unittest-$CI_COMMIT_SHORT_SHA
|
IMAGE_TAG_BASE: $CI_REGISTRY_IMAGE/$APP_NAME:mr-unittest-$CI_COMMIT_SHORT_SHA
|
||||||
@@ -31,9 +28,6 @@ variables:
|
|||||||
--destination $MR_IMAGE_TAG
|
--destination $MR_IMAGE_TAG
|
||||||
|
|
||||||
.py_build_push:
|
.py_build_push:
|
||||||
image:
|
|
||||||
name: gcr.io/kaniko-project/executor:debug
|
|
||||||
entrypoint: [""]
|
|
||||||
stage: build
|
stage: build
|
||||||
variables:
|
variables:
|
||||||
IMAGE_TAG_BASE: $CI_REGISTRY_IMAGE/$APP_NAME:$CI_COMMIT_BRANCH-$CI_COMMIT_SHORT_SHA
|
IMAGE_TAG_BASE: $CI_REGISTRY_IMAGE/$APP_NAME:$CI_COMMIT_BRANCH-$CI_COMMIT_SHORT_SHA
|
||||||
|
|||||||
@@ -13,8 +13,20 @@ networks:
|
|||||||
name: cic-network
|
name: cic-network
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
# eth:
|
||||||
|
# image: trufflesuite/ganache-cli
|
||||||
|
# ports:
|
||||||
|
# - ${HTTP_PORT_ETH:-8545}
|
||||||
|
# - ${WS_PORT_ETH:-8546}
|
||||||
|
# # Note! -e switch doesnt work, whatever you put there, it will be 100
|
||||||
|
# command: "-i 8996 -e 1000 -l 90000000 \
|
||||||
|
# -m '${DEV_MNEMONIC:-\"history stumble mystery avoid embark arrive mom foil pledge keep grain dice\"}' \
|
||||||
|
# -v --db /tmp/cic/ganache/ganache.db \
|
||||||
|
# --noVMErrorsOnRPCResponse --allowUnlimitedContractSize"
|
||||||
|
# volumes:
|
||||||
|
# - ganache-db:/tmp/cic/ganache
|
||||||
|
|
||||||
eth:
|
eth:
|
||||||
image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/bloxberg-node:${TAG:-latest}
|
|
||||||
build:
|
build:
|
||||||
context: apps/bloxbergValidatorSetup
|
context: apps/bloxbergValidatorSetup
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -59,7 +71,8 @@ services:
|
|||||||
- bee-data:/tmp/cic/bee
|
- bee-data:/tmp/cic/bee
|
||||||
|
|
||||||
contract-migration:
|
contract-migration:
|
||||||
image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/contract-migration:${TAG:-latest}
|
profiles:
|
||||||
|
- migrations
|
||||||
build:
|
build:
|
||||||
context: apps/contract-migration
|
context: apps/contract-migration
|
||||||
dockerfile: docker/Dockerfile
|
dockerfile: docker/Dockerfile
|
||||||
@@ -70,14 +83,16 @@ services:
|
|||||||
EXTRA_PIP_ARGS: $EXTRA_PIP_ARGS
|
EXTRA_PIP_ARGS: $EXTRA_PIP_ARGS
|
||||||
# image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/contract-migration:latest
|
# image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/contract-migration:latest
|
||||||
environment:
|
environment:
|
||||||
RPC_PROVIDER: ${RPC_PROVIDER:-http://eth:8545}
|
CIC_REGISTRY_ADDRESS: $CIC_REGISTRY_ADDRESS
|
||||||
ETH_PROVIDER: ${RPC_PROVIDER:-http://eth:8545}
|
ETH_PROVIDER: ${CIC_HTTP_PROVIDER:-http://eth:8545}
|
||||||
RPC_HTTP_PROVIDER: ${RPC_PROVIDER:-http://eth:8545}
|
RPC_HTTP_PROVIDER: ${CIC_HTTP_PROVIDER:-http://eth:8545}
|
||||||
|
# And these two are for wait-for-it (could parse this)
|
||||||
DEV_USE_DOCKER_WAIT_SCRIPT: 1
|
DEV_USE_DOCKER_WAIT_SCRIPT: 1
|
||||||
|
ETH_PROVIDER_HOST: eth
|
||||||
|
ETH_PROVIDER_PORT: 8545
|
||||||
CHAIN_SPEC: ${CHAIN_SPEC:-evm:bloxberg:8996}
|
CHAIN_SPEC: ${CHAIN_SPEC:-evm:bloxberg:8996}
|
||||||
CIC_CHAIN_SPEC: ${CHAIN_SPEC:-evm:bloxberg:8996}
|
CIC_CHAIN_SPEC: ${CHAIN_SPEC:-evm:bloxberg:8996}
|
||||||
DEV_DATA_DIR: ${DEV_DATA_DIR:-/tmp/cic/config}
|
CIC_DATA_DIR: ${CIC_DATA_DIR:-/tmp/cic/config}
|
||||||
DEV_CONFIG_RESET: $DEV_CONFIG_RESET
|
|
||||||
DATABASE_HOST: ${DATABASE_HOST:-postgres}
|
DATABASE_HOST: ${DATABASE_HOST:-postgres}
|
||||||
DATABASE_PORT: ${DATABASE_PORT:-5432}
|
DATABASE_PORT: ${DATABASE_PORT:-5432}
|
||||||
DATABASE_NAME: ${DEV_DATABASE_NAME_CIC_ETH:-cic_eth}
|
DATABASE_NAME: ${DEV_DATABASE_NAME_CIC_ETH:-cic_eth}
|
||||||
@@ -91,19 +106,18 @@ services:
|
|||||||
CELERY_RESULT_URL: ${CELERY_RESULT_URL:-redis://redis:6379}
|
CELERY_RESULT_URL: ${CELERY_RESULT_URL:-redis://redis:6379}
|
||||||
DEV_PIP_EXTRA_INDEX_URL: ${DEV_PIP_EXTRA_INDEX_URL:-https://pip.grassrootseconomics.net:8433}
|
DEV_PIP_EXTRA_INDEX_URL: ${DEV_PIP_EXTRA_INDEX_URL:-https://pip.grassrootseconomics.net:8433}
|
||||||
RUN_MASK: ${RUN_MASK:-0} # bit flags; 1: contract migrations 2: seed data
|
RUN_MASK: ${RUN_MASK:-0} # bit flags; 1: contract migrations 2: seed data
|
||||||
DEV_FAUCET_AMOUNT: ${DEV_FAUCET_AMOUNT:-50000000}
|
DEV_FAUCET_AMOUNT: ${DEV_FAUCET_AMOUNT:-0}
|
||||||
DEV_ETH_GAS_PRICE: $DEV_ETH_GAS_PRICE
|
#DEV_SARAFU_DEMURRAGE_LEVEL: ${DEV_SARAFU_DEMURRAGE_LEVEL:-196454828847045000000000000000000}
|
||||||
TOKEN_NAME: ${TOKEN_NAME:-Giftable Token}
|
DEV_ETH_GAS_PRICE: ${DEV_ETH_GAS_PRICE:-1}
|
||||||
TOKEN_SYMBOL: ${TOKEN_SYMBOL:-GFT}
|
CIC_DEFAULT_TOKEN_SYMBOL: $CIC_DEFAULT_TOKEN_SYMBOL
|
||||||
TOKEN_TYPE: ${TOKEN_TYPE:-giftable_erc20_token}
|
TOKEN_NAME: $TOKEN_NAME
|
||||||
TOKEN_DECIMALS: $TOKEN_DECIMALS
|
TOKEN_DECIMALS: $TOKEN_DECIMALS
|
||||||
TOKEN_REDISTRIBUTION_PERIOD: $TOKEN_DEMURRAGE_REDISTRIBUTION_PERIOD
|
TOKEN_REDISTRIBUTION_PERIOD: $TOKEN_REDISTRIBUTION_PERIOD
|
||||||
TASKS_TRANSFER_CALLBACKS: ${TASKS_TRANSFER_CALLBACKS:-"cic-eth:cic_eth.callbacks.noop.noop,cic-ussd:cic_ussd.tasks.callback_handler.transaction_callback"}
|
|
||||||
TOKEN_SUPPLY_LIMIT: $TOKEN_SUPPLY_LIMIT
|
TOKEN_SUPPLY_LIMIT: $TOKEN_SUPPLY_LIMIT
|
||||||
TOKEN_DEMURRAGE_LEVEL: $TOKEN_DEMURRAGE_LEVEL
|
TOKEN_DEMURRAGE_LEVEL: ${TOKEN_DEMURRAGE_LEVEL:-196454828847045000000000000000000}
|
||||||
TOKEN_SINK_ADDRESS: $TOKEN_SINK_ADDRESS
|
TOKEN_SINK_ADDRESS: $TOKEN_SINK_ADDRESS
|
||||||
SIGNER_PROVIDER: ${SIGNER_SOCKET_PATH:-http://cic-eth-signer:8000}
|
TOKEN_TYPE: $TOKEN_TYPE
|
||||||
restart: on-failure
|
#CONFINI_DIR: ${CONFINI_DIR:-/tmp/cic/config}
|
||||||
command: ["./run_job.sh"]
|
command: ["./run_job.sh"]
|
||||||
#command: ["./reset.sh"]
|
#command: ["./reset.sh"]
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -114,51 +128,9 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- contract-config:/tmp/cic/config
|
- contract-config:/tmp/cic/config
|
||||||
|
|
||||||
|
|
||||||
data-seeding:
|
|
||||||
image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/data-seeding:${TAG:-latest}
|
|
||||||
build:
|
|
||||||
context: apps/data-seeding
|
|
||||||
dockerfile: docker/Dockerfile
|
|
||||||
args:
|
|
||||||
pip_index_url: ${PIP_DEFAULT_INDEX_URL:-https://pypi.org/simple}
|
|
||||||
pip_extra_args: $PIP_EXTRA_ARGS
|
|
||||||
environment:
|
|
||||||
CIC_REGISTRY_ADDRESS: ${CIC_REGISTRY_ADDRESS:-0xea6225212005e86a4490018ded4bf37f3e772161}
|
|
||||||
OUT_DIR: out
|
|
||||||
NUMBER_OF_USERS: 10
|
|
||||||
CONFIG: /usr/local/etc/data-seeding
|
|
||||||
CIC_CHAIN_SPEC: ${CIC_CHAIN_SPEC:-evm:bloxberg:8996}
|
|
||||||
ETH_PROVIDER: ${CIC_HTTP_PROVIDER:-http://eth:8545}
|
|
||||||
TOKEN_SYMBOL: GFT
|
|
||||||
KEYSTORE_PATH: keystore/UTC--2021-01-08T17-18-44.521011372Z--eb3907ecad74a0013c259d5874ae7f22dcbcc95c
|
|
||||||
USSD_HOST: cic-user-ussd-server
|
|
||||||
USSD_PORT: 9000
|
|
||||||
INCLUDE_BALANCES: y
|
|
||||||
USSD_SSL: n
|
|
||||||
DATABASE_NAME: ${DATABASE_NAME:-cic_ussd}
|
|
||||||
DATABASE_USER: ${DATABASE_USER:-grassroots}
|
|
||||||
DATABASE_PASSWORD: ${DATABASE_PASSWORD:-tralala} # this is is set at initdb see: postgres/initdb/create_db.sql
|
|
||||||
DATABASE_HOST: ${DATABASE_HOST:-postgres}
|
|
||||||
DATABASE_PORT: ${DATABASE_PORT:-5432}
|
|
||||||
CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://redis:6379}
|
|
||||||
CELERY_RESULT_URL: ${CELERY_RESULT_URL:-redis://redis:6379}
|
|
||||||
NOTIFY_DATABASE_NAME: cic_notify
|
|
||||||
REDIS_HOST: redis
|
|
||||||
REDIS_PORT: 6379
|
|
||||||
REDIS_DB: 0
|
|
||||||
META_HOST: meta
|
|
||||||
META_PORT: 8000
|
|
||||||
META_URL: http://meta:8000
|
|
||||||
USSD_PROVIDER: http://cic-user-ussd-server:9000
|
|
||||||
CELERY_QUEUE: cic-import-ussd
|
|
||||||
EXCLUSIONS: ussd
|
|
||||||
command: bash import_ussd.sh
|
|
||||||
volumes:
|
|
||||||
- contract-config:/tmp/cic/config/:ro
|
|
||||||
|
|
||||||
cic-cache-tracker:
|
cic-cache-tracker:
|
||||||
image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/cic-cache:${TAG:-latest}
|
profiles:
|
||||||
|
- cache
|
||||||
build:
|
build:
|
||||||
context: apps/cic-cache
|
context: apps/cic-cache
|
||||||
dockerfile: docker/Dockerfile
|
dockerfile: docker/Dockerfile
|
||||||
@@ -166,8 +138,8 @@ services:
|
|||||||
EXTRA_INDEX_URL: ${EXTRA_INDEX_URL:-https://pip.grassrootseconomics.net:8433}
|
EXTRA_INDEX_URL: ${EXTRA_INDEX_URL:-https://pip.grassrootseconomics.net:8433}
|
||||||
environment:
|
environment:
|
||||||
CIC_REGISTRY_ADDRESS: $CIC_REGISTRY_ADDRESS # supplied at contract-config after contract provisioning
|
CIC_REGISTRY_ADDRESS: $CIC_REGISTRY_ADDRESS # supplied at contract-config after contract provisioning
|
||||||
ETH_PROVIDER: ${RPC_PROVIDER:-http://eth:8545}
|
ETH_PROVIDER: ${RPC_HTTP_PROVIDER:-http://eth:8545}
|
||||||
RPC_PROVIDER: ${RPC_PROVIDER:-http://eth:8545}
|
RPC_HTTP_PROVIDER: ${RPC_HTTP_PROVIDER:-http://eth:8545}
|
||||||
DATABASE_USER: ${DATABASE_USER:-grassroots}
|
DATABASE_USER: ${DATABASE_USER:-grassroots}
|
||||||
DATABASE_PASSWORD: ${DATABASE_PASSWORD:-tralala} # this is is set at initdb see: postgres/initdb/create_db.sql
|
DATABASE_PASSWORD: ${DATABASE_PASSWORD:-tralala} # this is is set at initdb see: postgres/initdb/create_db.sql
|
||||||
DATABASE_HOST: ${DATABASE_HOST:-postgres}
|
DATABASE_HOST: ${DATABASE_HOST:-postgres}
|
||||||
@@ -181,7 +153,9 @@ services:
|
|||||||
CIC_CHAIN_SPEC: ${CHAIN_SPEC:-evm:bloxberg:8996}
|
CIC_CHAIN_SPEC: ${CHAIN_SPEC:-evm:bloxberg:8996}
|
||||||
CELERY_BROKER_URL: redis://redis:6379
|
CELERY_BROKER_URL: redis://redis:6379
|
||||||
CELERY_RESULT_URL: redis://redis:6379
|
CELERY_RESULT_URL: redis://redis:6379
|
||||||
restart: on-failure
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
depends_on:
|
depends_on:
|
||||||
- redis
|
- redis
|
||||||
- postgres
|
- postgres
|
||||||
@@ -190,13 +164,14 @@ services:
|
|||||||
- /bin/bash
|
- /bin/bash
|
||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
if [[ -f /tmp/cic/config/env_reset ]]; then source /tmp/cic/config/env_reset; fi
|
if [[ -f /tmp/cic/config/.env ]]; then source /tmp/cic/config/.env; fi
|
||||||
./start_tracker.sh -c /usr/local/etc/cic-cache -vv
|
./start_tracker.sh -c /usr/local/etc/cic-cache -vv
|
||||||
volumes:
|
volumes:
|
||||||
- contract-config:/tmp/cic/config/:ro
|
- contract-config:/tmp/cic/config/:ro
|
||||||
|
|
||||||
cic-cache-tasker:
|
cic-cache-tasker:
|
||||||
image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/cic-cache:${TAG:-latest}
|
profiles:
|
||||||
|
- cache
|
||||||
build:
|
build:
|
||||||
context: apps/cic-cache
|
context: apps/cic-cache
|
||||||
dockerfile: docker/Dockerfile
|
dockerfile: docker/Dockerfile
|
||||||
@@ -218,7 +193,9 @@ services:
|
|||||||
CIC_CHAIN_SPEC: ${CIC_CHAIN_SPEC:-evm:bloxberg:8996}
|
CIC_CHAIN_SPEC: ${CIC_CHAIN_SPEC:-evm:bloxberg:8996}
|
||||||
CELERY_BROKER_URL: redis://redis:6379
|
CELERY_BROKER_URL: redis://redis:6379
|
||||||
CELERY_RESULT_URL: redis://redis:6379
|
CELERY_RESULT_URL: redis://redis:6379
|
||||||
restart: unless-stopped
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
depends_on:
|
depends_on:
|
||||||
- redis
|
- redis
|
||||||
- postgres
|
- postgres
|
||||||
@@ -227,13 +204,14 @@ services:
|
|||||||
- /bin/bash
|
- /bin/bash
|
||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
if [[ -f /tmp/cic/config/env_reset ]]; then source /tmp/cic/config/env_reset; fi
|
if [[ -f /tmp/cic/config/.env ]]; then source /tmp/cic/config/.env; fi
|
||||||
/usr/local/bin/cic-cache-taskerd -vv
|
/usr/local/bin/cic-cache-taskerd -vv
|
||||||
volumes:
|
volumes:
|
||||||
- contract-config:/tmp/cic/config/:ro
|
- contract-config:/tmp/cic/config/:ro
|
||||||
|
|
||||||
cic-cache-server:
|
cic-cache-server:
|
||||||
image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/cic-cache:${TAG:-latest}
|
profiles:
|
||||||
|
- cache
|
||||||
build:
|
build:
|
||||||
context: apps/cic-cache
|
context: apps/cic-cache
|
||||||
dockerfile: docker/Dockerfile
|
dockerfile: docker/Dockerfile
|
||||||
@@ -248,18 +226,18 @@ services:
|
|||||||
DATABASE_DEBUG: 1
|
DATABASE_DEBUG: 1
|
||||||
#PGPASSWORD: $DATABASE_PASSWORD
|
#PGPASSWORD: $DATABASE_PASSWORD
|
||||||
SERVER_PORT: 8000
|
SERVER_PORT: 8000
|
||||||
restart: on-failure
|
|
||||||
ports:
|
ports:
|
||||||
- ${HTTP_PORT_CIC_CACHE:-63313}:8000
|
- ${HTTP_PORT_CIC_CACHE:-63313}:8000
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
- cic-cache-tasker
|
deploy:
|
||||||
- cic-cache-tracker
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
command:
|
command:
|
||||||
- /bin/bash
|
- /bin/bash
|
||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
if [[ -f /tmp/cic/config/env_reset ]]; then source /tmp/cic/config/env_reset; fi
|
if [[ -f /tmp/cic/config/.env ]]; then source /tmp/cic/config/.env; fi
|
||||||
"/usr/local/bin/uwsgi" \
|
"/usr/local/bin/uwsgi" \
|
||||||
--wsgi-file /root/cic_cache/runnable/daemons/server.py \
|
--wsgi-file /root/cic_cache/runnable/daemons/server.py \
|
||||||
--http :8000 \
|
--http :8000 \
|
||||||
@@ -267,7 +245,6 @@ services:
|
|||||||
|
|
||||||
|
|
||||||
cic-eth-tasker:
|
cic-eth-tasker:
|
||||||
image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/cic-eth:${TAG:-latest}
|
|
||||||
build:
|
build:
|
||||||
context: apps/cic-eth
|
context: apps/cic-eth
|
||||||
dockerfile: docker/Dockerfile
|
dockerfile: docker/Dockerfile
|
||||||
@@ -278,7 +255,7 @@ services:
|
|||||||
CIC_REGISTRY_ADDRESS: $CIC_REGISTRY_ADDRESS
|
CIC_REGISTRY_ADDRESS: $CIC_REGISTRY_ADDRESS
|
||||||
ETH_GAS_PROVIDER_ADDRESS: $DEV_ETH_ACCOUNT_GAS_PROVIDER
|
ETH_GAS_PROVIDER_ADDRESS: $DEV_ETH_ACCOUNT_GAS_PROVIDER
|
||||||
ETH_PROVIDER: ${ETH_PROVIDER:-http://eth:8545}
|
ETH_PROVIDER: ${ETH_PROVIDER:-http://eth:8545}
|
||||||
RPC_PROVIDER: ${ETH_PROVIDER:-http://eth:8545}
|
RPC_HTTP_PROVIDER: ${ETH_PROVIDER:-http://eth:8545}
|
||||||
DATABASE_USER: ${DATABASE_USER:-grassroots}
|
DATABASE_USER: ${DATABASE_USER:-grassroots}
|
||||||
DATABASE_HOST: ${DATABASE_HOST:-postgres}
|
DATABASE_HOST: ${DATABASE_HOST:-postgres}
|
||||||
DATABASE_PASSWORD: ${DATABASE_PASSWORD:-tralala}
|
DATABASE_PASSWORD: ${DATABASE_PASSWORD:-tralala}
|
||||||
@@ -296,85 +273,31 @@ services:
|
|||||||
CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://redis}
|
CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://redis}
|
||||||
CELERY_RESULT_URL: ${CELERY_RESULT_URL:-redis://redis}
|
CELERY_RESULT_URL: ${CELERY_RESULT_URL:-redis://redis}
|
||||||
CELERY_DEBUG: ${CELERY_DEBUG:-1}
|
CELERY_DEBUG: ${CELERY_DEBUG:-1}
|
||||||
#SIGNER_SOCKET_PATH: ${SIGNER_SOCKET_PATH:-http://cic-eth-signer:8000}
|
SIGNER_SOCKET_PATH: ${SIGNER_SOCKET_PATH:-ipc:///run/crypto-dev-signer/jsonrpc.ipc}
|
||||||
SIGNER_PROVIDER: ${SIGNER_PROVIDER:-http://cic-eth-signer:8000}
|
SIGNER_PROVIDER: ${SIGNER_SOCKET_PATH:-ipc:///run/crypto-dev-signer/jsonrpc.ipc}
|
||||||
SIGNER_SECRET: ${SIGNER_SECRET:-deadbeef}
|
SIGNER_SECRET: ${SIGNER_SECRET:-deadbeef}
|
||||||
ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER: ${DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER:-0xACB0BC74E1686D62dE7DC6414C999EA60C09F0eA}
|
ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER: ${DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER:-0xACB0BC74E1686D62dE7DC6414C999EA60C09F0eA}
|
||||||
TASKS_TRACE_QUEUE_STATUS: ${TASKS_TRACE_QUEUE_STATUS:-1}
|
TASKS_TRACE_QUEUE_STATUS: ${TASKS_TRACE_QUEUE_STATUS:-1}
|
||||||
CIC_DEFAULT_TOKEN_SYMBOL: ${CIC_DEFAULT_TOKEN_SYMBOL:-GFT}
|
CIC_DEFAULT_TOKEN_SYMBOL: ${CIC_DEFAULT_TOKEN_SYMBOL:-GFT}
|
||||||
restart: unless-stopped
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- eth
|
- eth
|
||||||
- postgres
|
- postgres
|
||||||
- redis
|
- redis
|
||||||
- cic-eth-signer
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
volumes:
|
volumes:
|
||||||
- signer-data:/run/crypto-dev-signer
|
- signer-data:/tmp/cic/signer
|
||||||
- contract-config:/tmp/cic/config/:ro
|
- contract-config:/tmp/cic/config/:ro
|
||||||
#command: ["/usr/local/bin/cic-eth-taskerd"]
|
|
||||||
#command: ["sleep", "3600"]
|
|
||||||
command:
|
command:
|
||||||
- /bin/bash
|
- /bin/bash
|
||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
if [[ -f /tmp/cic/config/env_reset ]]; then source /tmp/cic/config/env_reset; fi
|
if [[ -f /tmp/cic/config/.env ]]; then source /tmp/cic/config/.env; fi
|
||||||
./start_tasker.sh --aux-all -q cic-eth -vv
|
./start_tasker.sh --aux-all -q cic-eth -vv
|
||||||
|
|
||||||
cic-eth-signer:
|
|
||||||
image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/cic-eth:${TAG:-latest}
|
|
||||||
build:
|
|
||||||
context: apps/cic-eth
|
|
||||||
dockerfile: docker/Dockerfile
|
|
||||||
target: dev
|
|
||||||
args:
|
|
||||||
EXTRA_INDEX_URL: ${EXTRA_INDEX_URL:-https://pip.grassrootseconomics.net:8433}
|
|
||||||
environment:
|
|
||||||
CIC_REGISTRY_ADDRESS: $CIC_REGISTRY_ADDRESS
|
|
||||||
ETH_GAS_PROVIDER_ADDRESS: $DEV_ETH_ACCOUNT_GAS_PROVIDER
|
|
||||||
ETH_PROVIDER: ${ETH_PROVIDER:-http://eth:8545}
|
|
||||||
RPC_PROVIDER: ${ETH_PROVIDER:-http://eth:8545}
|
|
||||||
DATABASE_USER: ${DATABASE_USER:-grassroots}
|
|
||||||
DATABASE_HOST: ${DATABASE_HOST:-postgres}
|
|
||||||
DATABASE_PASSWORD: ${DATABASE_PASSWORD:-tralala}
|
|
||||||
DATABASE_NAME: ${DATABASE_NAME_CIC_ETH:-cic_eth}
|
|
||||||
DATABASE_PORT: ${DATABASE_PORT:-5432}
|
|
||||||
DATABASE_ENGINE: ${DATABASE_ENGINE:-postgres}
|
|
||||||
DATABASE_DRIVER: ${DATABASE_DRIVER:-psycopg2}
|
|
||||||
DATABASE_DEBUG: ${DATABASE_DEBUG:-0}
|
|
||||||
DATABASE_POOL_SIZE: 0
|
|
||||||
REDIS_PORT: 6379
|
|
||||||
REDIS_HOST: redis
|
|
||||||
PGPASSWORD: ${DATABASE_PASSWORD:-tralala}
|
|
||||||
CIC_CHAIN_SPEC: ${CIC_CHAIN_SPEC:-evm:bloxberg:8996}
|
|
||||||
CHAIN_SPEC: ${CIC_CHAIN_SPEC:-evm:bloxberg:8996}
|
|
||||||
CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://redis}
|
|
||||||
CELERY_RESULT_URL: ${CELERY_RESULT_URL:-redis://redis}
|
|
||||||
CELERY_DEBUG: ${CELERY_DEBUG:-1}
|
|
||||||
SIGNER_SOCKET_PATH: ${SIGNER_SOCKET_PATH:-http://0.0.0.0:8000}
|
|
||||||
SIGNER_PROVIDER: ${SIGNER_SOCKET_PATH:-http://0.0.0.0:8000}
|
|
||||||
SIGNER_SECRET: ${SIGNER_SECRET:-deadbeef}
|
|
||||||
ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER: ${DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER:-0xACB0BC74E1686D62dE7DC6414C999EA60C09F0eA}
|
|
||||||
TASKS_TRACE_QUEUE_STATUS: ${TASKS_TRACE_QUEUE_STATUS:-1}
|
|
||||||
CIC_DEFAULT_TOKEN_SYMBOL: ${CIC_DEFAULT_TOKEN_SYMBOL:-GFT}
|
|
||||||
restart: on-failure
|
|
||||||
depends_on:
|
|
||||||
- eth
|
|
||||||
- postgres
|
|
||||||
- redis
|
|
||||||
volumes:
|
|
||||||
- signer-data:/run/crypto-dev-signer
|
|
||||||
- contract-config:/tmp/cic/config/:ro
|
|
||||||
command: ["python", "/usr/local/bin/crypto-dev-daemon", "-c", "/usr/local/etc/crypto-dev-signer", "-vv"]
|
|
||||||
#command:
|
|
||||||
# - /bin/bash
|
|
||||||
# - -c
|
|
||||||
# - |
|
|
||||||
# if [[ -f /tmp/cic/config/env_reset ]]; then source /tmp/cic/config/env_reset; fi
|
|
||||||
# ./start_tasker.sh --aux-all -q cic-eth -vv
|
|
||||||
# command: [/bin/sh, "./start_tasker.sh", -q, cic-eth, -vv ]
|
# command: [/bin/sh, "./start_tasker.sh", -q, cic-eth, -vv ]
|
||||||
|
|
||||||
cic-eth-tracker:
|
cic-eth-tracker:
|
||||||
image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/cic-eth:${TAG:-latest}
|
|
||||||
build:
|
build:
|
||||||
context: apps/cic-eth
|
context: apps/cic-eth
|
||||||
dockerfile: docker/Dockerfile
|
dockerfile: docker/Dockerfile
|
||||||
@@ -382,8 +305,8 @@ services:
|
|||||||
args:
|
args:
|
||||||
EXTRA_INDEX_URL: ${EXTRA_INDEX_URL:-https://pip.grassrootseconomics.net:8433}
|
EXTRA_INDEX_URL: ${EXTRA_INDEX_URL:-https://pip.grassrootseconomics.net:8433}
|
||||||
environment:
|
environment:
|
||||||
RPC_PROVIDER: ${RPC_PROVIDER:-http://eth:8545}
|
RPC_HTTP_PROVIDER: ${RPC_HTTP_PROVIDER:-http://eth:8545}
|
||||||
ETH_PROVIDER: ${RPC_PROVIDER:-http://eth:8545}
|
ETH_PROVIDER: ${RPC_HTTP_PROVIDER:-http://eth:8545}
|
||||||
DATABASE_USER: ${DATABASE_USER:-grassroots}
|
DATABASE_USER: ${DATABASE_USER:-grassroots}
|
||||||
DATABASE_HOST: ${DATABASE_HOST:-postgres}
|
DATABASE_HOST: ${DATABASE_HOST:-postgres}
|
||||||
DATABASE_PASSWORD: ${DATABASE_PASSWORD:-tralala}
|
DATABASE_PASSWORD: ${DATABASE_PASSWORD:-tralala}
|
||||||
@@ -395,28 +318,30 @@ services:
|
|||||||
CIC_CHAIN_SPEC: ${CHAIN_SPEC:-evm:bloxberg:8996}
|
CIC_CHAIN_SPEC: ${CHAIN_SPEC:-evm:bloxberg:8996}
|
||||||
CHAIN_SPEC: ${CHAIN_SPEC:-evm:bloxberg:8996}
|
CHAIN_SPEC: ${CHAIN_SPEC:-evm:bloxberg:8996}
|
||||||
CIC_REGISTRY_ADDRESS: $CIC_REGISTRY_ADDRESS
|
CIC_REGISTRY_ADDRESS: $CIC_REGISTRY_ADDRESS
|
||||||
|
#BANCOR_DIR: $BANCOR_DIR
|
||||||
CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://redis}
|
CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://redis}
|
||||||
CELERY_RESULT_URL: ${CELERY_RESULT_URL:-redis://redis}
|
CELERY_RESULT_URL: ${CELERY_RESULT_URL:-redis://redis}
|
||||||
TASKS_TRANSFER_CALLBACKS: ${TASKS_TRANSFER_CALLBACKS:-"cic-eth:cic_eth.callbacks.noop.noop,cic-ussd:cic_ussd.tasks.callback_handler.transaction_callback"}
|
TASKS_TRANSFER_CALLBACKS: $TASKS_TRANSFER_CALLBACKS
|
||||||
restart: on-failure
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- eth
|
- eth
|
||||||
- postgres
|
- postgres
|
||||||
- redis
|
- redis
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
volumes:
|
volumes:
|
||||||
- contract-config:/tmp/cic/config/:ro
|
- contract-config:/tmp/cic/config/:ro
|
||||||
command:
|
command:
|
||||||
- /bin/bash
|
- /bin/bash
|
||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
if [[ -f /tmp/cic/config/env_reset ]]; then source /tmp/cic/config/env_reset; fi
|
if [[ -f /tmp/cic/config/.env ]]; then source /tmp/cic/config/.env; fi
|
||||||
#./start_tracker.sh -vv -c /usr/local/etc/cic-eth
|
#./start_tracker.sh -vv -c /usr/local/etc/cic-eth
|
||||||
./start_tracker.sh -vv
|
./start_tracker.sh -vv
|
||||||
# command: "/root/start_manager.sh head -vv"
|
# command: "/root/start_manager.sh head -vv"
|
||||||
|
|
||||||
|
|
||||||
cic-eth-dispatcher:
|
cic-eth-dispatcher:
|
||||||
image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/cic-eth:${TAG:-latest}
|
|
||||||
build:
|
build:
|
||||||
context: apps/cic-eth
|
context: apps/cic-eth
|
||||||
dockerfile: docker/Dockerfile
|
dockerfile: docker/Dockerfile
|
||||||
@@ -425,7 +350,7 @@ services:
|
|||||||
EXTRA_INDEX_URL: ${EXTRA_INDEX_URL:-https://pip.grassrootseconomics.net:8433}
|
EXTRA_INDEX_URL: ${EXTRA_INDEX_URL:-https://pip.grassrootseconomics.net:8433}
|
||||||
environment:
|
environment:
|
||||||
ETH_PROVIDER: http://eth:8545
|
ETH_PROVIDER: http://eth:8545
|
||||||
RPC_PROVIDER: http://eth:8545
|
RPC_HTTP_PROVIDER: http://eth:8545
|
||||||
DATABASE_USER: ${DATABASE_USER:-grassroots}
|
DATABASE_USER: ${DATABASE_USER:-grassroots}
|
||||||
DATABASE_HOST: ${DATABASE_HOST:-postgres}
|
DATABASE_HOST: ${DATABASE_HOST:-postgres}
|
||||||
DATABASE_PASSWORD: ${DATABASE_PASSWORD:-tralala}
|
DATABASE_PASSWORD: ${DATABASE_PASSWORD:-tralala}
|
||||||
@@ -442,25 +367,25 @@ services:
|
|||||||
TASKS_TRANSFER_CALLBACKS: $TASKS_TRANSFER_CALLBACKS
|
TASKS_TRANSFER_CALLBACKS: $TASKS_TRANSFER_CALLBACKS
|
||||||
DATABASE_DEBUG: ${DATABASE_DEBUG:-false}
|
DATABASE_DEBUG: ${DATABASE_DEBUG:-false}
|
||||||
#DATABASE_DEBUG: 1
|
#DATABASE_DEBUG: 1
|
||||||
restart: on-failure
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- eth
|
- eth
|
||||||
- postgres
|
- postgres
|
||||||
- redis
|
- redis
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
volumes:
|
volumes:
|
||||||
- contract-config:/tmp/cic/config/:ro
|
- contract-config:/tmp/cic/config/:ro
|
||||||
command:
|
command:
|
||||||
- /bin/bash
|
- /bin/bash
|
||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
if [[ -f /tmp/cic/config/env_reset ]]; then source /tmp/cic/config/env_reset; fi
|
if [[ -f /tmp/cic/config/.env ]]; then source /tmp/cic/config/.env; fi
|
||||||
./start_dispatcher.sh -q cic-eth -vv
|
./start_dispatcher.sh -q cic-eth -vv
|
||||||
# command: "/root/start_dispatcher.sh -q cic-eth -vv"
|
# command: "/root/start_dispatcher.sh -q cic-eth -vv"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cic-eth-retrier:
|
cic-eth-retrier:
|
||||||
image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/cic-eth:${TAG:-latest}
|
|
||||||
build:
|
build:
|
||||||
context: apps/cic-eth
|
context: apps/cic-eth
|
||||||
dockerfile: docker/Dockerfile
|
dockerfile: docker/Dockerfile
|
||||||
@@ -469,7 +394,7 @@ services:
|
|||||||
EXTRA_INDEX_URL: ${EXTRA_INDEX_URL:-https://pip.grassrootseconomics.net:8433}
|
EXTRA_INDEX_URL: ${EXTRA_INDEX_URL:-https://pip.grassrootseconomics.net:8433}
|
||||||
environment:
|
environment:
|
||||||
ETH_PROVIDER: http://eth:8545
|
ETH_PROVIDER: http://eth:8545
|
||||||
RPC_PROVIDER: http://eth:8545
|
RPC_HTTP_PROVIDER: http://eth:8545
|
||||||
DATABASE_USER: ${DATABASE_USER:-grassroots}
|
DATABASE_USER: ${DATABASE_USER:-grassroots}
|
||||||
DATABASE_HOST: ${DATABASE_HOST:-postgres}
|
DATABASE_HOST: ${DATABASE_HOST:-postgres}
|
||||||
DATABASE_PASSWORD: ${DATABASE_PASSWORD:-tralala}
|
DATABASE_PASSWORD: ${DATABASE_PASSWORD:-tralala}
|
||||||
@@ -488,25 +413,26 @@ services:
|
|||||||
CIC_TX_RETRY_DELAY: 60
|
CIC_TX_RETRY_DELAY: 60
|
||||||
BATCH_SIZE: ${RETRIER_BATCH_SIZE:-50}
|
BATCH_SIZE: ${RETRIER_BATCH_SIZE:-50}
|
||||||
#DATABASE_DEBUG: 1
|
#DATABASE_DEBUG: 1
|
||||||
restart: on-failure
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- eth
|
- eth
|
||||||
- postgres
|
- postgres
|
||||||
- redis
|
- redis
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
volumes:
|
volumes:
|
||||||
- contract-config:/tmp/cic/config/:ro
|
- contract-config:/tmp/cic/config/:ro
|
||||||
command:
|
command:
|
||||||
- /bin/bash
|
- /bin/bash
|
||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
if [[ -f /tmp/cic/config/env_reset ]]; then source /tmp/cic/config/env_reset; fi
|
if [[ -f /tmp/cic/config/.env ]]; then source /tmp/cic/config/.env; fi
|
||||||
./start_retry.sh -vv
|
./start_retry.sh -vv
|
||||||
# command: "/root/start_retry.sh -q cic-eth -vv"
|
# command: "/root/start_retry.sh -q cic-eth -vv"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cic-notify-tasker:
|
cic-notify-tasker:
|
||||||
image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/cic-notify:${TAG:-latest}
|
|
||||||
build:
|
build:
|
||||||
context: apps/cic-notify
|
context: apps/cic-notify
|
||||||
dockerfile: docker/Dockerfile
|
dockerfile: docker/Dockerfile
|
||||||
@@ -525,15 +451,18 @@ services:
|
|||||||
AFRICASTALKING_API_USERNAME: $AFRICASTALKING_API_USERNAME
|
AFRICASTALKING_API_USERNAME: $AFRICASTALKING_API_USERNAME
|
||||||
AFRICASTALKING_API_KEY: $AFRICASTALKING_API_KEY
|
AFRICASTALKING_API_KEY: $AFRICASTALKING_API_KEY
|
||||||
AFRICASTALKING_API_SENDER_ID: $AFRICASTALKING_API_SENDER_ID
|
AFRICASTALKING_API_SENDER_ID: $AFRICASTALKING_API_SENDER_ID
|
||||||
restart: unless-stopped
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
- redis
|
- redis
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
command: "/root/start_tasker.sh -q cic-notify -vv"
|
command: "/root/start_tasker.sh -q cic-notify -vv"
|
||||||
|
|
||||||
|
|
||||||
cic-meta-server:
|
cic-meta-server:
|
||||||
image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/cic-meta:${TAG:-latest}
|
profiles:
|
||||||
|
- custodial-meta
|
||||||
hostname: meta
|
hostname: meta
|
||||||
build:
|
build:
|
||||||
context: apps/cic-meta
|
context: apps/cic-meta
|
||||||
@@ -555,17 +484,20 @@ services:
|
|||||||
PGP_PUBLICKEY_ACTIVE_FILE: publickeys.asc
|
PGP_PUBLICKEY_ACTIVE_FILE: publickeys.asc
|
||||||
PGP_PUBLICKEY_ENCRYPT_FILE: publickeys.asc
|
PGP_PUBLICKEY_ENCRYPT_FILE: publickeys.asc
|
||||||
SCHEMA_SQL_PATH: scripts/initdb/server.postgres.sql
|
SCHEMA_SQL_PATH: scripts/initdb/server.postgres.sql
|
||||||
restart: on-failure
|
|
||||||
ports:
|
ports:
|
||||||
- ${HTTP_PORT_CIC_META:-63380}:8000
|
- ${HTTP_PORT_CIC_META:-63380}:8000
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
volumes:
|
volumes:
|
||||||
- ./apps/contract-migration/testdata/pgp/:/tmp/cic/pgp
|
- ./apps/contract-migration/testdata/pgp/:/tmp/cic/pgp
|
||||||
# command: "/root/start_server.sh -vv"
|
# command: "/root/start_server.sh -vv"
|
||||||
|
|
||||||
cic-user-ussd-server:
|
cic-user-ussd-server:
|
||||||
image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/cic-ussd:${TAG:-latest}
|
profiles:
|
||||||
|
- custodial-ussd
|
||||||
build:
|
build:
|
||||||
context: apps/cic-ussd
|
context: apps/cic-ussd
|
||||||
dockerfile: docker/Dockerfile
|
dockerfile: docker/Dockerfile
|
||||||
@@ -583,7 +515,6 @@ services:
|
|||||||
PGP_PASSPHRASE: merman
|
PGP_PASSPHRASE: merman
|
||||||
SERVER_PORT: 9000
|
SERVER_PORT: 9000
|
||||||
CIC_META_URL: ${CIC_META_URL:-http://meta:8000}
|
CIC_META_URL: ${CIC_META_URL:-http://meta:8000}
|
||||||
restart: on-failure
|
|
||||||
ports:
|
ports:
|
||||||
- ${HTTP_PORT_CIC_USER_USSD_SERVER:-63315}:9000
|
- ${HTTP_PORT_CIC_USER_USSD_SERVER:-63315}:9000
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -591,10 +522,14 @@ services:
|
|||||||
- redis
|
- redis
|
||||||
volumes:
|
volumes:
|
||||||
- ./apps/contract-migration/testdata/pgp/:/usr/src/secrets/
|
- ./apps/contract-migration/testdata/pgp/:/usr/src/secrets/
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
command: "/root/start_cic_user_ussd_server.sh -vv"
|
command: "/root/start_cic_user_ussd_server.sh -vv"
|
||||||
|
|
||||||
cic-user-server:
|
cic-user-server:
|
||||||
image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/cic-ussd:${TAG:-latest}
|
profiles:
|
||||||
|
- custodial-ussd
|
||||||
build:
|
build:
|
||||||
context: apps/cic-ussd
|
context: apps/cic-ussd
|
||||||
dockerfile: docker/Dockerfile
|
dockerfile: docker/Dockerfile
|
||||||
@@ -608,15 +543,18 @@ services:
|
|||||||
DATABASE_ENGINE: postgresql
|
DATABASE_ENGINE: postgresql
|
||||||
DATABASE_DRIVER: psycopg2
|
DATABASE_DRIVER: psycopg2
|
||||||
DATABASE_POOL_SIZE: 0
|
DATABASE_POOL_SIZE: 0
|
||||||
restart: on-failure
|
|
||||||
ports:
|
ports:
|
||||||
- ${HTTP_PORT_CIC_USER_SERVER:-63415}:9500
|
- ${HTTP_PORT_CIC_USER_SERVER:-63415}:9500
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
command: "/root/start_cic_user_server.sh -vv"
|
command: "/root/start_cic_user_server.sh -vv"
|
||||||
|
|
||||||
cic-user-tasker:
|
cic-user-tasker:
|
||||||
image: registry.gitlab.com/grassrootseconomics/cic-internal-integration/cic-ussd:${TAG:-latest}
|
profiles:
|
||||||
|
- custodial-ussd
|
||||||
build:
|
build:
|
||||||
context: apps/cic-ussd/
|
context: apps/cic-ussd/
|
||||||
dockerfile: docker/Dockerfile
|
dockerfile: docker/Dockerfile
|
||||||
@@ -634,10 +572,12 @@ services:
|
|||||||
CELERY_RESULT_URL: ${CELERY_BROKER_URL:-redis://redis}
|
CELERY_RESULT_URL: ${CELERY_BROKER_URL:-redis://redis}
|
||||||
PGP_PASSPHRASE: merman
|
PGP_PASSPHRASE: merman
|
||||||
CIC_META_URL: ${CIC_META_URL:-http://meta:8000}
|
CIC_META_URL: ${CIC_META_URL:-http://meta:8000}
|
||||||
restart: unless-stopped
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
- redis
|
- redis
|
||||||
volumes:
|
volumes:
|
||||||
- ./apps/contract-migration/testdata/pgp/:/usr/src/secrets/
|
- ./apps/contract-migration/testdata/pgp/:/usr/src/secrets/
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
command: "/root/start_cic_user_tasker.sh -q cic-ussd -vv"
|
command: "/root/start_cic_user_tasker.sh -q cic-ussd -vv"
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
#! /usr/bin/env sh
|
|
||||||
|
|
||||||
# Exit in case of error
|
|
||||||
set -e
|
|
||||||
|
|
||||||
TAG=${TAG?Variable not set} \
|
|
||||||
sh ./scripts/build.sh
|
|
||||||
|
|
||||||
docker-compose -f docker-compose.yml push
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#! /usr/bin/env sh
|
|
||||||
|
|
||||||
# Exit in case of error
|
|
||||||
set -e
|
|
||||||
|
|
||||||
TAG=${TAG?Variable not set} \
|
|
||||||
docker-compose \
|
|
||||||
-f docker-compose.yml \
|
|
||||||
build
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
docker run -t -v --rm cic-internal-integration_contract-config:/tmp/cic/config busybox cat /tmp/cic/config/env_reset
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#! /usr/bin/env bash
|
|
||||||
|
|
||||||
# Exit in case of error
|
|
||||||
set -e
|
|
||||||
|
|
||||||
docker-compose down -v --remove-orphans # Remove possibly previous broken stacks left hanging after an error
|
|
||||||
|
|
||||||
if [ $(uname -s) = "Linux" ]; then
|
|
||||||
echo "Remove __pycache__ files"
|
|
||||||
sudo find . -type d -name __pycache__ -exec rm -r {} \+
|
|
||||||
fi
|
|
||||||
|
|
||||||
docker-compose build
|
|
||||||
docker-compose up -d
|
|
||||||
docker-compose exec -T backend bash /app/tests-start.sh "$@"
|
|
||||||
Reference in New Issue
Block a user