Compare commits
44 Commits
spencer/me
...
lash/free-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
195fd6ea08
|
||
| a123122ed9 | |||
| 4c420bdcfd | |||
| 6601a3cdb6 | |||
| 1b948776ba | |||
| b67d1ac26a | |||
| e68f10fac5 | |||
| 6a86238cb6 | |||
| 5fcef25bdd | |||
| 3e526ba1ac | |||
| 52239e2e82 | |||
| a96508dac4 | |||
| 868a0e836c | |||
| dadab0a20b | |||
|
|
a4b00545d3 | ||
| b7d5c6799f | |||
| eef8bb2cf7 | |||
| cf96fee430 | |||
| 9740963431 | |||
|
|
08aef8804b | ||
|
|
a3c4932488 | ||
|
|
aa667951be | ||
|
|
8fef8c98db
|
||
|
|
54b857d286 | ||
|
|
b917070155
|
||
|
|
ae3a8de2d4
|
||
|
|
ceaafeb513
|
||
|
|
7cd2fc4622
|
||
|
|
c2459cfd65 | ||
|
|
e7102ff02d | ||
| a942c785f6 | |||
| 70704b09ec | |||
|
|
2144bec1ef
|
||
|
|
4897007bf9
|
||
|
|
a075c55957 | ||
|
|
6464f651ec | ||
|
|
5145282946 | ||
|
|
1e87f2ed31
|
||
|
|
c852f41d76 | ||
|
|
f8e68cff96 | ||
| 7027d77836 | |||
| d356f8167d | |||
| 753d21fe95 | |||
| a252195bdc |
@@ -16,6 +16,7 @@ import cic_base.config
|
|||||||
import cic_base.log
|
import cic_base.log
|
||||||
import cic_base.argparse
|
import cic_base.argparse
|
||||||
import cic_base.rpc
|
import cic_base.rpc
|
||||||
|
from cic_base.eth.syncer import chain_interface
|
||||||
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
|
||||||
from chainlib.chain import ChainSpec
|
from chainlib.chain import ChainSpec
|
||||||
@@ -28,10 +29,8 @@ from hexathon import (
|
|||||||
strip_0x,
|
strip_0x,
|
||||||
)
|
)
|
||||||
from chainsyncer.backend.sql import SQLBackend
|
from chainsyncer.backend.sql import SQLBackend
|
||||||
from chainsyncer.driver import (
|
from chainsyncer.driver.head import HeadSyncer
|
||||||
HeadSyncer,
|
from chainsyncer.driver.history import HistorySyncer
|
||||||
HistorySyncer,
|
|
||||||
)
|
|
||||||
from chainsyncer.db.models.base import SessionBase
|
from chainsyncer.db.models.base import SessionBase
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
@@ -113,10 +112,10 @@ def main():
|
|||||||
logg.info('resuming sync session {}'.format(syncer_backend))
|
logg.info('resuming sync session {}'.format(syncer_backend))
|
||||||
|
|
||||||
for syncer_backend in syncer_backends:
|
for syncer_backend in syncer_backends:
|
||||||
syncers.append(HistorySyncer(syncer_backend))
|
syncers.append(HistorySyncer(syncer_backend, chain_interface))
|
||||||
|
|
||||||
syncer_backend = SQLBackend.live(chain_spec, block_offset+1)
|
syncer_backend = SQLBackend.live(chain_spec, block_offset+1)
|
||||||
syncers.append(HeadSyncer(syncer_backend))
|
syncers.append(HeadSyncer(syncer_backend, chain_interface))
|
||||||
|
|
||||||
trusted_addresses_src = config.get('CIC_TRUST_ADDRESS')
|
trusted_addresses_src = config.get('CIC_TRUST_ADDRESS')
|
||||||
if trusted_addresses_src == None:
|
if trusted_addresses_src == None:
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
cic-base~=0.1.2b10
|
cic-base==0.1.3a3+build.984b5cff
|
||||||
alembic==1.4.2
|
alembic==1.4.2
|
||||||
confini~=0.3.6rc3
|
confini~=0.3.6rc3
|
||||||
uwsgi==2.0.19.1
|
uwsgi==2.0.19.1
|
||||||
moolb~=0.1.0
|
moolb~=0.1.0
|
||||||
cic-eth-registry~=0.5.5a4
|
cic-eth-registry~=0.5.6a1
|
||||||
SQLAlchemy==1.3.20
|
SQLAlchemy==1.3.20
|
||||||
semver==2.13.0
|
semver==2.13.0
|
||||||
psycopg2==2.8.6
|
psycopg2==2.8.6
|
||||||
celery==4.4.7
|
celery==4.4.7
|
||||||
redis==3.5.3
|
redis==3.5.3
|
||||||
chainsyncer[sql]~=0.0.2a4
|
chainsyncer[sql]~=0.0.3a3
|
||||||
|
erc20-faucet~=0.2.2a1
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
|
|
||||||
import alembic
|
import alembic
|
||||||
from alembic.config import Config as AlembicConfig
|
from alembic.config import Config as AlembicConfig
|
||||||
@@ -23,6 +24,8 @@ argparser = argparse.ArgumentParser()
|
|||||||
argparser.add_argument('-c', type=str, default=config_dir, help='config file')
|
argparser.add_argument('-c', type=str, default=config_dir, help='config file')
|
||||||
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('--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('--migrations-dir', dest='migrations_dir', default=migrationsdir, type=str, help='path to alembic migrations directory')
|
argparser.add_argument('--migrations-dir', dest='migrations_dir', default=migrationsdir, type=str, help='path to alembic migrations directory')
|
||||||
|
argparser.add_argument('--reset', action='store_true', help='downgrade before upgrading')
|
||||||
|
argparser.add_argument('-f', action='store_true', help='force action')
|
||||||
argparser.add_argument('-v', action='store_true', help='be verbose')
|
argparser.add_argument('-v', action='store_true', help='be verbose')
|
||||||
argparser.add_argument('-vv', action='store_true', help='be more verbose')
|
argparser.add_argument('-vv', action='store_true', help='be more verbose')
|
||||||
args = argparser.parse_args()
|
args = argparser.parse_args()
|
||||||
@@ -53,4 +56,10 @@ ac = AlembicConfig(os.path.join(migrations_dir, 'alembic.ini'))
|
|||||||
ac.set_main_option('sqlalchemy.url', dsn)
|
ac.set_main_option('sqlalchemy.url', dsn)
|
||||||
ac.set_main_option('script_location', migrations_dir)
|
ac.set_main_option('script_location', migrations_dir)
|
||||||
|
|
||||||
|
if args.reset:
|
||||||
|
if not args.f:
|
||||||
|
if not re.match(r'[yY][eE]?[sS]?', input('EEK! this will DELETE the existing db. are you sure??')):
|
||||||
|
logg.error('user chickened out on requested reset, bailing')
|
||||||
|
sys.exit(1)
|
||||||
|
alembic.command.downgrade(ac, 'base')
|
||||||
alembic.command.upgrade(ac, 'head')
|
alembic.command.upgrade(ac, 'head')
|
||||||
|
|||||||
@@ -6,6 +6,5 @@ sqlparse==0.4.1
|
|||||||
pytest-celery==0.0.0a1
|
pytest-celery==0.0.0a1
|
||||||
eth_tester==0.5.0b3
|
eth_tester==0.5.0b3
|
||||||
py-evm==0.3.0a20
|
py-evm==0.3.0a20
|
||||||
web3==5.12.2
|
cic_base[full]==0.1.3a3+build.984b5cff
|
||||||
cic-eth-registry~=0.5.5a3
|
sarafu-faucet~=0.0.4a1
|
||||||
cic-base[full]==0.1.2b8
|
|
||||||
|
|||||||
@@ -3,31 +3,29 @@
|
|||||||
APP_NAME: cic-eth
|
APP_NAME: cic-eth
|
||||||
DOCKERFILE_PATH: $APP_NAME/docker/Dockerfile
|
DOCKERFILE_PATH: $APP_NAME/docker/Dockerfile
|
||||||
|
|
||||||
.cic_eth_changes_target:
|
.cic_eth_mr_changes_target:
|
||||||
rules:
|
rules:
|
||||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
#changes:
|
changes:
|
||||||
#- $CONTEXT/$APP_NAME/**/*
|
- $CONTEXT/$APP_NAME/**/*
|
||||||
when: always
|
when: always
|
||||||
|
|
||||||
build-mr-cic-eth:
|
build-mr-cic-eth:
|
||||||
extends:
|
extends:
|
||||||
- .cic_eth_variables
|
- .cic_eth_variables
|
||||||
- .cic_eth_changes_target
|
- .cic_eth_mr_changes_target
|
||||||
- .py_build_target_test
|
- .py_build_target_test
|
||||||
|
|
||||||
test-mr-cic-eth:
|
test-mr-cic-eth:
|
||||||
extends:
|
extends:
|
||||||
- .cic_eth_variables
|
- .cic_eth_variables
|
||||||
- .cic_eth_changes_target
|
- .cic_eth_mr_changes_target
|
||||||
stage: test
|
stage: test
|
||||||
image: $CI_REGISTRY_IMAGE/$APP_NAME-test:latest
|
image: $IMAGE_TAG_BASE
|
||||||
script:
|
script:
|
||||||
- cd apps/$APP_NAME/
|
- cd apps/$APP_NAME/
|
||||||
- pytest -x --cov=cic_eth --cov-fail-under=90 --cov-report term-missing tests
|
- pytest -x --cov=cic_eth --cov-fail-under=90 --cov-report term-missing tests
|
||||||
needs: ["build-mr-cic-eth"]
|
|
||||||
|
|
||||||
build-push-cic-eth:
|
build-push-cic-eth:
|
||||||
extends:
|
extends:
|
||||||
- .py_build_push
|
- .py_build_push
|
||||||
- .cic_eth_variables
|
|
||||||
|
|||||||
2
apps/cic-eth/MANIFEST.in
Normal file
2
apps/cic-eth/MANIFEST.in
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
include *requirements.txt
|
||||||
|
|
||||||
5
apps/cic-eth/admin_requirements.txt
Normal file
5
apps/cic-eth/admin_requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
SQLAlchemy==1.3.20
|
||||||
|
cic-eth-registry~=0.5.6a1
|
||||||
|
hexathon~=0.0.1a7
|
||||||
|
chainqueue~=0.0.2b5
|
||||||
|
eth-erc20==0.0.10a2
|
||||||
@@ -5,4 +5,3 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from .api_task import Api
|
from .api_task import Api
|
||||||
from .api_admin import AdminApi
|
|
||||||
|
|||||||
@@ -562,13 +562,13 @@ class AdminApi:
|
|||||||
tx['source_token_symbol'] = source_token.symbol
|
tx['source_token_symbol'] = source_token.symbol
|
||||||
o = erc20_c.balance_of(tx['source_token'], tx['sender'], sender_address=self.call_address)
|
o = erc20_c.balance_of(tx['source_token'], tx['sender'], sender_address=self.call_address)
|
||||||
r = self.rpc.do(o)
|
r = self.rpc.do(o)
|
||||||
tx['sender_token_balance'] = erc20_c.parse_balance_of(r)
|
tx['sender_token_balance'] = erc20_c.parse_balance(r)
|
||||||
|
|
||||||
if destination_token != None:
|
if destination_token != None:
|
||||||
tx['destination_token_symbol'] = destination_token.symbol
|
tx['destination_token_symbol'] = destination_token.symbol
|
||||||
o = erc20_c.balance_of(tx['destination_token'], tx['recipient'], sender_address=self.call_address)
|
o = erc20_c.balance_of(tx['destination_token'], tx['recipient'], sender_address=self.call_address)
|
||||||
r = self.rpc.do(o)
|
r = self.rpc.do(o)
|
||||||
tx['recipient_token_balance'] = erc20_c.parse_balance_of(r)
|
tx['recipient_token_balance'] = erc20_c.parse_balance(r)
|
||||||
#tx['recipient_token_balance'] = destination_token.function('balanceOf')(tx['recipient']).call()
|
#tx['recipient_token_balance'] = destination_token.function('balanceOf')(tx['recipient']).call()
|
||||||
|
|
||||||
# TODO: this can mean either not subitted or culled, need to check other txs with same nonce to determine which
|
# TODO: this can mean either not subitted or culled, need to check other txs with same nonce to determine which
|
||||||
@@ -8,11 +8,10 @@ import logging
|
|||||||
|
|
||||||
# external imports
|
# external imports
|
||||||
import celery
|
import celery
|
||||||
from cic_eth_registry import CICRegistry
|
|
||||||
from chainlib.chain import ChainSpec
|
from chainlib.chain import ChainSpec
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from cic_eth.db.enum import LockEnum
|
from cic_eth.enum import LockEnum
|
||||||
|
|
||||||
app = celery.current_app
|
app = celery.current_app
|
||||||
|
|
||||||
@@ -204,6 +203,82 @@ class Api:
|
|||||||
# return t
|
# return t
|
||||||
|
|
||||||
|
|
||||||
|
def transfer_from(self, from_address, to_address, value, token_symbol, spender_address):
|
||||||
|
"""Executes a chain of celery tasks that performs a transfer of ERC20 tokens by one address on behalf of another address to a third party.
|
||||||
|
|
||||||
|
:param from_address: Ethereum address of sender
|
||||||
|
:type from_address: str, 0x-hex
|
||||||
|
:param to_address: Ethereum address of recipient
|
||||||
|
:type to_address: str, 0x-hex
|
||||||
|
:param value: Estimated return from conversion
|
||||||
|
:type value: int
|
||||||
|
:param token_symbol: ERC20 token symbol of token to send
|
||||||
|
:type token_symbol: str
|
||||||
|
:param spender_address: Ethereum address of recipient
|
||||||
|
:type spender_address: str, 0x-hex
|
||||||
|
:returns: uuid of root task
|
||||||
|
:rtype: celery.Task
|
||||||
|
"""
|
||||||
|
s_check = celery.signature(
|
||||||
|
'cic_eth.admin.ctrl.check_lock',
|
||||||
|
[
|
||||||
|
[token_symbol],
|
||||||
|
self.chain_spec.asdict(),
|
||||||
|
LockEnum.QUEUE,
|
||||||
|
from_address,
|
||||||
|
],
|
||||||
|
queue=self.queue,
|
||||||
|
)
|
||||||
|
s_nonce = celery.signature(
|
||||||
|
'cic_eth.eth.nonce.reserve_nonce',
|
||||||
|
[
|
||||||
|
self.chain_spec.asdict(),
|
||||||
|
from_address,
|
||||||
|
],
|
||||||
|
queue=self.queue,
|
||||||
|
)
|
||||||
|
s_tokens = celery.signature(
|
||||||
|
'cic_eth.eth.erc20.resolve_tokens_by_symbol',
|
||||||
|
[
|
||||||
|
self.chain_spec.asdict(),
|
||||||
|
],
|
||||||
|
queue=self.queue,
|
||||||
|
)
|
||||||
|
s_allow = celery.signature(
|
||||||
|
'cic_eth.eth.erc20.check_allowance',
|
||||||
|
[
|
||||||
|
from_address,
|
||||||
|
value,
|
||||||
|
self.chain_spec.asdict(),
|
||||||
|
spender_address,
|
||||||
|
],
|
||||||
|
queue=self.queue,
|
||||||
|
)
|
||||||
|
s_transfer = celery.signature(
|
||||||
|
'cic_eth.eth.erc20.transfer_from',
|
||||||
|
[
|
||||||
|
from_address,
|
||||||
|
to_address,
|
||||||
|
value,
|
||||||
|
self.chain_spec.asdict(),
|
||||||
|
spender_address,
|
||||||
|
],
|
||||||
|
queue=self.queue,
|
||||||
|
)
|
||||||
|
s_tokens.link(s_allow)
|
||||||
|
s_nonce.link(s_tokens)
|
||||||
|
s_check.link(s_nonce)
|
||||||
|
if self.callback_param != None:
|
||||||
|
s_transfer.link(self.callback_success)
|
||||||
|
s_allow.link(s_transfer).on_error(self.callback_error)
|
||||||
|
else:
|
||||||
|
s_allow.link(s_transfer)
|
||||||
|
|
||||||
|
t = s_check.apply_async(queue=self.queue)
|
||||||
|
return t
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def transfer(self, from_address, to_address, value, token_symbol):
|
def transfer(self, from_address, to_address, value, token_symbol):
|
||||||
"""Executes a chain of celery tasks that performs a transfer of ERC20 tokens from one address to another.
|
"""Executes a chain of celery tasks that performs a transfer of ERC20 tokens from one address to another.
|
||||||
|
|
||||||
|
|||||||
@@ -1,158 +1 @@
|
|||||||
# standard imports
|
from cic_eth.enum import *
|
||||||
import enum
|
|
||||||
|
|
||||||
|
|
||||||
@enum.unique
|
|
||||||
class StatusBits(enum.IntEnum):
|
|
||||||
"""Individual bit flags that are combined to define the state and legacy of a queued transaction
|
|
||||||
|
|
||||||
"""
|
|
||||||
QUEUED = 0x01 # transaction should be sent to network
|
|
||||||
IN_NETWORK = 0x08 # transaction is in network
|
|
||||||
|
|
||||||
DEFERRED = 0x10 # an attempt to send the transaction to network has failed
|
|
||||||
GAS_ISSUES = 0x20 # transaction is pending sender account gas funding
|
|
||||||
|
|
||||||
LOCAL_ERROR = 0x100 # errors that originate internally from the component
|
|
||||||
NODE_ERROR = 0x200 # errors originating in the node (invalid RLP input...)
|
|
||||||
NETWORK_ERROR = 0x400 # errors that originate from the network (REVERT)
|
|
||||||
UNKNOWN_ERROR = 0x800 # unclassified errors (the should not occur)
|
|
||||||
|
|
||||||
FINAL = 0x1000 # transaction processing has completed
|
|
||||||
OBSOLETE = 0x2000 # transaction has been replaced by a different transaction with higher fee
|
|
||||||
MANUAL = 0x8000 # transaction processing has been manually overridden
|
|
||||||
|
|
||||||
|
|
||||||
@enum.unique
|
|
||||||
class StatusEnum(enum.IntEnum):
|
|
||||||
"""
|
|
||||||
|
|
||||||
- Inactive, not finalized. (<0)
|
|
||||||
* PENDING: The initial state of a newly added transaction record. No action has been performed on this transaction yet.
|
|
||||||
* SENDFAIL: The transaction was not received by the node.
|
|
||||||
* RETRY: The transaction is queued for a new send attempt after previously failing.
|
|
||||||
* READYSEND: The transaction is queued for its first send attempt
|
|
||||||
* OBSOLETED: A new transaction with the same nonce and higher gas has been sent to network.
|
|
||||||
* WAITFORGAS: The transaction is on hold pending gas funding.
|
|
||||||
- Active state: (==0)
|
|
||||||
* SENT: The transaction has been sent to the mempool.
|
|
||||||
- Inactive, finalized. (>0)
|
|
||||||
* FUBAR: Unknown error occurred and transaction is abandoned. Manual intervention needed.
|
|
||||||
* CANCELLED: The transaction was sent, but was not mined and has disappered from the mempool. This usually follows a transaction being obsoleted.
|
|
||||||
* OVERRIDDEN: Transaction has been manually overriden.
|
|
||||||
* REJECTED: The transaction was rejected by the node.
|
|
||||||
* REVERTED: The transaction was mined, but exception occurred during EVM execution. (Block number will be set)
|
|
||||||
* SUCCESS: THe transaction was successfully mined. (Block number will be set)
|
|
||||||
|
|
||||||
"""
|
|
||||||
PENDING = 0
|
|
||||||
|
|
||||||
SENDFAIL = StatusBits.DEFERRED | StatusBits.LOCAL_ERROR
|
|
||||||
RETRY = StatusBits.QUEUED | StatusBits.DEFERRED
|
|
||||||
READYSEND = StatusBits.QUEUED
|
|
||||||
|
|
||||||
OBSOLETED = StatusBits.OBSOLETE | StatusBits.IN_NETWORK
|
|
||||||
|
|
||||||
WAITFORGAS = StatusBits.GAS_ISSUES
|
|
||||||
|
|
||||||
SENT = StatusBits.IN_NETWORK
|
|
||||||
FUBAR = StatusBits.FINAL | StatusBits.UNKNOWN_ERROR
|
|
||||||
CANCELLED = StatusBits.IN_NETWORK | StatusBits.FINAL | StatusBits.OBSOLETE
|
|
||||||
OVERRIDDEN = StatusBits.FINAL | StatusBits.OBSOLETE | StatusBits.MANUAL
|
|
||||||
|
|
||||||
REJECTED = StatusBits.NODE_ERROR | StatusBits.FINAL
|
|
||||||
REVERTED = StatusBits.IN_NETWORK | StatusBits.FINAL | StatusBits.NETWORK_ERROR
|
|
||||||
SUCCESS = StatusBits.IN_NETWORK | StatusBits.FINAL
|
|
||||||
|
|
||||||
|
|
||||||
@enum.unique
|
|
||||||
class LockEnum(enum.IntEnum):
|
|
||||||
"""
|
|
||||||
STICKY: When set, reset is not possible
|
|
||||||
CREATE: Disable creation of accounts
|
|
||||||
SEND: Disable sending to network
|
|
||||||
QUEUE: Disable queueing new or modified transactions
|
|
||||||
"""
|
|
||||||
STICKY=1
|
|
||||||
INIT=2
|
|
||||||
CREATE=4
|
|
||||||
SEND=8
|
|
||||||
QUEUE=16
|
|
||||||
QUERY=32
|
|
||||||
ALL=int(0xfffffffffffffffe)
|
|
||||||
|
|
||||||
|
|
||||||
def status_str(v, bits_only=False):
|
|
||||||
"""Render a human-readable string describing the status
|
|
||||||
|
|
||||||
If the bit field exactly matches a StatusEnum value, the StatusEnum label will be returned.
|
|
||||||
|
|
||||||
If a StatusEnum cannot be matched, the string will be postfixed with "*", unless explicitly instructed to return bit field labels only.
|
|
||||||
|
|
||||||
:param v: Status bit field
|
|
||||||
:type v: number
|
|
||||||
:param bits_only: Only render individual bit labels.
|
|
||||||
:type bits_only: bool
|
|
||||||
:returns: Status string
|
|
||||||
:rtype: str
|
|
||||||
"""
|
|
||||||
s = ''
|
|
||||||
if not bits_only:
|
|
||||||
try:
|
|
||||||
s = StatusEnum(v).name
|
|
||||||
return s
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if v == 0:
|
|
||||||
return 'NONE'
|
|
||||||
|
|
||||||
for i in range(16):
|
|
||||||
b = (1 << i)
|
|
||||||
if (b & 0xffff) & v:
|
|
||||||
n = StatusBits(b).name
|
|
||||||
if len(s) > 0:
|
|
||||||
s += ','
|
|
||||||
s += n
|
|
||||||
if not bits_only:
|
|
||||||
s += '*'
|
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
def all_errors():
|
|
||||||
"""Bit mask of all error states
|
|
||||||
|
|
||||||
:returns: Error flags
|
|
||||||
:rtype: number
|
|
||||||
"""
|
|
||||||
return StatusBits.LOCAL_ERROR | StatusBits.NODE_ERROR | StatusBits.NETWORK_ERROR | StatusBits.UNKNOWN_ERROR
|
|
||||||
|
|
||||||
|
|
||||||
def is_error_status(v):
|
|
||||||
"""Check if value is an error state
|
|
||||||
|
|
||||||
:param v: Status bit field
|
|
||||||
:type v: number
|
|
||||||
:returns: True if error
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
|
||||||
return bool(v & all_errors())
|
|
||||||
|
|
||||||
|
|
||||||
def dead():
|
|
||||||
"""Bit mask defining whether a transaction is still likely to be processed on the network.
|
|
||||||
|
|
||||||
:returns: Bit mask
|
|
||||||
:rtype: number
|
|
||||||
"""
|
|
||||||
return StatusBits.FINAL | StatusBits.OBSOLETE
|
|
||||||
|
|
||||||
|
|
||||||
def is_alive(v):
|
|
||||||
"""Check if transaction is still likely to be processed on the network.
|
|
||||||
|
|
||||||
The contingency of "likely" refers to the case a transaction has been obsoleted after sent to the network, but the network still confirms the obsoleted transaction. The return value of this method will not change as a result of this, BUT the state itself will (as the FINAL bit will be set).
|
|
||||||
|
|
||||||
:returns:
|
|
||||||
"""
|
|
||||||
return bool(v & dead() == 0)
|
|
||||||
|
|||||||
158
apps/cic-eth/cic_eth/enum.py
Normal file
158
apps/cic-eth/cic_eth/enum.py
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
# standard imports
|
||||||
|
import enum
|
||||||
|
|
||||||
|
|
||||||
|
@enum.unique
|
||||||
|
class StatusBits(enum.IntEnum):
|
||||||
|
"""Individual bit flags that are combined to define the state and legacy of a queued transaction
|
||||||
|
|
||||||
|
"""
|
||||||
|
QUEUED = 0x01 # transaction should be sent to network
|
||||||
|
IN_NETWORK = 0x08 # transaction is in network
|
||||||
|
|
||||||
|
DEFERRED = 0x10 # an attempt to send the transaction to network has failed
|
||||||
|
GAS_ISSUES = 0x20 # transaction is pending sender account gas funding
|
||||||
|
|
||||||
|
LOCAL_ERROR = 0x100 # errors that originate internally from the component
|
||||||
|
NODE_ERROR = 0x200 # errors originating in the node (invalid RLP input...)
|
||||||
|
NETWORK_ERROR = 0x400 # errors that originate from the network (REVERT)
|
||||||
|
UNKNOWN_ERROR = 0x800 # unclassified errors (the should not occur)
|
||||||
|
|
||||||
|
FINAL = 0x1000 # transaction processing has completed
|
||||||
|
OBSOLETE = 0x2000 # transaction has been replaced by a different transaction with higher fee
|
||||||
|
MANUAL = 0x8000 # transaction processing has been manually overridden
|
||||||
|
|
||||||
|
|
||||||
|
@enum.unique
|
||||||
|
class StatusEnum(enum.IntEnum):
|
||||||
|
"""
|
||||||
|
|
||||||
|
- Inactive, not finalized. (<0)
|
||||||
|
* PENDING: The initial state of a newly added transaction record. No action has been performed on this transaction yet.
|
||||||
|
* SENDFAIL: The transaction was not received by the node.
|
||||||
|
* RETRY: The transaction is queued for a new send attempt after previously failing.
|
||||||
|
* READYSEND: The transaction is queued for its first send attempt
|
||||||
|
* OBSOLETED: A new transaction with the same nonce and higher gas has been sent to network.
|
||||||
|
* WAITFORGAS: The transaction is on hold pending gas funding.
|
||||||
|
- Active state: (==0)
|
||||||
|
* SENT: The transaction has been sent to the mempool.
|
||||||
|
- Inactive, finalized. (>0)
|
||||||
|
* FUBAR: Unknown error occurred and transaction is abandoned. Manual intervention needed.
|
||||||
|
* CANCELLED: The transaction was sent, but was not mined and has disappered from the mempool. This usually follows a transaction being obsoleted.
|
||||||
|
* OVERRIDDEN: Transaction has been manually overriden.
|
||||||
|
* REJECTED: The transaction was rejected by the node.
|
||||||
|
* REVERTED: The transaction was mined, but exception occurred during EVM execution. (Block number will be set)
|
||||||
|
* SUCCESS: THe transaction was successfully mined. (Block number will be set)
|
||||||
|
|
||||||
|
"""
|
||||||
|
PENDING = 0
|
||||||
|
|
||||||
|
SENDFAIL = StatusBits.DEFERRED | StatusBits.LOCAL_ERROR
|
||||||
|
RETRY = StatusBits.QUEUED | StatusBits.DEFERRED
|
||||||
|
READYSEND = StatusBits.QUEUED
|
||||||
|
|
||||||
|
OBSOLETED = StatusBits.OBSOLETE | StatusBits.IN_NETWORK
|
||||||
|
|
||||||
|
WAITFORGAS = StatusBits.GAS_ISSUES
|
||||||
|
|
||||||
|
SENT = StatusBits.IN_NETWORK
|
||||||
|
FUBAR = StatusBits.FINAL | StatusBits.UNKNOWN_ERROR
|
||||||
|
CANCELLED = StatusBits.IN_NETWORK | StatusBits.FINAL | StatusBits.OBSOLETE
|
||||||
|
OVERRIDDEN = StatusBits.FINAL | StatusBits.OBSOLETE | StatusBits.MANUAL
|
||||||
|
|
||||||
|
REJECTED = StatusBits.NODE_ERROR | StatusBits.FINAL
|
||||||
|
REVERTED = StatusBits.IN_NETWORK | StatusBits.FINAL | StatusBits.NETWORK_ERROR
|
||||||
|
SUCCESS = StatusBits.IN_NETWORK | StatusBits.FINAL
|
||||||
|
|
||||||
|
|
||||||
|
@enum.unique
|
||||||
|
class LockEnum(enum.IntEnum):
|
||||||
|
"""
|
||||||
|
STICKY: When set, reset is not possible
|
||||||
|
CREATE: Disable creation of accounts
|
||||||
|
SEND: Disable sending to network
|
||||||
|
QUEUE: Disable queueing new or modified transactions
|
||||||
|
"""
|
||||||
|
STICKY=1
|
||||||
|
INIT=2
|
||||||
|
CREATE=4
|
||||||
|
SEND=8
|
||||||
|
QUEUE=16
|
||||||
|
QUERY=32
|
||||||
|
ALL=int(0xfffffffffffffffe)
|
||||||
|
|
||||||
|
|
||||||
|
def status_str(v, bits_only=False):
|
||||||
|
"""Render a human-readable string describing the status
|
||||||
|
|
||||||
|
If the bit field exactly matches a StatusEnum value, the StatusEnum label will be returned.
|
||||||
|
|
||||||
|
If a StatusEnum cannot be matched, the string will be postfixed with "*", unless explicitly instructed to return bit field labels only.
|
||||||
|
|
||||||
|
:param v: Status bit field
|
||||||
|
:type v: number
|
||||||
|
:param bits_only: Only render individual bit labels.
|
||||||
|
:type bits_only: bool
|
||||||
|
:returns: Status string
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
s = ''
|
||||||
|
if not bits_only:
|
||||||
|
try:
|
||||||
|
s = StatusEnum(v).name
|
||||||
|
return s
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if v == 0:
|
||||||
|
return 'NONE'
|
||||||
|
|
||||||
|
for i in range(16):
|
||||||
|
b = (1 << i)
|
||||||
|
if (b & 0xffff) & v:
|
||||||
|
n = StatusBits(b).name
|
||||||
|
if len(s) > 0:
|
||||||
|
s += ','
|
||||||
|
s += n
|
||||||
|
if not bits_only:
|
||||||
|
s += '*'
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def all_errors():
|
||||||
|
"""Bit mask of all error states
|
||||||
|
|
||||||
|
:returns: Error flags
|
||||||
|
:rtype: number
|
||||||
|
"""
|
||||||
|
return StatusBits.LOCAL_ERROR | StatusBits.NODE_ERROR | StatusBits.NETWORK_ERROR | StatusBits.UNKNOWN_ERROR
|
||||||
|
|
||||||
|
|
||||||
|
def is_error_status(v):
|
||||||
|
"""Check if value is an error state
|
||||||
|
|
||||||
|
:param v: Status bit field
|
||||||
|
:type v: number
|
||||||
|
:returns: True if error
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
return bool(v & all_errors())
|
||||||
|
|
||||||
|
|
||||||
|
def dead():
|
||||||
|
"""Bit mask defining whether a transaction is still likely to be processed on the network.
|
||||||
|
|
||||||
|
:returns: Bit mask
|
||||||
|
:rtype: number
|
||||||
|
"""
|
||||||
|
return StatusBits.FINAL | StatusBits.OBSOLETE
|
||||||
|
|
||||||
|
|
||||||
|
def is_alive(v):
|
||||||
|
"""Check if transaction is still likely to be processed on the network.
|
||||||
|
|
||||||
|
The contingency of "likely" refers to the case a transaction has been obsoleted after sent to the network, but the network still confirms the obsoleted transaction. The return value of this method will not change as a result of this, BUT the state itself will (as the FINAL bit will be set).
|
||||||
|
|
||||||
|
:returns:
|
||||||
|
"""
|
||||||
|
return bool(v & dead() == 0)
|
||||||
@@ -80,3 +80,8 @@ class SignerError(SeppukuError):
|
|||||||
class RoleAgencyError(SeppukuError):
|
class RoleAgencyError(SeppukuError):
|
||||||
"""Exception raise when a role cannot perform its function. This is a critical exception
|
"""Exception raise when a role cannot perform its function. This is a critical exception
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class YouAreBrokeError(Exception):
|
||||||
|
"""Exception raised when a value transfer is attempted without access to sufficient funds
|
||||||
|
"""
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ from cic_eth.error import (
|
|||||||
TokenCountError,
|
TokenCountError,
|
||||||
PermanentTxError,
|
PermanentTxError,
|
||||||
OutOfGasError,
|
OutOfGasError,
|
||||||
|
YouAreBrokeError,
|
||||||
)
|
)
|
||||||
from cic_eth.queue.tx import register_tx
|
from cic_eth.queue.tx import register_tx
|
||||||
from cic_eth.eth.gas import (
|
from cic_eth.eth.gas import (
|
||||||
@@ -71,6 +72,117 @@ def balance(tokens, holder_address, chain_spec_dict):
|
|||||||
return tokens
|
return tokens
|
||||||
|
|
||||||
|
|
||||||
|
@celery_app.task(bind=True)
|
||||||
|
def check_allowance(self, tokens, holder_address, value, chain_spec_dict, spender_address):
|
||||||
|
"""Best-effort verification that the allowance for a transfer from spend is sufficient.
|
||||||
|
|
||||||
|
:raises YouAreBrokeError: If allowance is insufficient
|
||||||
|
|
||||||
|
:param tokens: Token addresses
|
||||||
|
:type tokens: list of str, 0x-hex
|
||||||
|
:param holder_address: Token holder address
|
||||||
|
:type holder_address: str, 0x-hex
|
||||||
|
:param value: Amount of token, in 'wei'
|
||||||
|
:type value: int
|
||||||
|
:param chain_str: Chain spec string representation
|
||||||
|
:type chain_str: str
|
||||||
|
:param spender_address: Address of account spending on behalf of holder
|
||||||
|
:type spender_address: str, 0x-hex
|
||||||
|
:return: Token list as passed to task
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
logg.debug('tokens {}'.format(tokens))
|
||||||
|
if len(tokens) != 1:
|
||||||
|
raise TokenCountError
|
||||||
|
t = tokens[0]
|
||||||
|
chain_spec = ChainSpec.from_dict(chain_spec_dict)
|
||||||
|
|
||||||
|
rpc = RPCConnection.connect(chain_spec, 'default')
|
||||||
|
|
||||||
|
caller_address = ERC20Token.caller_address
|
||||||
|
c = ERC20(chain_spec)
|
||||||
|
o = c.allowance(t['address'], holder_address, spender_address, sender_address=caller_address)
|
||||||
|
r = rpc.do(o)
|
||||||
|
allowance = c.parse_allowance(r)
|
||||||
|
if allowance < value:
|
||||||
|
errstr = 'allowance {} insufficent to transfer {} {} by {} on behalf of {}'.format(allowance, value, t['symbol'], spender_address, holder_address)
|
||||||
|
logg.error(errstr)
|
||||||
|
raise YouAreBrokeError(errstr)
|
||||||
|
|
||||||
|
return tokens
|
||||||
|
|
||||||
|
|
||||||
|
@celery_app.task(bind=True, base=CriticalSQLAlchemyAndSignerTask)
|
||||||
|
def transfer_from(self, tokens, holder_address, receiver_address, value, chain_spec_dict, spender_address):
|
||||||
|
"""Transfer ERC20 tokens between addresses
|
||||||
|
|
||||||
|
First argument is a list of tokens, to enable the task to be chained to the symbol to token address resolver function. However, it accepts only one token as argument.
|
||||||
|
|
||||||
|
:param tokens: Token addresses
|
||||||
|
:type tokens: list of str, 0x-hex
|
||||||
|
:param holder_address: Token holder address
|
||||||
|
:type holder_address: str, 0x-hex
|
||||||
|
:param receiver_address: Token receiver address
|
||||||
|
:type receiver_address: str, 0x-hex
|
||||||
|
:param value: Amount of token, in 'wei'
|
||||||
|
:type value: int
|
||||||
|
:param chain_str: Chain spec string representation
|
||||||
|
:type chain_str: str
|
||||||
|
:param spender_address: Address of account spending on behalf of holder
|
||||||
|
:type spender_address: str, 0x-hex
|
||||||
|
:raises TokenCountError: Either none or more then one tokens have been passed as tokens argument
|
||||||
|
:return: Transaction hash for tranfer operation
|
||||||
|
:rtype: str, 0x-hex
|
||||||
|
"""
|
||||||
|
# we only allow one token, one transfer
|
||||||
|
logg.debug('tokens {}'.format(tokens))
|
||||||
|
if len(tokens) != 1:
|
||||||
|
raise TokenCountError
|
||||||
|
t = tokens[0]
|
||||||
|
chain_spec = ChainSpec.from_dict(chain_spec_dict)
|
||||||
|
queue = self.request.delivery_info.get('routing_key')
|
||||||
|
|
||||||
|
rpc = RPCConnection.connect(chain_spec, 'default')
|
||||||
|
rpc_signer = RPCConnection.connect(chain_spec, 'signer')
|
||||||
|
|
||||||
|
session = self.create_session()
|
||||||
|
nonce_oracle = CustodialTaskNonceOracle(holder_address, self.request.root_id, session=session)
|
||||||
|
gas_oracle = self.create_gas_oracle(rpc, MaxGasOracle.gas)
|
||||||
|
c = ERC20(chain_spec, signer=rpc_signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle)
|
||||||
|
try:
|
||||||
|
(tx_hash_hex, tx_signed_raw_hex) = c.transfer_from(t['address'], spender_address, holder_address, receiver_address, value, tx_format=TxFormat.RLP_SIGNED)
|
||||||
|
except FileNotFoundError as e:
|
||||||
|
raise SignerError(e)
|
||||||
|
except ConnectionError as e:
|
||||||
|
raise SignerError(e)
|
||||||
|
|
||||||
|
|
||||||
|
rpc_signer.disconnect()
|
||||||
|
rpc.disconnect()
|
||||||
|
|
||||||
|
cache_task = 'cic_eth.eth.erc20.cache_transfer_from_data'
|
||||||
|
|
||||||
|
register_tx(tx_hash_hex, tx_signed_raw_hex, chain_spec, queue, cache_task=cache_task, session=session)
|
||||||
|
session.commit()
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
gas_pair = gas_oracle.get_gas(tx_signed_raw_hex)
|
||||||
|
gas_budget = gas_pair[0] * gas_pair[1]
|
||||||
|
logg.debug('transfer tx {} {} {}'.format(tx_hash_hex, queue, gas_budget))
|
||||||
|
|
||||||
|
s = create_check_gas_task(
|
||||||
|
[tx_signed_raw_hex],
|
||||||
|
chain_spec,
|
||||||
|
holder_address,
|
||||||
|
gas_budget,
|
||||||
|
[tx_hash_hex],
|
||||||
|
queue,
|
||||||
|
)
|
||||||
|
s.apply_async()
|
||||||
|
return tx_hash_hex
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@celery_app.task(bind=True, base=CriticalSQLAlchemyAndSignerTask)
|
@celery_app.task(bind=True, base=CriticalSQLAlchemyAndSignerTask)
|
||||||
def transfer(self, tokens, holder_address, receiver_address, value, chain_spec_dict):
|
def transfer(self, tokens, holder_address, receiver_address, value, chain_spec_dict):
|
||||||
"""Transfer ERC20 tokens between addresses
|
"""Transfer ERC20 tokens between addresses
|
||||||
@@ -232,6 +344,7 @@ def resolve_tokens_by_symbol(self, token_symbols, chain_spec_dict):
|
|||||||
logg.debug('token {}'.format(token_address))
|
logg.debug('token {}'.format(token_address))
|
||||||
tokens.append({
|
tokens.append({
|
||||||
'address': token_address,
|
'address': token_address,
|
||||||
|
'symbol': token_symbol,
|
||||||
'converters': [],
|
'converters': [],
|
||||||
})
|
})
|
||||||
rpc.disconnect()
|
rpc.disconnect()
|
||||||
@@ -279,6 +392,48 @@ def cache_transfer_data(
|
|||||||
return (tx_hash_hex, cache_id)
|
return (tx_hash_hex, cache_id)
|
||||||
|
|
||||||
|
|
||||||
|
@celery_app.task(base=CriticalSQLAlchemyTask)
|
||||||
|
def cache_transfer_from_data(
|
||||||
|
tx_hash_hex,
|
||||||
|
tx_signed_raw_hex,
|
||||||
|
chain_spec_dict,
|
||||||
|
):
|
||||||
|
"""Helper function for otx_cache_transfer_from
|
||||||
|
|
||||||
|
:param tx_hash_hex: Transaction hash
|
||||||
|
:type tx_hash_hex: str, 0x-hex
|
||||||
|
:param tx: Signed raw transaction
|
||||||
|
:type tx: str, 0x-hex
|
||||||
|
:returns: Transaction hash and id of cache element in storage backend, respectively
|
||||||
|
:rtype: tuple
|
||||||
|
"""
|
||||||
|
chain_spec = ChainSpec.from_dict(chain_spec_dict)
|
||||||
|
tx_signed_raw_bytes = bytes.fromhex(strip_0x(tx_signed_raw_hex))
|
||||||
|
tx = unpack(tx_signed_raw_bytes, chain_spec)
|
||||||
|
|
||||||
|
tx_data = ERC20.parse_transfer_from_request(tx['data'])
|
||||||
|
spender_address = tx_data[0]
|
||||||
|
recipient_address = tx_data[1]
|
||||||
|
token_value = tx_data[2]
|
||||||
|
|
||||||
|
session = SessionBase.create_session()
|
||||||
|
tx_cache = TxCache(
|
||||||
|
tx_hash_hex,
|
||||||
|
tx['from'],
|
||||||
|
recipient_address,
|
||||||
|
tx['to'],
|
||||||
|
tx['to'],
|
||||||
|
token_value,
|
||||||
|
token_value,
|
||||||
|
session=session,
|
||||||
|
)
|
||||||
|
session.add(tx_cache)
|
||||||
|
session.commit()
|
||||||
|
cache_id = tx_cache.id
|
||||||
|
session.close()
|
||||||
|
return (tx_hash_hex, cache_id)
|
||||||
|
|
||||||
|
|
||||||
@celery_app.task(base=CriticalSQLAlchemyTask)
|
@celery_app.task(base=CriticalSQLAlchemyTask)
|
||||||
def cache_approve_data(
|
def cache_approve_data(
|
||||||
tx_hash_hex,
|
tx_hash_hex,
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
# third-party imports
|
# external imports
|
||||||
import pytest
|
import pytest
|
||||||
import confini
|
import confini
|
||||||
|
|
||||||
script_dir = os.path.dirname(os.path.realpath(__file__))
|
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||||
root_dir = os.path.dirname(script_dir)
|
root_dir = os.path.dirname(os.path.dirname(script_dir))
|
||||||
logg = logging.getLogger(__file__)
|
logg = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
@pytest.fixture(scope='session')
|
||||||
@@ -37,7 +37,8 @@ def init_database(
|
|||||||
database_engine,
|
database_engine,
|
||||||
):
|
):
|
||||||
|
|
||||||
rootdir = os.path.dirname(os.path.dirname(__file__))
|
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
rootdir = os.path.dirname(os.path.dirname(script_dir))
|
||||||
dbdir = os.path.join(rootdir, 'cic_eth', 'db')
|
dbdir = os.path.join(rootdir, 'cic_eth', 'db')
|
||||||
migrationsdir = os.path.join(dbdir, 'migrations', load_config.get('DATABASE_ENGINE'))
|
migrationsdir = os.path.join(dbdir, 'migrations', load_config.get('DATABASE_ENGINE'))
|
||||||
if not os.path.isdir(migrationsdir):
|
if not os.path.isdir(migrationsdir):
|
||||||
@@ -12,7 +12,7 @@ from chainlib.eth.constant import ZERO_ADDRESS
|
|||||||
from chainlib.eth.address import is_checksum_address
|
from chainlib.eth.address import is_checksum_address
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from cic_eth.api import AdminApi
|
from cic_eth.api.admin import AdminApi
|
||||||
from cic_eth.db.enum import LockEnum
|
from cic_eth.db.enum import LockEnum
|
||||||
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
logging.basicConfig(level=logging.WARNING)
|
||||||
|
|||||||
@@ -1,136 +0,0 @@
|
|||||||
# standard imports
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import logging
|
|
||||||
import argparse
|
|
||||||
import json
|
|
||||||
|
|
||||||
# third-party imports
|
|
||||||
import web3
|
|
||||||
import confini
|
|
||||||
import celery
|
|
||||||
from json.decoder import JSONDecodeError
|
|
||||||
from cic_registry.chain import ChainSpec
|
|
||||||
|
|
||||||
# local imports
|
|
||||||
from cic_eth.db import dsn_from_config
|
|
||||||
from cic_eth.db.models.base import SessionBase
|
|
||||||
from cic_eth.eth.util import unpack_signed_raw_tx
|
|
||||||
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
|
||||||
logg = logging.getLogger()
|
|
||||||
|
|
||||||
rootdir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
|
||||||
dbdir = os.path.join(rootdir, 'cic_eth', 'db')
|
|
||||||
migrationsdir = os.path.join(dbdir, 'migrations')
|
|
||||||
|
|
||||||
config_dir = os.path.join('/usr/local/etc/cic-eth')
|
|
||||||
|
|
||||||
argparser = argparse.ArgumentParser()
|
|
||||||
argparser.add_argument('-c', type=str, default=config_dir, help='config file')
|
|
||||||
argparser.add_argument('-i', '--chain-spec', dest='i', type=str, help='chain spec')
|
|
||||||
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-eth', help='queue name for worker tasks')
|
|
||||||
argparser.add_argument('-v', action='store_true', help='be verbose')
|
|
||||||
argparser.add_argument('-vv', action='store_true', help='be more verbose')
|
|
||||||
args = argparser.parse_args()
|
|
||||||
|
|
||||||
if args.vv:
|
|
||||||
logging.getLogger().setLevel(logging.DEBUG)
|
|
||||||
elif args.v:
|
|
||||||
logging.getLogger().setLevel(logging.INFO)
|
|
||||||
|
|
||||||
config = confini.Config(args.c, args.env_prefix)
|
|
||||||
config.process()
|
|
||||||
args_override = {
|
|
||||||
'CIC_CHAIN_SPEC': getattr(args, 'i'),
|
|
||||||
}
|
|
||||||
config.censor('PASSWORD', 'DATABASE')
|
|
||||||
config.censor('PASSWORD', 'SSL')
|
|
||||||
logg.debug('config:\n{}'.format(config))
|
|
||||||
|
|
||||||
dsn = dsn_from_config(config)
|
|
||||||
SessionBase.connect(dsn)
|
|
||||||
|
|
||||||
celery_app = celery.Celery(backend=config.get('CELERY_RESULT_URL'), broker=config.get('CELERY_BROKER_URL'))
|
|
||||||
queue = args.q
|
|
||||||
|
|
||||||
re_something = r'^/something/?'
|
|
||||||
|
|
||||||
chain_spec = ChainSpec.from_chain_str(config.get('CIC_CHAIN_SPEC'))
|
|
||||||
|
|
||||||
|
|
||||||
def process_something(session, env):
|
|
||||||
r = re.match(re_something, env.get('PATH_INFO'))
|
|
||||||
if not r:
|
|
||||||
return None
|
|
||||||
|
|
||||||
#if env.get('CONTENT_TYPE') != 'application/json':
|
|
||||||
# raise AttributeError('content type')
|
|
||||||
|
|
||||||
#if env.get('REQUEST_METHOD') != 'POST':
|
|
||||||
# raise AttributeError('method')
|
|
||||||
|
|
||||||
#post_data = json.load(env.get('wsgi.input'))
|
|
||||||
|
|
||||||
#return ('text/plain', 'foo'.encode('utf-8'),)
|
|
||||||
|
|
||||||
|
|
||||||
# uwsgi application
|
|
||||||
def application(env, start_response):
|
|
||||||
|
|
||||||
for k in env.keys():
|
|
||||||
logg.debug('env {} {}'.format(k, env[k]))
|
|
||||||
|
|
||||||
headers = []
|
|
||||||
content = b''
|
|
||||||
err = None
|
|
||||||
|
|
||||||
session = SessionBase.create_session()
|
|
||||||
for handler in [
|
|
||||||
process_something,
|
|
||||||
]:
|
|
||||||
try:
|
|
||||||
r = handler(session, env)
|
|
||||||
except AttributeError as e:
|
|
||||||
logg.error('handler fail attribute {}'.format(e))
|
|
||||||
err = '400 Impertinent request'
|
|
||||||
break
|
|
||||||
except JSONDecodeError as e:
|
|
||||||
logg.error('handler fail json {}'.format(e))
|
|
||||||
err = '400 Invalid data format'
|
|
||||||
break
|
|
||||||
except KeyError as e:
|
|
||||||
logg.error('handler fail key {}'.format(e))
|
|
||||||
err = '400 Invalid JSON'
|
|
||||||
break
|
|
||||||
except ValueError as e:
|
|
||||||
logg.error('handler fail value {}'.format(e))
|
|
||||||
err = '400 Invalid data'
|
|
||||||
break
|
|
||||||
except RuntimeError as e:
|
|
||||||
logg.error('task fail value {}'.format(e))
|
|
||||||
err = '500 Task failed, sorry I cannot tell you more'
|
|
||||||
break
|
|
||||||
if r != None:
|
|
||||||
(mime_type, content) = r
|
|
||||||
break
|
|
||||||
session.close()
|
|
||||||
|
|
||||||
if err != None:
|
|
||||||
headers.append(('Content-Type', 'text/plain, charset=UTF-8',))
|
|
||||||
start_response(err, headers)
|
|
||||||
session.close()
|
|
||||||
return [content]
|
|
||||||
|
|
||||||
headers.append(('Content-Length', str(len(content))),)
|
|
||||||
headers.append(('Access-Control-Allow-Origin', '*',));
|
|
||||||
|
|
||||||
if len(content) == 0:
|
|
||||||
headers.append(('Content-Type', 'text/plain, charset=UTF-8',))
|
|
||||||
start_response('404 Looked everywhere, sorry', headers)
|
|
||||||
else:
|
|
||||||
headers.append(('Content-Type', mime_type,))
|
|
||||||
start_response('200 OK', headers)
|
|
||||||
|
|
||||||
return [content]
|
|
||||||
@@ -15,6 +15,7 @@ import cic_base.config
|
|||||||
import cic_base.log
|
import cic_base.log
|
||||||
import cic_base.argparse
|
import cic_base.argparse
|
||||||
import cic_base.rpc
|
import cic_base.rpc
|
||||||
|
from cic_base.eth.syncer import chain_interface
|
||||||
from cic_eth_registry.error import UnknownContractError
|
from cic_eth_registry.error import UnknownContractError
|
||||||
from chainlib.chain import ChainSpec
|
from chainlib.chain import ChainSpec
|
||||||
from chainlib.eth.constant import ZERO_ADDRESS
|
from chainlib.eth.constant import ZERO_ADDRESS
|
||||||
@@ -26,10 +27,8 @@ from hexathon import (
|
|||||||
strip_0x,
|
strip_0x,
|
||||||
)
|
)
|
||||||
from chainsyncer.backend.sql import SQLBackend
|
from chainsyncer.backend.sql import SQLBackend
|
||||||
from chainsyncer.driver import (
|
from chainsyncer.driver.head import HeadSyncer
|
||||||
HeadSyncer,
|
from chainsyncer.driver.history import HistorySyncer
|
||||||
HistorySyncer,
|
|
||||||
)
|
|
||||||
from chainsyncer.db.models.base import SessionBase
|
from chainsyncer.db.models.base import SessionBase
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
@@ -80,6 +79,7 @@ chain_spec = ChainSpec.from_chain_str(config.get('CIC_CHAIN_SPEC'))
|
|||||||
cic_base.rpc.setup(chain_spec, config.get('ETH_PROVIDER'))
|
cic_base.rpc.setup(chain_spec, config.get('ETH_PROVIDER'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
# connect to celery
|
# connect to celery
|
||||||
celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL'))
|
celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL'))
|
||||||
@@ -121,11 +121,11 @@ def main():
|
|||||||
|
|
||||||
for syncer_backend in syncer_backends:
|
for syncer_backend in syncer_backends:
|
||||||
try:
|
try:
|
||||||
syncers.append(HistorySyncer(syncer_backend))
|
syncers.append(HistorySyncer(syncer_backend, chain_interface))
|
||||||
logg.info('Initializing HISTORY syncer on backend {}'.format(syncer_backend))
|
logg.info('Initializing HISTORY syncer on backend {}'.format(syncer_backend))
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
logg.info('Initializing HEAD syncer on backend {}'.format(syncer_backend))
|
logg.info('Initializing HEAD syncer on backend {}'.format(syncer_backend))
|
||||||
syncers.append(HeadSyncer(syncer_backend))
|
syncers.append(HeadSyncer(syncer_backend, chain_interface))
|
||||||
|
|
||||||
connect_registry(rpc, chain_spec, config.get('CIC_REGISTRY_ADDRESS'))
|
connect_registry(rpc, chain_spec, config.get('CIC_REGISTRY_ADDRESS'))
|
||||||
|
|
||||||
|
|||||||
@@ -12,10 +12,8 @@ import confini
|
|||||||
import celery
|
import celery
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from cic_eth.api import (
|
from cic_eth.api import Api
|
||||||
Api,
|
from cic_eth.api.admin import AdminApi
|
||||||
AdminApi,
|
|
||||||
)
|
|
||||||
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
logging.basicConfig(level=logging.WARNING)
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from chainlib.chain import ChainSpec
|
|||||||
from chainlib.eth.connection import EthHTTPConnection
|
from chainlib.eth.connection import EthHTTPConnection
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from cic_eth.api.api_admin import AdminApi
|
from cic_eth.api.admin import AdminApi
|
||||||
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
logging.basicConfig(level=logging.WARNING)
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ from chainlib.chain import ChainSpec
|
|||||||
from xdg.BaseDirectory import xdg_config_home
|
from xdg.BaseDirectory import xdg_config_home
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from cic_eth.api import AdminApi
|
from cic_eth.api.admin import AdminApi
|
||||||
from cic_eth.db import dsn_from_config
|
from cic_eth.db import dsn_from_config
|
||||||
from cic_eth.db.models.base import SessionBase
|
from cic_eth.db.models.base import SessionBase
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ from chainlib.eth.connection import EthHTTPConnection
|
|||||||
from hexathon import add_0x
|
from hexathon import add_0x
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from cic_eth.api import AdminApi
|
from cic_eth.api.admin import AdminApi
|
||||||
from cic_eth.db.enum import (
|
from cic_eth.db.enum import (
|
||||||
StatusEnum,
|
StatusEnum,
|
||||||
status_str,
|
status_str,
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import semver
|
|||||||
|
|
||||||
version = (
|
version = (
|
||||||
0,
|
0,
|
||||||
11,
|
12,
|
||||||
0,
|
0,
|
||||||
'beta.16',
|
'alpha.1',
|
||||||
)
|
)
|
||||||
|
|
||||||
version_object = semver.VersionInfo(
|
version_object = semver.VersionInfo(
|
||||||
|
|||||||
@@ -8,12 +8,14 @@ RUN apt-get update && \
|
|||||||
#RUN python -m venv venv && . venv/bin/activate
|
#RUN python -m venv venv && . venv/bin/activate
|
||||||
|
|
||||||
ARG pip_extra_index_url_flag='--index https://pypi.org/simple --extra-index-url https://pip.grassrootseconomics.net:8433'
|
ARG pip_extra_index_url_flag='--index https://pypi.org/simple --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"
|
||||||
RUN /usr/local/bin/python -m pip install --upgrade pip
|
RUN /usr/local/bin/python -m pip install --upgrade pip
|
||||||
RUN pip install semver
|
RUN pip install semver
|
||||||
|
|
||||||
# TODO use a packaging style that lets us copy requirments only ie. pip-tools
|
|
||||||
COPY cic-eth/ .
|
COPY cic-eth/ .
|
||||||
RUN pip install $pip_extra_index_url_flag .
|
RUN pip install --extra-index-url $GITLAB_PYTHON_REGISTRY \
|
||||||
|
--extra-index-url $EXTRA_INDEX_URL .
|
||||||
|
|
||||||
# --- TEST IMAGE ---
|
# --- TEST IMAGE ---
|
||||||
FROM python:3.8.6-slim-buster as test
|
FROM python:3.8.6-slim-buster as test
|
||||||
@@ -32,8 +34,12 @@ COPY --from=compile /usr/local/lib/python3.8/site-packages/ \
|
|||||||
# COPY --from=compile /usr/src/cic-eth/ .
|
# COPY --from=compile /usr/src/cic-eth/ .
|
||||||
# RUN . venv/bin/activate
|
# RUN . venv/bin/activate
|
||||||
|
|
||||||
|
ARG EXTRA_INDEX_URL="https://pip.grassrootseconomics.net:8433"
|
||||||
|
ARG GITLAB_PYTHON_REGISTRY="https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple"
|
||||||
|
|
||||||
COPY cic-eth/test_requirements.txt .
|
COPY cic-eth/test_requirements.txt .
|
||||||
RUN pip install $pip_extra_index_url_flag -r test_requirements.txt
|
RUN pip install --extra-index-url $GITLAB_PYTHON_REGISTRY \
|
||||||
|
--extra-index-url $EXTRA_INDEX_URL -r test_requirements.txt
|
||||||
|
|
||||||
COPY cic-eth .
|
COPY cic-eth .
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,3 @@
|
|||||||
cic-base~=0.1.2b15
|
|
||||||
celery==4.4.7
|
celery==4.4.7
|
||||||
crypto-dev-signer~=0.4.14b3
|
chainlib~=0.0.5a1
|
||||||
confini~=0.3.6rc3
|
|
||||||
cic-eth-registry~=0.5.5a7
|
|
||||||
redis==3.5.3
|
|
||||||
alembic==1.4.2
|
|
||||||
websockets==8.1
|
|
||||||
requests~=2.24.0
|
|
||||||
eth_accounts_index~=0.0.11a12
|
|
||||||
erc20-transfer-authorization~=0.3.1a7
|
|
||||||
uWSGI==2.0.19.1
|
|
||||||
semver==2.13.0
|
semver==2.13.0
|
||||||
websocket-client==0.57.0
|
|
||||||
moolb~=0.1.1b2
|
|
||||||
eth-address-index~=0.1.1a11
|
|
||||||
chainlib~=0.0.3rc2
|
|
||||||
hexathon~=0.0.1a7
|
|
||||||
chainsyncer[sql]==0.0.2a5
|
|
||||||
chainqueue~=0.0.2b3
|
|
||||||
sarafu-faucet~=0.0.3a3
|
|
||||||
erc20-faucet~=0.2.1a5
|
|
||||||
coincurve==15.0.0
|
|
||||||
potaahto~=0.0.1a2
|
|
||||||
pycryptodome==3.10.1
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
import alembic
|
import alembic
|
||||||
from alembic.config import Config as AlembicConfig
|
from alembic.config import Config as AlembicConfig
|
||||||
@@ -23,6 +25,8 @@ argparser = argparse.ArgumentParser()
|
|||||||
argparser.add_argument('-c', type=str, default=config_dir, help='config file')
|
argparser.add_argument('-c', type=str, default=config_dir, help='config file')
|
||||||
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('--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('--migrations-dir', dest='migrations_dir', default=migrationsdir, type=str, help='path to alembic migrations directory')
|
argparser.add_argument('--migrations-dir', dest='migrations_dir', default=migrationsdir, type=str, help='path to alembic migrations directory')
|
||||||
|
argparser.add_argument('--reset', action='store_true', help='downgrade before upgrading')
|
||||||
|
argparser.add_argument('-f', action='store_true', help='force action')
|
||||||
argparser.add_argument('-v', action='store_true', help='be verbose')
|
argparser.add_argument('-v', action='store_true', help='be verbose')
|
||||||
argparser.add_argument('-vv', action='store_true', help='be more verbose')
|
argparser.add_argument('-vv', action='store_true', help='be more verbose')
|
||||||
args = argparser.parse_args()
|
args = argparser.parse_args()
|
||||||
@@ -53,4 +57,10 @@ ac = AlembicConfig(os.path.join(migrations_dir, 'alembic.ini'))
|
|||||||
ac.set_main_option('sqlalchemy.url', dsn)
|
ac.set_main_option('sqlalchemy.url', dsn)
|
||||||
ac.set_main_option('script_location', migrations_dir)
|
ac.set_main_option('script_location', migrations_dir)
|
||||||
|
|
||||||
|
if args.reset:
|
||||||
|
if not args.f:
|
||||||
|
if not re.match(r'[yY][eE]?[sS]?', input('EEK! this will DELETE the existing db. are you sure??')):
|
||||||
|
logg.error('user chickened out on requested reset, bailing')
|
||||||
|
sys.exit(1)
|
||||||
|
alembic.command.downgrade(ac, 'base')
|
||||||
alembic.command.upgrade(ac, 'head')
|
alembic.command.upgrade(ac, 'head')
|
||||||
|
|||||||
7
apps/cic-eth/services_requirements.txt
Normal file
7
apps/cic-eth/services_requirements.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
chainsyncer[sql]~=0.0.3a3
|
||||||
|
chainqueue~=0.0.2b5
|
||||||
|
alembic==1.4.2
|
||||||
|
confini~=0.3.6rc4
|
||||||
|
redis==3.5.3
|
||||||
|
hexathon~=0.0.1a7
|
||||||
|
pycryptodome==3.10.1
|
||||||
@@ -45,16 +45,16 @@ scripts =
|
|||||||
[options.entry_points]
|
[options.entry_points]
|
||||||
console_scripts =
|
console_scripts =
|
||||||
# daemons
|
# daemons
|
||||||
cic-eth-taskerd = cic_eth.runnable.daemons.tasker:main
|
cic-eth-taskerd = cic_eth.runnable.daemons.tasker:main [services]
|
||||||
cic-eth-trackerd = cic_eth.runnable.daemons.tracker:main
|
cic-eth-trackerd = cic_eth.runnable.daemons.tracker:main [services]
|
||||||
cic-eth-dispatcherd = cic_eth.runnable.daemons.dispatcher:main
|
cic-eth-dispatcherd = cic_eth.runnable.daemons.dispatcher:main [services]
|
||||||
cic-eth-retrierd = cic_eth.runnable.daemons.retry:main
|
cic-eth-retrierd = cic_eth.runnable.daemons.retry:main [services]
|
||||||
# tools
|
# tools
|
||||||
cic-eth-create = cic_eth.runnable.create:main
|
cic-eth-create = cic_eth.runnable.create:main [tools]
|
||||||
cic-eth-inspect = cic_eth.runnable.view:main
|
cic-eth-inspect = cic_eth.runnable.view:main [tools]
|
||||||
cic-eth-ctl = cic_eth.runnable.ctrl:main
|
cic-eth-ctl = cic_eth.runnable.ctrl:main [tools]
|
||||||
cic-eth-info = cic_eth.runnable.info:main
|
cic-eth-info = cic_eth.runnable.info:main [tools]
|
||||||
# TODO: Merge this with ctl when subcmds sorted to submodules
|
# TODO: Merge this with ctl when subcmds sorted to submodules
|
||||||
cic-eth-tag = cic_eth.runnable.tag:main
|
cic-eth-tag = cic_eth.runnable.tag:main [tools]
|
||||||
cic-eth-resend = cic_eth.runnable.resend:main
|
cic-eth-resend = cic_eth.runnable.resend:main [tools]
|
||||||
cic-eth-transfer = cic_eth.runnable.transfer:main
|
cic-eth-transfer = cic_eth.runnable.transfer:main [tools]
|
||||||
|
|||||||
@@ -11,6 +11,41 @@ while True:
|
|||||||
requirements.append(l.rstrip())
|
requirements.append(l.rstrip())
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
admin_requirements = []
|
||||||
|
f = open('admin_requirements.txt', 'r')
|
||||||
|
while True:
|
||||||
|
l = f.readline()
|
||||||
|
if l == '':
|
||||||
|
break
|
||||||
|
admin_requirements.append(l.rstrip())
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
tools_requirements = []
|
||||||
|
f = open('tools_requirements.txt', 'r')
|
||||||
|
while True:
|
||||||
|
l = f.readline()
|
||||||
|
if l == '':
|
||||||
|
break
|
||||||
|
tools_requirements.append(l.rstrip())
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
services_requirements = []
|
||||||
|
f = open('services_requirements.txt', 'r')
|
||||||
|
while True:
|
||||||
|
l = f.readline()
|
||||||
|
if l == '':
|
||||||
|
break
|
||||||
|
services_requirements.append(l.rstrip())
|
||||||
|
f.close()
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
install_requires=requirements
|
install_requires=requirements,
|
||||||
|
extras_require = {
|
||||||
|
'tools': tools_requirements,
|
||||||
|
'admin_api': admin_requirements,
|
||||||
|
'services': services_requirements,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,5 +2,8 @@ pytest==6.0.1
|
|||||||
pytest-celery==0.0.0a1
|
pytest-celery==0.0.0a1
|
||||||
pytest-mock==3.3.1
|
pytest-mock==3.3.1
|
||||||
pytest-cov==2.10.1
|
pytest-cov==2.10.1
|
||||||
|
pytest-redis==2.0.0
|
||||||
|
redis==3.5.3
|
||||||
eth-tester==0.5.0b3
|
eth-tester==0.5.0b3
|
||||||
py-evm==0.3.0a20
|
py-evm==0.3.0a20
|
||||||
|
eth-erc20~=0.0.10a2
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ root_dir = os.path.dirname(script_dir)
|
|||||||
sys.path.insert(0, root_dir)
|
sys.path.insert(0, root_dir)
|
||||||
|
|
||||||
# assemble fixtures
|
# assemble fixtures
|
||||||
from tests.fixtures_config import *
|
from cic_eth.pytest.fixtures_config import *
|
||||||
from tests.fixtures_database import *
|
from cic_eth.pytest.fixtures_celery import *
|
||||||
from tests.fixtures_celery import *
|
from cic_eth.pytest.fixtures_database import *
|
||||||
from tests.fixtures_role import *
|
from cic_eth.pytest.fixtures_role import *
|
||||||
from tests.fixtures_contract import *
|
from cic_eth.pytest.fixtures_contract import *
|
||||||
from chainlib.eth.pytest import *
|
from chainlib.eth.pytest import *
|
||||||
from eth_contract_registry.pytest import *
|
from eth_contract_registry.pytest import *
|
||||||
from cic_eth_registry.pytest.fixtures_contracts import *
|
from cic_eth_registry.pytest.fixtures_contracts import *
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ from chainqueue.sql.query import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from cic_eth.api import AdminApi
|
from cic_eth.api.admin import AdminApi
|
||||||
from cic_eth.db.models.role import AccountRole
|
from cic_eth.db.models.role import AccountRole
|
||||||
from cic_eth.db.enum import LockEnum
|
from cic_eth.db.enum import LockEnum
|
||||||
from cic_eth.error import InitializationError
|
from cic_eth.error import InitializationError
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ from eth_erc20 import ERC20
|
|||||||
from cic_eth_registry import CICRegistry
|
from cic_eth_registry import CICRegistry
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from cic_eth.api.api_admin import AdminApi
|
from cic_eth.api.admin import AdminApi
|
||||||
from cic_eth.eth.gas import cache_gas_data
|
from cic_eth.eth.gas import cache_gas_data
|
||||||
from cic_eth.eth.erc20 import cache_transfer_data
|
from cic_eth.eth.erc20 import cache_transfer_data
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
from tests.fixtures_celery import *
|
from cic_eth.pytest.fixtures_celery import *
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ from chainlib.eth.tx import (
|
|||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from cic_eth.queue.tx import register_tx
|
from cic_eth.queue.tx import register_tx
|
||||||
|
from cic_eth.error import YouAreBrokeError
|
||||||
|
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
|
|
||||||
@@ -167,3 +168,101 @@ def test_erc20_approve_task(
|
|||||||
r = t.get_leaf()
|
r = t.get_leaf()
|
||||||
|
|
||||||
logg.debug('result {}'.format(r))
|
logg.debug('result {}'.format(r))
|
||||||
|
|
||||||
|
|
||||||
|
def test_erc20_transfer_from_task(
|
||||||
|
default_chain_spec,
|
||||||
|
foo_token,
|
||||||
|
agent_roles,
|
||||||
|
custodial_roles,
|
||||||
|
eth_signer,
|
||||||
|
eth_rpc,
|
||||||
|
init_database,
|
||||||
|
celery_session_worker,
|
||||||
|
token_roles,
|
||||||
|
):
|
||||||
|
|
||||||
|
token_object = {
|
||||||
|
'address': foo_token,
|
||||||
|
}
|
||||||
|
transfer_value = 100 * (10 ** 6)
|
||||||
|
|
||||||
|
nonce_oracle = RPCNonceOracle(token_roles['FOO_TOKEN_OWNER'], conn=eth_rpc)
|
||||||
|
c = ERC20(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle)
|
||||||
|
(tx_hash, o) = c.approve(foo_token, token_roles['FOO_TOKEN_OWNER'], agent_roles['ALICE'], transfer_value)
|
||||||
|
r = eth_rpc.do(o)
|
||||||
|
o = receipt(tx_hash)
|
||||||
|
r = eth_rpc.do(o)
|
||||||
|
assert r['status'] == 1
|
||||||
|
|
||||||
|
s_nonce = celery.signature(
|
||||||
|
'cic_eth.eth.nonce.reserve_nonce',
|
||||||
|
[
|
||||||
|
[token_object],
|
||||||
|
default_chain_spec.asdict(),
|
||||||
|
custodial_roles['FOO_TOKEN_GIFTER'],
|
||||||
|
],
|
||||||
|
queue=None,
|
||||||
|
)
|
||||||
|
s_transfer = celery.signature(
|
||||||
|
'cic_eth.eth.erc20.transfer_from',
|
||||||
|
[
|
||||||
|
custodial_roles['FOO_TOKEN_GIFTER'],
|
||||||
|
agent_roles['BOB'],
|
||||||
|
transfer_value,
|
||||||
|
default_chain_spec.asdict(),
|
||||||
|
agent_roles['ALICE'],
|
||||||
|
],
|
||||||
|
queue=None,
|
||||||
|
)
|
||||||
|
s_nonce.link(s_transfer)
|
||||||
|
t = s_nonce.apply_async()
|
||||||
|
r = t.get_leaf()
|
||||||
|
|
||||||
|
logg.debug('result {}'.format(r))
|
||||||
|
|
||||||
|
|
||||||
|
def test_erc20_allowance_check_task(
|
||||||
|
default_chain_spec,
|
||||||
|
foo_token,
|
||||||
|
agent_roles,
|
||||||
|
custodial_roles,
|
||||||
|
eth_signer,
|
||||||
|
eth_rpc,
|
||||||
|
init_database,
|
||||||
|
celery_session_worker,
|
||||||
|
token_roles,
|
||||||
|
):
|
||||||
|
|
||||||
|
token_object = {
|
||||||
|
'address': foo_token,
|
||||||
|
'symbol': 'FOO',
|
||||||
|
}
|
||||||
|
transfer_value = 100 * (10 ** 6)
|
||||||
|
|
||||||
|
s_check = celery.signature(
|
||||||
|
'cic_eth.eth.erc20.check_allowance',
|
||||||
|
[
|
||||||
|
[token_object],
|
||||||
|
custodial_roles['FOO_TOKEN_GIFTER'],
|
||||||
|
transfer_value,
|
||||||
|
default_chain_spec.asdict(),
|
||||||
|
agent_roles['ALICE']
|
||||||
|
],
|
||||||
|
queue=None,
|
||||||
|
)
|
||||||
|
t = s_check.apply_async()
|
||||||
|
with pytest.raises(YouAreBrokeError):
|
||||||
|
t.get()
|
||||||
|
|
||||||
|
nonce_oracle = RPCNonceOracle(token_roles['FOO_TOKEN_OWNER'], conn=eth_rpc)
|
||||||
|
c = ERC20(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle)
|
||||||
|
(tx_hash, o) = c.approve(foo_token, token_roles['FOO_TOKEN_OWNER'], agent_roles['ALICE'], transfer_value)
|
||||||
|
r = eth_rpc.do(o)
|
||||||
|
o = receipt(tx_hash)
|
||||||
|
r = eth_rpc.do(o)
|
||||||
|
assert r['status'] == 1
|
||||||
|
|
||||||
|
t = s_check.apply_async()
|
||||||
|
t.get()
|
||||||
|
assert t.successful()
|
||||||
|
|||||||
8
apps/cic-eth/tools_requirements.txt
Normal file
8
apps/cic-eth/tools_requirements.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
crypto-dev-signer~=0.4.14b6
|
||||||
|
chainqueue~=0.0.2b5
|
||||||
|
confini~=0.3.6rc4
|
||||||
|
cic-eth-registry~=0.5.6a1
|
||||||
|
redis==3.5.3
|
||||||
|
hexathon~=0.0.1a7
|
||||||
|
pycryptodome==3.10.1
|
||||||
|
pyxdg==0.27
|
||||||
@@ -147,7 +147,7 @@ function handleClientMergeGet(db, digest, keystore) {
|
|||||||
doh(e);
|
doh(e);
|
||||||
});
|
});
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
console.error('message', e);
|
console.error('mesage', e);
|
||||||
doh(e);
|
doh(e);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ async function startServer() {
|
|||||||
http.createServer(processRequest).listen(config.get('SERVER_PORT'));
|
http.createServer(processRequest).listen(config.get('SERVER_PORT'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const re_digest = /^([a-fA-F0-9]{64})\/?$/;
|
const re_digest = /^\/([a-fA-F0-9]{64})\/?$/;
|
||||||
function parseDigest(url) {
|
function parseDigest(url) {
|
||||||
const digest_test = url.match(re_digest);
|
const digest_test = url.match(re_digest);
|
||||||
if (digest_test === null) {
|
if (digest_test === null) {
|
||||||
@@ -96,42 +96,6 @@ function parseDigest(url) {
|
|||||||
return digest_test[1].toLowerCase();
|
return digest_test[1].toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getIds(url: string): Array<string> {
|
|
||||||
const params: Array<string> = url.split('?')[1].split('&');
|
|
||||||
let ids: Array<string> = [];
|
|
||||||
for (let param of params) {
|
|
||||||
const splitParam: Array<string> = param.split('=');
|
|
||||||
if (splitParam[0] === 'id') {
|
|
||||||
ids.push(parseDigest(splitParam[1]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ids;
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateResponseBody(digest: string, data: string | boolean): string {
|
|
||||||
let response = {
|
|
||||||
id: digest,
|
|
||||||
status: 0,
|
|
||||||
headers: {},
|
|
||||||
body: ''
|
|
||||||
}
|
|
||||||
if (typeof data === 'boolean' || data === undefined) {
|
|
||||||
response.body = `Metadata for identifier ${digest} not found!`;
|
|
||||||
response.status = 404;
|
|
||||||
response.headers = {"Content-Type": "text/plain"}
|
|
||||||
} else {
|
|
||||||
const responseContentLength = (new TextEncoder().encode(data)).length;
|
|
||||||
response.body = data;
|
|
||||||
response.status = 200;
|
|
||||||
response.headers = {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
"Content-Type": 'application/json',
|
|
||||||
"Content-Length": responseContentLength,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return JSON.stringify(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function processRequest(req, res) {
|
async function processRequest(req, res) {
|
||||||
let digest = undefined;
|
let digest = undefined;
|
||||||
const headers = {
|
const headers = {
|
||||||
@@ -155,16 +119,7 @@ async function processRequest(req, res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (req.url.includes('id')) {
|
digest = parseDigest(req.url);
|
||||||
if (req.method !== 'GET') {
|
|
||||||
res.writeHead(405, {"Content-Type": "text/plain"});
|
|
||||||
res.end();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
digest = getIds(req.url);
|
|
||||||
} else {
|
|
||||||
digest = parseDigest(req.url.substring(1));
|
|
||||||
}
|
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.error('digest error: ' + e)
|
console.error('digest error: ' + e)
|
||||||
res.writeHead(400, {"Content-Type": "text/plain"});
|
res.writeHead(400, {"Content-Type": "text/plain"});
|
||||||
@@ -207,24 +162,7 @@ async function processRequest(req, res) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'get:automerge:client':
|
case 'get:automerge:client':
|
||||||
if (digest instanceof Array) {
|
content = await handlers.handleClientMergeGet(db, digest, keystore);
|
||||||
let response = [];
|
|
||||||
for (let dg of digest) {
|
|
||||||
const metadata = await handlers.handleClientMergeGet(db, dg, keystore);
|
|
||||||
response.push(generateResponseBody(dg, metadata));
|
|
||||||
}
|
|
||||||
const responseContentLength = (new TextEncoder().encode(response.toString())).length;
|
|
||||||
res.writeHead(207, {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
"Content-Type": contentType,
|
|
||||||
"Content-Length": responseContentLength,
|
|
||||||
});
|
|
||||||
res.write(response.toString());
|
|
||||||
res.end();
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
content = await handlers.handleClientMergeGet(db, digest, keystore);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'post:automerge:server':
|
case 'post:automerge:server':
|
||||||
@@ -244,30 +182,13 @@ async function processRequest(req, res) {
|
|||||||
// break;
|
// break;
|
||||||
|
|
||||||
case 'get:automerge:none':
|
case 'get:automerge:none':
|
||||||
if (digest instanceof Array) {
|
r = await handlers.handleNoMergeGet(db, digest, keystore);
|
||||||
let response = [];
|
if (r == false) {
|
||||||
for (let dg of digest) {
|
res.writeHead(404, {"Content-Type": "text/plain"});
|
||||||
const metadata = await handlers.handleNoMergeGet(db, dg, keystore);
|
|
||||||
response.push(generateResponseBody(dg, metadata));
|
|
||||||
}
|
|
||||||
const responseContentLength = (new TextEncoder().encode(response.toString())).length;
|
|
||||||
res.writeHead(207, {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
"Content-Type": contentType,
|
|
||||||
"Content-Length": responseContentLength,
|
|
||||||
});
|
|
||||||
res.write(response.toString());
|
|
||||||
res.end();
|
res.end();
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
r = await handlers.handleNoMergeGet(db, digest, keystore);
|
|
||||||
if (r == false) {
|
|
||||||
res.writeHead(404, {"Content-Type": "text/plain"});
|
|
||||||
res.end();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
content = r;
|
|
||||||
}
|
}
|
||||||
|
content = r;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -284,7 +205,7 @@ async function processRequest(req, res) {
|
|||||||
|
|
||||||
if (content === undefined) {
|
if (content === undefined) {
|
||||||
console.error('empty content', data);
|
console.error('empty content', data);
|
||||||
res.writeHead(404, {"Content-Type": "text/plain"});
|
res.writeHead(400, {"Content-Type": "text/plain"});
|
||||||
res.end();
|
res.end();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import semver
|
|||||||
|
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
|
|
||||||
version = (0, 4, 0, 'alpha.5')
|
version = (0, 4, 0, 'alpha.7')
|
||||||
|
|
||||||
version_object = semver.VersionInfo(
|
version_object = semver.VersionInfo(
|
||||||
major=version[0],
|
major=version[0],
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
cic_base[full_graph]~=0.1.2a61
|
cic_base[full_graph]==0.1.3a3+build.984b5cff
|
||||||
|
|||||||
@@ -2,4 +2,3 @@ pytest~=6.0.1
|
|||||||
pytest-celery~=0.0.0a1
|
pytest-celery~=0.0.0a1
|
||||||
pytest-mock~=3.3.1
|
pytest-mock~=3.3.1
|
||||||
pysqlite3~=0.4.3
|
pysqlite3~=0.4.3
|
||||||
|
|
||||||
|
|||||||
@@ -294,6 +294,7 @@ def process_display_user_metadata(user: Account, display_key: str):
|
|||||||
preferred_language=user.preferred_language,
|
preferred_language=user.preferred_language,
|
||||||
full_name=absent,
|
full_name=absent,
|
||||||
gender=absent,
|
gender=absent,
|
||||||
|
age=absent,
|
||||||
location=absent,
|
location=absent,
|
||||||
products=absent
|
products=absent
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -127,6 +127,8 @@ def main():
|
|||||||
argv.append('--loglevel=INFO')
|
argv.append('--loglevel=INFO')
|
||||||
argv.append('-Q')
|
argv.append('-Q')
|
||||||
argv.append(args.q)
|
argv.append(args.q)
|
||||||
|
argv.append('-n')
|
||||||
|
argv.append(args.q)
|
||||||
|
|
||||||
current_app.worker_main(argv)
|
current_app.worker_main(argv)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
cic_base[full_graph]~=0.1.2b21
|
cic_base[full_graph]==0.1.3a3+build.984b5cff
|
||||||
cic-eth~=0.11.0b16
|
cic-eth~=0.12.0a1
|
||||||
cic-notify~=0.4.0a5
|
cic-notify~=0.4.0a7
|
||||||
cic-types~=0.1.0a11
|
cic-types~=0.1.0a11
|
||||||
|
|||||||
@@ -8,4 +8,4 @@ pytest-mock==3.3.1
|
|||||||
pytest-ordering==0.6
|
pytest-ordering==0.6
|
||||||
pytest-redis==2.0.0
|
pytest-redis==2.0.0
|
||||||
requests-mock==1.8.0
|
requests-mock==1.8.0
|
||||||
tavern==1.14.2
|
tavern==1.14.2
|
||||||
|
|||||||
40
apps/cic-ussd/tests/fixtures/integration.py
vendored
40
apps/cic-ussd/tests/fixtures/integration.py
vendored
@@ -124,46 +124,6 @@ def second_profile_management_session_id() -> str:
|
|||||||
return session_id()
|
return session_id()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
|
||||||
def first_account_change_given_name() -> str:
|
|
||||||
return fake.first_name()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
|
||||||
def second_account_change_given_name() -> str:
|
|
||||||
return fake.first_name()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
|
||||||
def first_account_change_family_name() -> str:
|
|
||||||
return fake.last_name()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
|
||||||
def second_account_change_family_name() -> str:
|
|
||||||
return fake.last_name()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
|
||||||
def first_account_change_location() -> str:
|
|
||||||
return fake.city()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
|
||||||
def second_account_change_location() -> str:
|
|
||||||
return fake.city()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
|
||||||
def first_account_change_product() -> str:
|
|
||||||
return fake.color_name()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
|
||||||
def second_account_change_product() -> str:
|
|
||||||
return fake.color_name()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
@pytest.fixture(scope='session')
|
||||||
def first_profile_management_session_id_1() -> str:
|
def first_profile_management_session_id_1() -> str:
|
||||||
return session_id()
|
return session_id()
|
||||||
|
|||||||
25
apps/cic-ussd/tests/integration/README.md
Normal file
25
apps/cic-ussd/tests/integration/README.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# INTEGRATION TESTING
|
||||||
|
|
||||||
|
This folder contains integration tests.
|
||||||
|
|
||||||
|
## OVERVIEW
|
||||||
|
|
||||||
|
There are four files defining the integration tests.
|
||||||
|
|
||||||
|
* **test_account_creation**: Tests account sign up process.
|
||||||
|
* **test_transactions**: Tests transactions between two accounts.
|
||||||
|
* **test_profile_management**: Tests that account metadata can be edited.
|
||||||
|
* **test_account_management**: Tests that account management functionalities are intact.
|
||||||
|
|
||||||
|
## REQUIREMENTS
|
||||||
|
|
||||||
|
In order to run the transaction tests, please ensure that the faucet amount is set to a non-zero value, ideally `50000000`
|
||||||
|
which is the value set in the config file `.config/test/integration.ini`.
|
||||||
|
|
||||||
|
This implies setting the `DEV_FAUCET_AMOUNT` to a non-zero value before bringing up the contract-migration image:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
export DEV_FAUCET_AMOUNT=50000000
|
||||||
|
RUN_MASK=1 docker-compose up contract-migration
|
||||||
|
RUN_MASK=2 docker-compose up contract-migration
|
||||||
|
```
|
||||||
@@ -214,12 +214,13 @@ stages:
|
|||||||
status_code:
|
status_code:
|
||||||
- 200
|
- 200
|
||||||
headers:
|
headers:
|
||||||
Content-Length: '28'
|
Content-Length: '51'
|
||||||
Content-Type: "text/plain"
|
Content-Type: "text/plain"
|
||||||
verify_response_with:
|
verify_response_with:
|
||||||
function: ext.validator:validate_response
|
function: ext.validator:validate_response
|
||||||
extra_kwargs:
|
extra_kwargs:
|
||||||
expected_response: "CON Enter first name\n0. Back"
|
expected_response: "CON Balance {gift_value} {token_symbol}\n1. Send\n2. My Account\n3. Help"
|
||||||
|
delay_before: 10
|
||||||
|
|
||||||
- name: Pin number confirmation [{second_account_pin_number} - second account]
|
- name: Pin number confirmation [{second_account_pin_number} - second account]
|
||||||
request:
|
request:
|
||||||
@@ -232,227 +233,6 @@ stages:
|
|||||||
headers:
|
headers:
|
||||||
content-type: "application/x-www-form-urlencoded"
|
content-type: "application/x-www-form-urlencoded"
|
||||||
method: POST
|
method: POST
|
||||||
response:
|
|
||||||
status_code:
|
|
||||||
- 200
|
|
||||||
headers:
|
|
||||||
Content-Length: '37'
|
|
||||||
Content-Type: "text/plain"
|
|
||||||
verify_response_with:
|
|
||||||
function: ext.validator:validate_response
|
|
||||||
extra_kwargs:
|
|
||||||
expected_response: "CON Weka jina lako la kwanza\n0. Nyuma"
|
|
||||||
|
|
||||||
- name: Enter first name [first_account_given_name - first account]
|
|
||||||
request:
|
|
||||||
url: "{server_url}"
|
|
||||||
data:
|
|
||||||
serviceCode: "*483*46#"
|
|
||||||
sessionId: "{first_metadata_entry_session_id}"
|
|
||||||
phoneNumber: "{first_account_phone_number}"
|
|
||||||
text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}"
|
|
||||||
headers:
|
|
||||||
content-type: "application/x-www-form-urlencoded"
|
|
||||||
method: POST
|
|
||||||
response:
|
|
||||||
status_code:
|
|
||||||
- 200
|
|
||||||
headers:
|
|
||||||
Content-Length: '29'
|
|
||||||
Content-Type: "text/plain"
|
|
||||||
verify_response_with:
|
|
||||||
function: ext.validator:validate_response
|
|
||||||
extra_kwargs:
|
|
||||||
expected_response: "CON Enter family name\n0. Back"
|
|
||||||
|
|
||||||
- name: Enter first name [second_account_given_name - second account]
|
|
||||||
request:
|
|
||||||
url: "{server_url}"
|
|
||||||
data:
|
|
||||||
serviceCode: "*483*46#"
|
|
||||||
sessionId: "{second_metadata_entry_session_id}"
|
|
||||||
phoneNumber: "{second_account_phone_number}"
|
|
||||||
text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}"
|
|
||||||
headers:
|
|
||||||
content-type: "application/x-www-form-urlencoded"
|
|
||||||
method: POST
|
|
||||||
response:
|
|
||||||
status_code:
|
|
||||||
- 200
|
|
||||||
headers:
|
|
||||||
Content-Length: '37'
|
|
||||||
Content-Type: "text/plain"
|
|
||||||
verify_response_with:
|
|
||||||
function: ext.validator:validate_response
|
|
||||||
extra_kwargs:
|
|
||||||
expected_response: "CON Weka jina lako la mwisho\n0. Nyuma"
|
|
||||||
|
|
||||||
- name: Enter last name [first_account_family_name - first account]
|
|
||||||
request:
|
|
||||||
url: "{server_url}"
|
|
||||||
data:
|
|
||||||
serviceCode: "*483*46#"
|
|
||||||
sessionId: "{first_metadata_entry_session_id}"
|
|
||||||
phoneNumber: "{first_account_phone_number}"
|
|
||||||
text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}*{first_account_family_name}"
|
|
||||||
headers:
|
|
||||||
content-type: "application/x-www-form-urlencoded"
|
|
||||||
method: POST
|
|
||||||
response:
|
|
||||||
status_code:
|
|
||||||
- 200
|
|
||||||
headers:
|
|
||||||
Content-Length: '51'
|
|
||||||
Content-Type: "text/plain"
|
|
||||||
verify_response_with:
|
|
||||||
function: ext.validator:validate_response
|
|
||||||
extra_kwargs:
|
|
||||||
expected_response: "CON Enter gender\n1. Male\n2. Female\n3. Other\n0. Back"
|
|
||||||
|
|
||||||
- name: Enter last name [second_account_family_name - second account]
|
|
||||||
request:
|
|
||||||
url: "{server_url}"
|
|
||||||
data:
|
|
||||||
serviceCode: "*483*46#"
|
|
||||||
sessionId: "{second_metadata_entry_session_id}"
|
|
||||||
phoneNumber: "{second_account_phone_number}"
|
|
||||||
text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}*{second_account_family_name}"
|
|
||||||
headers:
|
|
||||||
content-type: "application/x-www-form-urlencoded"
|
|
||||||
method: POST
|
|
||||||
response:
|
|
||||||
status_code:
|
|
||||||
- 200
|
|
||||||
headers:
|
|
||||||
Content-Length: '64'
|
|
||||||
Content-Type: "text/plain"
|
|
||||||
verify_response_with:
|
|
||||||
function: ext.validator:validate_response
|
|
||||||
extra_kwargs:
|
|
||||||
expected_response: "CON Weka jinsia yako\n1. Mwanaume\n2. Mwanamke\n3. Nyngine\n0. Nyuma"
|
|
||||||
|
|
||||||
- name: Select gender [Male - first account]
|
|
||||||
request:
|
|
||||||
url: "{server_url}"
|
|
||||||
data:
|
|
||||||
serviceCode: "*483*46#"
|
|
||||||
sessionId: "{first_metadata_entry_session_id}"
|
|
||||||
phoneNumber: "{first_account_phone_number}"
|
|
||||||
text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}*{first_account_family_name}*1"
|
|
||||||
headers:
|
|
||||||
content-type: "application/x-www-form-urlencoded"
|
|
||||||
method: POST
|
|
||||||
response:
|
|
||||||
status_code:
|
|
||||||
- 200
|
|
||||||
headers:
|
|
||||||
Content-Length: '31'
|
|
||||||
Content-Type: "text/plain"
|
|
||||||
verify_response_with:
|
|
||||||
function: ext.validator:validate_response
|
|
||||||
extra_kwargs:
|
|
||||||
expected_response: "CON Enter your location\n0. Back"
|
|
||||||
|
|
||||||
- name: Select gender [Female - second account]
|
|
||||||
request:
|
|
||||||
url: "{server_url}"
|
|
||||||
data:
|
|
||||||
serviceCode: "*483*46#"
|
|
||||||
sessionId: "{second_metadata_entry_session_id}"
|
|
||||||
phoneNumber: "{second_account_phone_number}"
|
|
||||||
text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}*{second_account_family_name}*2"
|
|
||||||
headers:
|
|
||||||
content-type: "application/x-www-form-urlencoded"
|
|
||||||
method: POST
|
|
||||||
response:
|
|
||||||
status_code:
|
|
||||||
- 200
|
|
||||||
headers:
|
|
||||||
Content-Length: '27'
|
|
||||||
Content-Type: "text/plain"
|
|
||||||
verify_response_with:
|
|
||||||
function: ext.validator:validate_response
|
|
||||||
extra_kwargs:
|
|
||||||
expected_response: "CON Weka eneo lako\n0. Nyuma"
|
|
||||||
|
|
||||||
- name: Enter location [first_account_location - first account]
|
|
||||||
request:
|
|
||||||
url: "{server_url}"
|
|
||||||
data:
|
|
||||||
serviceCode: "*483*46#"
|
|
||||||
sessionId: "{first_metadata_entry_session_id}"
|
|
||||||
phoneNumber: "{first_account_phone_number}"
|
|
||||||
text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}*{first_account_family_name}*1*{first_account_location}"
|
|
||||||
headers:
|
|
||||||
content-type: "application/x-www-form-urlencoded"
|
|
||||||
method: POST
|
|
||||||
response:
|
|
||||||
status_code:
|
|
||||||
- 200
|
|
||||||
headers:
|
|
||||||
Content-Length: '55'
|
|
||||||
Content-Type: "text/plain"
|
|
||||||
verify_response_with:
|
|
||||||
function: ext.validator:validate_response
|
|
||||||
extra_kwargs:
|
|
||||||
expected_response: "CON Please enter a product or service you offer\n0. Back"
|
|
||||||
|
|
||||||
- name: Enter location [second_account_location - second account]
|
|
||||||
request:
|
|
||||||
url: "{server_url}"
|
|
||||||
data:
|
|
||||||
serviceCode: "*483*46#"
|
|
||||||
sessionId: "{second_metadata_entry_session_id}"
|
|
||||||
phoneNumber: "{second_account_phone_number}"
|
|
||||||
text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}*{second_account_family_name}*2*{second_account_location}"
|
|
||||||
headers:
|
|
||||||
content-type: "application/x-www-form-urlencoded"
|
|
||||||
method: POST
|
|
||||||
response:
|
|
||||||
status_code:
|
|
||||||
- 200
|
|
||||||
headers:
|
|
||||||
Content-Length: '42'
|
|
||||||
Content-Type: "text/plain"
|
|
||||||
verify_response_with:
|
|
||||||
function: ext.validator:validate_response
|
|
||||||
extra_kwargs:
|
|
||||||
expected_response: "CON Weka bidhaa ama huduma unauza\n0. Nyuma"
|
|
||||||
|
|
||||||
- name: Enter product [first_account_product - first account]
|
|
||||||
request:
|
|
||||||
url: "{server_url}"
|
|
||||||
data:
|
|
||||||
serviceCode: "*483*46#"
|
|
||||||
sessionId: "{first_metadata_entry_session_id}"
|
|
||||||
phoneNumber: "{first_account_phone_number}"
|
|
||||||
text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}*{first_account_family_name}*1*{first_account_location}*{first_account_product}"
|
|
||||||
headers:
|
|
||||||
content-type: "application/x-www-form-urlencoded"
|
|
||||||
method: POST
|
|
||||||
response:
|
|
||||||
status_code:
|
|
||||||
- 200
|
|
||||||
headers:
|
|
||||||
Content-Length: '51'
|
|
||||||
Content-Type: "text/plain"
|
|
||||||
verify_response_with:
|
|
||||||
function: ext.validator:validate_response
|
|
||||||
extra_kwargs:
|
|
||||||
expected_response: "CON Balance {gift_value} {token_symbol}\n1. Send\n2. My Account\n3. Help"
|
|
||||||
delay_before: 10
|
|
||||||
|
|
||||||
- name: Enter product [second_account_product - second account]
|
|
||||||
request:
|
|
||||||
url: "{server_url}"
|
|
||||||
data:
|
|
||||||
serviceCode: "*483*46#"
|
|
||||||
sessionId: "{second_metadata_entry_session_id}"
|
|
||||||
phoneNumber: "{second_account_phone_number}"
|
|
||||||
text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}*{second_account_family_name}*2*{second_account_location}*{second_account_product}"
|
|
||||||
headers:
|
|
||||||
content-type: "application/x-www-form-urlencoded"
|
|
||||||
method: POST
|
|
||||||
response:
|
response:
|
||||||
status_code:
|
status_code:
|
||||||
- 200
|
- 200
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ stages:
|
|||||||
status_code:
|
status_code:
|
||||||
- 200
|
- 200
|
||||||
headers:
|
headers:
|
||||||
Content-Length: '51'
|
|
||||||
Content-Type: "text/plain"
|
Content-Type: "text/plain"
|
||||||
verify_response_with:
|
verify_response_with:
|
||||||
function: ext.validator:validate_response
|
function: ext.validator:validate_response
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -170,7 +170,7 @@ stages:
|
|||||||
verify_response_with:
|
verify_response_with:
|
||||||
function: ext.validator:validate_response
|
function: ext.validator:validate_response
|
||||||
extra_kwargs:
|
extra_kwargs:
|
||||||
expected_response: "CON {second_account_given_name} {second_account_family_name} {second_account_phone_number} will receive 17.00 {token_symbol} from {first_account_given_name} {first_account_family_name} {first_account_phone_number}.\nPlease enter your PIN to confirm.\n0. Back"
|
expected_response: "CON {second_account_phone_number} will receive 17.00 {token_symbol} from {first_account_phone_number}.\nPlease enter your PIN to confirm.\n0. Back"
|
||||||
|
|
||||||
- name: Enter transcation amount [second account]
|
- name: Enter transcation amount [second account]
|
||||||
request:
|
request:
|
||||||
@@ -191,7 +191,7 @@ stages:
|
|||||||
verify_response_with:
|
verify_response_with:
|
||||||
function: ext.validator:validate_response
|
function: ext.validator:validate_response
|
||||||
extra_kwargs:
|
extra_kwargs:
|
||||||
expected_response: "CON {first_account_given_name} {first_account_family_name} {first_account_phone_number} atapokea 25.00 {token_symbol} kutoka kwa {second_account_given_name} {second_account_family_name} {second_account_phone_number}.\nTafadhali weka nambari yako ya siri kudhibitisha.\n0. Nyuma"
|
expected_response: "CON {first_account_phone_number} atapokea 25.00 {token_symbol} kutoka kwa {second_account_phone_number}.\nTafadhali weka nambari yako ya siri kudhibitisha.\n0. Nyuma"
|
||||||
|
|
||||||
- name: Pin to authorize transaction [first account]
|
- name: Pin to authorize transaction [first account]
|
||||||
request:
|
request:
|
||||||
@@ -212,7 +212,7 @@ stages:
|
|||||||
verify_response_with:
|
verify_response_with:
|
||||||
function: ext.validator:validate_response
|
function: ext.validator:validate_response
|
||||||
extra_kwargs:
|
extra_kwargs:
|
||||||
expected_response: "CON Your request has been sent. {second_account_given_name} {second_account_family_name} {second_account_phone_number} will receive 17.00 {token_symbol} from {first_account_given_name} {first_account_family_name} {first_account_phone_number}.\n00. Back\n99. Exit"
|
expected_response: "CON Your request has been sent. {second_account_phone_number} will receive 17.00 {token_symbol} from {first_account_phone_number}.\n00. Back\n99. Exit"
|
||||||
|
|
||||||
- name: Pin to authorize transaction [second account]
|
- name: Pin to authorize transaction [second account]
|
||||||
request:
|
request:
|
||||||
@@ -233,7 +233,7 @@ stages:
|
|||||||
verify_response_with:
|
verify_response_with:
|
||||||
function: ext.validator:validate_response
|
function: ext.validator:validate_response
|
||||||
extra_kwargs:
|
extra_kwargs:
|
||||||
expected_response: "CON Ombi lako limetumwa. {first_account_given_name} {first_account_family_name} {first_account_phone_number} atapokea 25.00 {token_symbol} kutoka kwa {second_account_given_name} {second_account_family_name} {second_account_phone_number}.\n00. Nyuma\n99. Ondoka"
|
expected_response: "CON Ombi lako limetumwa. {first_account_phone_number} atapokea 25.00 {token_symbol} kutoka kwa {second_account_phone_number}.\n00. Nyuma\n99. Ondoka"
|
||||||
|
|
||||||
- name: Verify balance changes [first account]
|
- name: Verify balance changes [first account]
|
||||||
delay_before: 10
|
delay_before: 10
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "enter_date_of_birth",
|
"source": "enter_date_of_birth",
|
||||||
"dest": "enter_gender",
|
"dest": "enter_location",
|
||||||
"conditions": "cic_ussd.state_machine.logic.validator.is_valid_date",
|
"conditions": "cic_ussd.state_machine.logic.validator.is_valid_date",
|
||||||
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
||||||
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "enter_gender",
|
"source": "enter_gender",
|
||||||
"dest": "enter_location",
|
"dest": "enter_date_of_birth",
|
||||||
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
||||||
"conditions": "cic_ussd.state_machine.logic.validator.is_valid_gender_selection",
|
"conditions": "cic_ussd.state_machine.logic.validator.is_valid_gender_selection",
|
||||||
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "enter_family_name",
|
"source": "enter_family_name",
|
||||||
"dest": "enter_date_of_birth",
|
"dest": "enter_gender",
|
||||||
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
||||||
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ en:
|
|||||||
CON My profile
|
CON My profile
|
||||||
1. Edit name
|
1. Edit name
|
||||||
2. Edit gender
|
2. Edit gender
|
||||||
3. Edit Age
|
3. Edit age
|
||||||
4. Edit location
|
4. Edit location
|
||||||
5. Edit products
|
5. Edit products
|
||||||
6. View my profile
|
6. View my profile
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ sw:
|
|||||||
CON Wasifu wangu
|
CON Wasifu wangu
|
||||||
1. Weka jina
|
1. Weka jina
|
||||||
2. Weka jinsia
|
2. Weka jinsia
|
||||||
3 Weka umri
|
3. Weka umri
|
||||||
4. Weka eneo
|
4. Weka eneo
|
||||||
5. Weka bidhaa
|
5. Weka bidhaa
|
||||||
6. Angalia wasifu wako
|
6. Angalia wasifu wako
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
.contract_migration_variables:
|
.contract_migration_variables:
|
||||||
variables:
|
variables:
|
||||||
APP_NAME: contract-migration
|
APP_NAME: contract-migration
|
||||||
DOCKERFILE_PATH: $APP_NAME/docker/Dockerfile
|
DOCKERFILE_PATH: $APP_NAME/docker/Dockerfile_ci
|
||||||
|
|
||||||
.contract_migration_changes_target:
|
.contract_migration_changes_target:
|
||||||
rules:
|
rules:
|
||||||
|
|||||||
@@ -1,28 +1,22 @@
|
|||||||
# syntax = docker/dockerfile:1.2
|
# syntax = docker/dockerfile:1.2
|
||||||
FROM python:3.8.6-slim-buster as compile-image
|
FROM registry.gitlab.com/grassrootseconomics/cic-base-images:python-3.8.6-dev-55da5f4e
|
||||||
|
|
||||||
RUN apt-get update
|
WORKDIR /root
|
||||||
RUN apt-get install -y --no-install-recommends git gcc g++ libpq-dev gawk jq telnet wget openssl iputils-ping gnupg socat bash procps make python2 cargo
|
|
||||||
|
|
||||||
RUN touch /etc/apt/sources.list.d/ethereum.list
|
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 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 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 cat etc/apt/sources.list.d/ethereum.list
|
|
||||||
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 2A518C819BE37D2C2031944D1C52189C923F6CA9
|
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 2A518C819BE37D2C2031944D1C52189C923F6CA9
|
||||||
|
|
||||||
RUN apt-get update
|
#RUN apt-get install solc
|
||||||
RUN apt-get install solc
|
|
||||||
RUN pip install --upgrade pip
|
|
||||||
|
|
||||||
WORKDIR /root
|
|
||||||
RUN mkdir -vp /usr/local/etc/cic
|
RUN mkdir -vp /usr/local/etc/cic
|
||||||
|
|
||||||
COPY contract-migration/nvm.sh .
|
|
||||||
ENV CONFINI_DIR /usr/local/etc/cic/
|
ENV CONFINI_DIR /usr/local/etc/cic/
|
||||||
RUN mkdir -vp $CONFINI_DIR
|
RUN mkdir -vp $CONFINI_DIR
|
||||||
|
|
||||||
ARG cic_config_commit=35c69ba75f00c8147150acf325565d5391cf25bf
|
ARG cic_config_commit=0abe0867f18077907c7023bf0ef5e466a3984dd8
|
||||||
ARG cic_config_url=https://gitlab.com/grassrootseconomics/cic-config.git/
|
ARG cic_config_url=https://gitlab.com/grassrootseconomics/cic-config.git/
|
||||||
RUN echo Install confini schema files && \
|
RUN echo Install confini schema files && \
|
||||||
git clone --depth 1 $cic_config_url cic-config && \
|
git clone --depth 1 $cic_config_url cic-config && \
|
||||||
@@ -31,70 +25,18 @@ RUN echo Install confini schema files && \
|
|||||||
git checkout $cic_config_commit && \
|
git checkout $cic_config_commit && \
|
||||||
cp -v *.ini $CONFINI_DIR
|
cp -v *.ini $CONFINI_DIR
|
||||||
|
|
||||||
# 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
|
|
||||||
# && 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
|
|
||||||
|
|
||||||
#RUN useradd --create-home grassroots
|
|
||||||
# WORKDIR /home/grassroots
|
|
||||||
# USER grassroots
|
|
||||||
|
|
||||||
COPY contract-migration/requirements.txt .
|
COPY contract-migration/requirements.txt .
|
||||||
|
|
||||||
ARG pip_extra_args=""
|
|
||||||
ARG pip_index_url=https://pypi.org/simple
|
ARG pip_index_url=https://pypi.org/simple
|
||||||
ARG pip_extra_index_url=https://pip.grassrootseconomics.net:8433
|
ARG EXTRA_INDEX_URL="https://pip.grassrootseconomics.net:8433"
|
||||||
RUN pip install --index-url https://pypi.org/simple \
|
ARG GITLAB_PYTHON_REGISTRY="https://gitlab.com/api/v4/projects/27624814/packages/pypi/simple"
|
||||||
--extra-index-url $pip_extra_index_url -r requirements.txt
|
ARG pip_trusted_host=pypi.org
|
||||||
|
RUN --mount=type=cache,mode=0755,target=/root/.cache/pip \
|
||||||
|
pip install --index-url https://pypi.org/simple \
|
||||||
|
--force-reinstall \
|
||||||
|
--trusted-host $pip_trusted_host \
|
||||||
|
--extra-index-url $GITLAB_PYTHON_REGISTRY --extra-index-url $EXTRA_INDEX_URL \
|
||||||
|
-r requirements.txt
|
||||||
|
|
||||||
# -------------- begin runtime container ----------------
|
COPY contract-migration/ .
|
||||||
FROM python:3.8.6-slim-buster as runtime-image
|
RUN chmod +x *.sh
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y --no-install-recommends gnupg libpq-dev
|
|
||||||
RUN apt-get install -y jq bash iputils-ping socat
|
|
||||||
|
|
||||||
COPY --from=compile-image /usr/local/bin/ /usr/local/bin/
|
|
||||||
COPY --from=compile-image /usr/local/etc/cic/ /usr/local/etc/cic/
|
|
||||||
COPY --from=compile-image /usr/local/lib/python3.8/site-packages/ \
|
|
||||||
/usr/local/lib/python3.8/site-packages/
|
|
||||||
|
|
||||||
ENV EXTRA_INDEX_URL https://pip.grassrootseconomics.net:8433
|
|
||||||
# RUN useradd -u 1001 --create-home grassroots
|
|
||||||
# RUN adduser grassroots sudo && \
|
|
||||||
# echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
|
|
||||||
# WORKDIR /home/grassroots
|
|
||||||
|
|
||||||
COPY contract-migration/testdata/pgp testdata/pgp
|
|
||||||
COPY contract-migration/sarafu_declaration.json sarafu_declaration.json
|
|
||||||
COPY contract-migration/keystore keystore
|
|
||||||
COPY contract-migration/envlist .
|
|
||||||
|
|
||||||
# A shared output dir for environment configs
|
|
||||||
RUN mkdir -p /tmp/cic/config
|
|
||||||
# RUN chown grassroots:grassroots /tmp/cic/config
|
|
||||||
RUN chmod a+rwx /tmp/cic/config
|
|
||||||
|
|
||||||
COPY contract-migration/*.sh ./
|
|
||||||
# RUN chown grassroots:grassroots -R .
|
|
||||||
RUN chmod gu+x *.sh
|
|
||||||
|
|
||||||
# we copied these from the root build container.
|
|
||||||
# this is dumb though...I guess the compile image should have the same user
|
|
||||||
# RUN chown grassroots:grassroots -R /usr/local/lib/python3.8/site-packages/
|
|
||||||
|
|
||||||
# USER grassroots
|
|
||||||
|
|
||||||
ENTRYPOINT [ ]
|
|
||||||
|
|||||||
42
apps/contract-migration/docker/Dockerfile_ci
Normal file
42
apps/contract-migration/docker/Dockerfile_ci
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# syntax = docker/dockerfile:1.2
|
||||||
|
FROM registry.gitlab.com/grassrootseconomics/cic-base-images:python-3.8.6-dev-55da5f4e
|
||||||
|
|
||||||
|
WORKDIR /root
|
||||||
|
|
||||||
|
# solc install which we needed for bancor. Leaving as an artfact of HOW to do it.
|
||||||
|
#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/
|
||||||
|
RUN mkdir -vp $CONFINI_DIR
|
||||||
|
|
||||||
|
ARG cic_config_commit=0abe0867f18077907c7023bf0ef5e466a3984dd8
|
||||||
|
ARG cic_config_url=https://gitlab.com/grassrootseconomics/cic-config.git/
|
||||||
|
RUN echo Install confini schema files && \
|
||||||
|
git clone --depth 1 $cic_config_url cic-config && \
|
||||||
|
cd cic-config && \
|
||||||
|
git fetch --depth 1 origin $cic_config_commit && \
|
||||||
|
git checkout $cic_config_commit && \
|
||||||
|
cp -v *.ini $CONFINI_DIR
|
||||||
|
|
||||||
|
COPY contract-migration/requirements.txt .
|
||||||
|
|
||||||
|
ARG pip_index_url=https://pypi.org/simple
|
||||||
|
ARG EXTRA_INDEX_URL="https://pip.grassrootseconomics.net:8433"
|
||||||
|
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 \
|
||||||
|
--force-reinstall \
|
||||||
|
--trusted-host $pip_trusted_host \
|
||||||
|
--extra-index-url $GITLAB_PYTHON_REGISTRY --extra-index-url $EXTRA_INDEX_URL \
|
||||||
|
-r requirements.txt
|
||||||
|
|
||||||
|
COPY contract-migration/ .
|
||||||
|
RUN chmod +x *.sh
|
||||||
3
apps/contract-migration/override_requirements.txt
Normal file
3
apps/contract-migration/override_requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#eth-contract-registry==0.5.5a3
|
||||||
|
#erc20-demurrage-token==0.0.1b4
|
||||||
|
#eth-address-index==0.1.1a12
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
cic-base[full_graph]==0.1.2b15
|
cic_base[full]==0.1.3a3+build.984b5cff
|
||||||
sarafu-faucet==0.0.3a3
|
sarafu-faucet~=0.0.4a1
|
||||||
sarafu-token==0.0.1a8
|
cic-eth~=0.11.1a2
|
||||||
cic-eth==0.11.0b16
|
erc20-demurrage-token==0.0.2a1
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
set -a
|
set -a
|
||||||
|
|
||||||
CIC_CHAIN_SPEC=${CIC_CHAIN_SPEC:-evm:bloxberg:8995}
|
|
||||||
CIC_DEFAULT_TOKEN_SYMBOL=${CIC_DEFAULT_TOKEN_SYMBOL:-GFT}
|
CIC_DEFAULT_TOKEN_SYMBOL=${CIC_DEFAULT_TOKEN_SYMBOL:-GFT}
|
||||||
|
TOKEN_SYMBOL=${CIC_DEFAULT_TOKEN_SYMBOL}
|
||||||
|
cat <<EOF
|
||||||
|
external token settings:
|
||||||
|
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
|
||||||
|
|
||||||
|
CIC_CHAIN_SPEC=${CIC_CHAIN_SPEC:-evm:bloxberg:8995}
|
||||||
|
TOKEN_SYMBOL=${TOKEN_SYMBOL:-GFT}
|
||||||
DEV_ETH_ACCOUNT_RESERVE_MINTER=${DEV_ETH_ACCOUNT_RESERVE_MINTER:-$DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER}
|
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_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER=${DEV_ETH_ACCOUNT_RESERVE_MINTER:-$DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER}
|
||||||
DEV_RESERVE_AMOUNT=${DEV_ETH_RESERVE_AMOUNT:-""10000000000000000000000000000000000}
|
DEV_RESERVE_AMOUNT=${DEV_ETH_RESERVE_AMOUNT:-""10000000000000000000000000000000000}
|
||||||
@@ -19,8 +31,8 @@ if [ ! -z $DEV_ETH_GAS_PRICE ]; then
|
|||||||
>&2 echo using static gas price $DEV_ETH_GAS_PRICE
|
>&2 echo using static gas price $DEV_ETH_GAS_PRICE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $CIC_DEFAULT_TOKEN_SYMBOL != 'GFT' && $CIC_DEFAULT_TOKEN_SYMBOL != 'SRF' ]]; then
|
if [[ $TOKEN_SYMBOL != 'GFT' && $TOKEN_SYMBOL != 'SRF' ]]; then
|
||||||
>&2 echo CIC_DEFAULT_TOKEN_SYMBOL must be one of [GFT,SRF], but was $CIC_DEFAULT_TOKEN_SYMBOL
|
>&2 echo TOKEN_SYMBOL must be one of [GFT,SRF], but was $TOKEN_SYMBOL
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -60,17 +72,18 @@ if [[ -n "${ETH_PROVIDER}" ]]; then
|
|||||||
./wait-for-it.sh "${ETH_PROVIDER_HOST}:${ETH_PROVIDER_PORT}"
|
./wait-for-it.sh "${ETH_PROVIDER_HOST}:${ETH_PROVIDER_PORT}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $CIC_DEFAULT_TOKEN_SYMBOL == 'GFT' ]; then
|
if [ $TOKEN_SYMBOL == 'GFT' ]; then
|
||||||
>&2 echo "deploying 'giftable token'"
|
>&2 echo "deploying 'giftable token'"
|
||||||
DEV_RESERVE_ADDRESS=`giftable-token-deploy $gas_price_arg -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -vv -w --name "Giftable Token" --symbol "GFT" --decimals 6 -vv`
|
DEV_RESERVE_ADDRESS=`giftable-token-deploy $gas_price_arg -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -vv -ww --name "Giftable Token" --symbol "GFT" --decimals 6 -vv`
|
||||||
else
|
else
|
||||||
>&2 echo "deploying 'sarafu' token'"
|
>&2 echo "deploying 'redistributed demurrage token'"
|
||||||
DEV_RESERVE_ADDRESS=`sarafu-token-deploy $gas_price_arg -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -vv -w --name "Sarafu" --decimals 6 -vv SRF $DEV_SARAFU_DEMURRAGE_LEVEL`
|
if [ -z $TOKEN_SINK_ADDRESS && ! -z $TOKEN_REDISTRIBUTION_PERIOD ]; then
|
||||||
|
>&2 echo -e "\033[;93mtoken sink address not set, so redistribution will be BURNED\033[;39m"
|
||||||
|
fi
|
||||||
|
DEV_RESERVE_ADDRESS=`erc20-demurrage-token-deploy $gas_price_arg -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -vv -ww`
|
||||||
fi
|
fi
|
||||||
giftable-token-gift $gas_price_arg -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -vv -w -a $DEV_RESERVE_ADDRESS $DEV_RESERVE_AMOUNT
|
giftable-token-gift $gas_price_arg -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -vv -w -a $DEV_RESERVE_ADDRESS $DEV_RESERVE_AMOUNT
|
||||||
|
|
||||||
#BANCOR_REGISTRY_ADDRESS=`cic-bancor-deploy $gas_price_arg --bancor-dir /usr/local/share/cic/bancor -z $DEV_ETH_RESERVE_ADDRESS -p $ETH_PROVIDER -o $DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER`
|
|
||||||
|
|
||||||
>&2 echo "deploy account index contract"
|
>&2 echo "deploy account index contract"
|
||||||
DEV_ACCOUNT_INDEX_ADDRESS=`eth-accounts-index-deploy $gas_price_arg -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -vv -w`
|
DEV_ACCOUNT_INDEX_ADDRESS=`eth-accounts-index-deploy $gas_price_arg -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -vv -w`
|
||||||
>&2 echo "add deployer address as account index writer"
|
>&2 echo "add deployer address as account index writer"
|
||||||
|
|||||||
@@ -2,13 +2,22 @@
|
|||||||
|
|
||||||
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"
|
||||||
./reset.sh
|
./reset.sh
|
||||||
if [ $? -ne "0" ]; then
|
if [ $? -ne "0" ]; then
|
||||||
exit 1;
|
>&2 echo -e "\033[;31mFAILED\033[;39m RUN_MASK 1 - contract deployment"
|
||||||
|
exit 1;
|
||||||
fi
|
fi
|
||||||
|
>&2 echo -e "\033[;32mSUCCEEDED\033[;39m RUN_MASK 1 - contract deployment"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $((RUN_MASK & 2)) -eq 2 ]]
|
if [[ $((RUN_MASK & 2)) -eq 2 ]]
|
||||||
then
|
then
|
||||||
|
>&2 echo -e "\033[;96mRUNNING\033[;39m RUN_MASK 2 - custodial service initialization"
|
||||||
./seed_cic_eth.sh
|
./seed_cic_eth.sh
|
||||||
|
if [ $? -ne "0" ]; then
|
||||||
|
>&2 echo -e "\033[;31mFAILED\033[;39m RUN_MASK 2 - custodial service initialization"
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
>&2 echo -e "\033[;32mSUCCEEDED\033[;39m RUN_MASK 2 - custodial service initialization"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ DEV_DATABASE_NAME_CIC_ETH=${DEV_DATABASE_NAME_CIC_ETH:-"cic-eth"}
|
|||||||
CIC_DATA_DIR=${CIC_DATA_DIR:-/tmp/cic}
|
CIC_DATA_DIR=${CIC_DATA_DIR:-/tmp/cic}
|
||||||
ETH_PASSPHRASE=''
|
ETH_PASSPHRASE=''
|
||||||
CIC_DEFAULT_TOKEN_SYMBOL=${CIC_DEFAULT_TOKEN_SYMBOL:-GFT}
|
CIC_DEFAULT_TOKEN_SYMBOL=${CIC_DEFAULT_TOKEN_SYMBOL:-GFT}
|
||||||
|
TOKEN_SYMBOL=$CIC_DEFAULT_TOKEN_SYMBOL
|
||||||
if [[ $CIC_DEFAULT_TOKEN_SYMBOL != 'GFT' && $CIC_DEFAULT_TOKEN_SYMBOL != 'SRF' ]]; then
|
if [[ $CIC_DEFAULT_TOKEN_SYMBOL != 'GFT' && $CIC_DEFAULT_TOKEN_SYMBOL != 'SRF' ]]; then
|
||||||
>&2 echo CIC_DEFAULT_TOKEN_SYMBOL must be one of [GFT,SRF], but was $CIC_DEFAULT_TOKEN_SYMBOL
|
>&2 echo CIC_DEFAULT_TOKEN_SYMBOL must be one of [GFT,SRF], but was $CIC_DEFAULT_TOKEN_SYMBOL
|
||||||
exit 1
|
exit 1
|
||||||
@@ -98,8 +99,8 @@ 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 sarafu tokens to token gifter address"
|
>&2 echo "transfer tokens to token gifter address"
|
||||||
>&2 erc20-transfer -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER --token-address $DEV_RESERVE_ADDRESS -w $debug $DEV_ETH_ACCOUNT_SARAFU_GIFTER ${token_amount:0:-1}
|
>&2 erc20-transfer -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER --gas-limit 100000 --token-address $DEV_RESERVE_ADDRESS -w $debug $DEV_ETH_ACCOUNT_SARAFU_GIFTER ${token_amount:0:-1}
|
||||||
|
|
||||||
#echo -n 0 > $init_level_file
|
#echo -n 0 > $init_level_file
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
.data_seeding_variables:
|
.data_seeding_variables:
|
||||||
variables:
|
variables:
|
||||||
APP_NAME: data-seeding
|
APP_NAME: data-seeding
|
||||||
DOCKERFILE_PATH: $APP_NAME/docker/Dockerfile
|
DOCKERFILE_PATH: $APP_NAME/docker/Dockerfile_ci
|
||||||
|
|
||||||
.data_seeding_changes_target:
|
.data_seeding_changes_target:
|
||||||
rules:
|
rules:
|
||||||
|
|||||||
@@ -171,7 +171,11 @@ Then, in sequence, run in first terminal:
|
|||||||
|
|
||||||
In second terminal:
|
In second terminal:
|
||||||
|
|
||||||
`python cic_ussd/import_users.py -v -c config out`
|
`python cic_ussd/import_users.py -v --ussd-host <user_ussd_server_host> --ussd-port <user_ussd_server_port> -c config out`
|
||||||
|
|
||||||
|
In the event that you are running the command in a local environment you may want to consider passing the `--ussd-no-ssl` flag i.e:
|
||||||
|
|
||||||
|
`python cic_ussd/import_users.py -v --ussd-host <user_ussd_server_host> --ussd-port <user_ussd_server_port> --ussd-no-ssl -c config out`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -199,6 +203,13 @@ If _number of users_ is omitted the script will run until manually interrupted.
|
|||||||
If you imported using `cic_ussd`, the phone pointer is _already added_ and this script will do nothing.
|
If you imported using `cic_ussd`, the phone pointer is _already added_ and this script will do nothing.
|
||||||
|
|
||||||
|
|
||||||
|
### Importing preferences metadata
|
||||||
|
|
||||||
|
`node cic_meta/import_meta_preferences.js <datadir> <number_of_users>`
|
||||||
|
|
||||||
|
If you used the `cic_ussd/import_user.py` script to import your users, preferences metadata is generated and will be imported.
|
||||||
|
|
||||||
|
|
||||||
##### Importing pins and ussd data (optional)
|
##### Importing pins and ussd data (optional)
|
||||||
|
|
||||||
Once the user imports are complete the next step should be importing the user's pins and auxiliary ussd data. This can be done in 3 steps:
|
Once the user imports are complete the next step should be importing the user's pins and auxiliary ussd data. This can be done in 3 steps:
|
||||||
|
|||||||
@@ -18,19 +18,17 @@ from hexathon import (
|
|||||||
add_0x,
|
add_0x,
|
||||||
)
|
)
|
||||||
from chainsyncer.backend.memory import MemBackend
|
from chainsyncer.backend.memory import MemBackend
|
||||||
from chainsyncer.driver import HeadSyncer
|
from chainsyncer.driver.head import HeadSyncer
|
||||||
from chainlib.eth.connection import EthHTTPConnection
|
from chainlib.eth.connection import EthHTTPConnection
|
||||||
from chainlib.eth.block import (
|
from chainlib.eth.block import (
|
||||||
block_latest,
|
block_latest,
|
||||||
block_by_number,
|
|
||||||
Block,
|
|
||||||
)
|
)
|
||||||
from chainlib.hash import keccak256_string_to_hex
|
from chainlib.hash import keccak256_string_to_hex
|
||||||
from chainlib.eth.address import to_checksum_address
|
from chainlib.eth.address import to_checksum_address
|
||||||
from chainlib.eth.gas import OverrideGasOracle
|
from chainlib.eth.gas import OverrideGasOracle
|
||||||
from chainlib.eth.nonce import RPCNonceOracle
|
from chainlib.eth.nonce import RPCNonceOracle
|
||||||
from chainlib.eth.tx import TxFactory
|
from chainlib.eth.tx import TxFactory
|
||||||
from chainlib.jsonrpc import jsonrpc_template
|
from chainlib.jsonrpc import JSONRPCRequest
|
||||||
from chainlib.eth.error import EthException
|
from chainlib.eth.error import EthException
|
||||||
from chainlib.chain import ChainSpec
|
from chainlib.chain import ChainSpec
|
||||||
from chainlib.eth.constant import ZERO_ADDRESS
|
from chainlib.eth.constant import ZERO_ADDRESS
|
||||||
@@ -38,6 +36,7 @@ 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
|
||||||
from cic_types.models.person import Person
|
from cic_types.models.person import Person
|
||||||
from eth_erc20 import ERC20
|
from eth_erc20 import ERC20
|
||||||
|
from cic_base.eth.syncer import chain_interface
|
||||||
|
|
||||||
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
logging.basicConfig(level=logging.WARNING)
|
||||||
@@ -70,13 +69,14 @@ elif args.vv == True:
|
|||||||
config_dir = os.path.join(args.c)
|
config_dir = os.path.join(args.c)
|
||||||
os.makedirs(config_dir, 0o777, True)
|
os.makedirs(config_dir, 0o777, True)
|
||||||
config = confini.Config(config_dir, args.env_prefix)
|
config = confini.Config(config_dir, args.env_prefix)
|
||||||
config.process()
|
|
||||||
# override args
|
# override args
|
||||||
|
config.process()
|
||||||
|
logg.debug('config loaded from {}:\n{}'.format(config_dir, config))
|
||||||
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'),
|
||||||
'CIC_REGISTRY_ADDRESS': getattr(args, 'r'),
|
'CIC_REGISTRY_ADDRESS': getattr(args, 'r'),
|
||||||
'KEYSTORE_FILE_PATH': getattr(args, 'key-file')
|
'KEYSTORE_FILE_PATH': getattr(args, 'y'),
|
||||||
}
|
}
|
||||||
config.dict_override(args_override, 'cli flag')
|
config.dict_override(args_override, 'cli flag')
|
||||||
config.censor('PASSWORD', 'DATABASE')
|
config.censor('PASSWORD', 'DATABASE')
|
||||||
@@ -185,27 +185,6 @@ class Handler:
|
|||||||
# logg.error('key record not found in imports: {}'.format(e).ljust(200))
|
# logg.error('key record not found in imports: {}'.format(e).ljust(200))
|
||||||
|
|
||||||
|
|
||||||
#class BlockGetter:
|
|
||||||
#
|
|
||||||
# def __init__(self, conn, gas_oracle, nonce_oracle, chain_spec):
|
|
||||||
# self.conn = conn
|
|
||||||
# self.tx_factory = ERC20(signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle, chain_id=chain_id)
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# def get(self, n):
|
|
||||||
# o = block_by_number(n)
|
|
||||||
# r = self.conn.do(o)
|
|
||||||
# b = None
|
|
||||||
# try:
|
|
||||||
# b = Block(r)
|
|
||||||
# except TypeError as e:
|
|
||||||
# if r == None:
|
|
||||||
# logg.debug('block not found {}'.format(n))
|
|
||||||
# else:
|
|
||||||
# logg.error('block retrieve error {}'.format(e))
|
|
||||||
# return b
|
|
||||||
|
|
||||||
|
|
||||||
def progress_callback(block_number, tx_index):
|
def progress_callback(block_number, tx_index):
|
||||||
sys.stdout.write(str(block_number).ljust(200) + "\n")
|
sys.stdout.write(str(block_number).ljust(200) + "\n")
|
||||||
|
|
||||||
@@ -226,11 +205,13 @@ def main():
|
|||||||
data = add_0x(registry_addressof_method)
|
data = add_0x(registry_addressof_method)
|
||||||
data += eth_abi.encode_single('bytes32', b'TokenRegistry').hex()
|
data += eth_abi.encode_single('bytes32', b'TokenRegistry').hex()
|
||||||
txf.set_code(tx, data)
|
txf.set_code(tx, data)
|
||||||
|
|
||||||
o = jsonrpc_template()
|
j = JSONRPCRequest()
|
||||||
|
o = j.template()
|
||||||
o['method'] = 'eth_call'
|
o['method'] = 'eth_call'
|
||||||
o['params'].append(txf.normalize(tx))
|
o['params'].append(txf.normalize(tx))
|
||||||
o['params'].append('latest')
|
o['params'].append('latest')
|
||||||
|
o = j.finalize(o)
|
||||||
r = conn.do(o)
|
r = conn.do(o)
|
||||||
token_index_address = to_checksum_address(eth_abi.decode_single('address', bytes.fromhex(strip_0x(r))))
|
token_index_address = to_checksum_address(eth_abi.decode_single('address', bytes.fromhex(strip_0x(r))))
|
||||||
logg.info('found token index address {}'.format(token_index_address))
|
logg.info('found token index address {}'.format(token_index_address))
|
||||||
@@ -244,10 +225,11 @@ def main():
|
|||||||
z = h.digest()
|
z = h.digest()
|
||||||
data += eth_abi.encode_single('bytes32', z).hex()
|
data += eth_abi.encode_single('bytes32', z).hex()
|
||||||
txf.set_code(tx, data)
|
txf.set_code(tx, data)
|
||||||
o = jsonrpc_template()
|
o = j.template()
|
||||||
o['method'] = 'eth_call'
|
o['method'] = 'eth_call'
|
||||||
o['params'].append(txf.normalize(tx))
|
o['params'].append(txf.normalize(tx))
|
||||||
o['params'].append('latest')
|
o['params'].append('latest')
|
||||||
|
o = j.finalize(o)
|
||||||
r = conn.do(o)
|
r = conn.do(o)
|
||||||
try:
|
try:
|
||||||
sarafu_token_address = to_checksum_address(eth_abi.decode_single('address', bytes.fromhex(strip_0x(r))))
|
sarafu_token_address = to_checksum_address(eth_abi.decode_single('address', bytes.fromhex(strip_0x(r))))
|
||||||
@@ -305,7 +287,7 @@ def main():
|
|||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
syncer_backend.set(block_offset, 0)
|
syncer_backend.set(block_offset, 0)
|
||||||
syncer = HeadSyncer(syncer_backend, block_callback=progress_callback)
|
syncer = HeadSyncer(syncer_backend, chain_interface, block_callback=progress_callback)
|
||||||
handler = Handler(conn, chain_spec, user_dir, balances, sarafu_token_address, signer, gas_oracle, nonce_oracle)
|
handler = Handler(conn, chain_spec, user_dir, balances, sarafu_token_address, signer, gas_oracle, nonce_oracle)
|
||||||
syncer.add_filter(handler)
|
syncer.add_filter(handler)
|
||||||
syncer.loop(1, conn)
|
syncer.loop(1, conn)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import redis
|
|||||||
import celery
|
import celery
|
||||||
from cic_eth_registry.registry import CICRegistry
|
from cic_eth_registry.registry import CICRegistry
|
||||||
from chainsyncer.backend.memory import MemBackend
|
from chainsyncer.backend.memory import MemBackend
|
||||||
from chainsyncer.driver import HeadSyncer
|
from chainsyncer.driver.head import HeadSyncer
|
||||||
from chainlib.eth.connection import EthHTTPConnection
|
from chainlib.eth.connection import EthHTTPConnection
|
||||||
from chainlib.chain import ChainSpec
|
from chainlib.chain import ChainSpec
|
||||||
from chainlib.eth.gas import RPCGasOracle
|
from chainlib.eth.gas import RPCGasOracle
|
||||||
@@ -24,6 +24,7 @@ from cic_base import (
|
|||||||
rpc,
|
rpc,
|
||||||
signer as signer_funcs,
|
signer as signer_funcs,
|
||||||
)
|
)
|
||||||
|
from cic_base.eth.syncer import chain_interface
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
#import common
|
#import common
|
||||||
@@ -120,7 +121,7 @@ def main():
|
|||||||
'api_queue': config.get('_CELERY_QUEUE'),
|
'api_queue': config.get('_CELERY_QUEUE'),
|
||||||
}
|
}
|
||||||
|
|
||||||
syncer = HeadSyncer(syncer_backend, block_callback=handler.refresh)
|
syncer = HeadSyncer(syncer_backend, chain_interface, block_callback=handler.refresh)
|
||||||
syncer.add_filter(handler)
|
syncer.add_filter(handler)
|
||||||
syncer.loop(1, conn)
|
syncer.loop(1, conn)
|
||||||
|
|
||||||
|
|||||||
@@ -93,9 +93,9 @@ function importMeta(keystore) {
|
|||||||
let files;
|
let files;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
err, files = fs.readdirSync(workDir);
|
files = fs.readdirSync(workDir);
|
||||||
} catch {
|
} catch (err) {
|
||||||
console.error('source directory not yet ready', workDir);
|
console.error('source directory not yet ready', workDir, 'reason: ', err);
|
||||||
setTimeout(importMeta, batchDelay, keystore);
|
setTimeout(importMeta, batchDelay, keystore);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,22 @@
|
|||||||
# standard imports
|
# standard imports
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import logging
|
|
||||||
import argparse
|
import argparse
|
||||||
import hashlib
|
import logging
|
||||||
import redis
|
import sys
|
||||||
import celery
|
import os
|
||||||
|
|
||||||
# external imports
|
# external imports
|
||||||
|
import celery
|
||||||
import confini
|
import confini
|
||||||
from chainlib.eth.connection import EthHTTPConnection
|
import redis
|
||||||
from chainlib.chain import ChainSpec
|
from chainlib.chain import ChainSpec
|
||||||
from hexathon import (
|
|
||||||
strip_0x,
|
|
||||||
add_0x,
|
|
||||||
)
|
|
||||||
from chainlib.eth.address import to_checksum_address
|
from chainlib.eth.address import to_checksum_address
|
||||||
|
from chainlib.eth.connection import EthHTTPConnection
|
||||||
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
|
||||||
from cic_types.models.person import Person
|
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from import_util import BalanceProcessor
|
from import_task import ImportTask, MetadataTask
|
||||||
from import_task import *
|
from import_util import BalanceProcessor, get_celery_worker_status
|
||||||
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
logging.basicConfig(level=logging.WARNING)
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
@@ -41,37 +35,41 @@ argparser.add_argument('--meta-port', dest='meta_port', type=int, help='metadata
|
|||||||
argparser.add_argument('--redis-host', dest='redis_host', type=str, help='redis host to use for task submission')
|
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-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('--redis-db', dest='redis_db', type=int, help='redis db to use for task submission and callback')
|
||||||
argparser.add_argument('--token-symbol', default='SRF', type=str, dest='token_symbol', help='Token symbol to use for trnsactions')
|
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('--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('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str,
|
||||||
argparser.add_argument('-q', type=str, default='cic-eth', help='celery queue to submit transaction tasks to')
|
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('--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('-v', help='be verbose', action='store_true')
|
||||||
argparser.add_argument('-vv', help='be more 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')
|
argparser.add_argument('user_dir', default='out', type=str, help='user export directory')
|
||||||
args = argparser.parse_args(sys.argv[1:])
|
args = argparser.parse_args(sys.argv[1:])
|
||||||
|
|
||||||
if args.v == True:
|
if args.v:
|
||||||
logging.getLogger().setLevel(logging.INFO)
|
logging.getLogger().setLevel(logging.INFO)
|
||||||
elif args.vv == True:
|
|
||||||
|
elif args.vv:
|
||||||
logging.getLogger().setLevel(logging.DEBUG)
|
logging.getLogger().setLevel(logging.DEBUG)
|
||||||
|
|
||||||
config_dir = os.path.join(args.c)
|
config_dir = os.path.join(args.c)
|
||||||
os.makedirs(config_dir, 0o777, True)
|
os.makedirs(config_dir, 0o777, True)
|
||||||
config = confini.Config(config_dir, args.env_prefix)
|
config = confini.Config(config_dir, args.env_prefix)
|
||||||
config.process()
|
config.process()
|
||||||
|
|
||||||
# override args
|
# 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'),
|
||||||
'CIC_REGISTRY_ADDRESS': getattr(args, 'r'),
|
'CIC_REGISTRY_ADDRESS': getattr(args, 'r'),
|
||||||
'REDIS_HOST': getattr(args, 'redis_host'),
|
'REDIS_HOST': getattr(args, 'redis_host'),
|
||||||
'REDIS_PORT': getattr(args, 'redis_port'),
|
'REDIS_PORT': getattr(args, 'redis_port'),
|
||||||
'REDIS_DB': getattr(args, 'redis_db'),
|
'REDIS_DB': getattr(args, 'redis_db'),
|
||||||
'META_HOST': getattr(args, 'meta_host'),
|
'META_HOST': getattr(args, 'meta_host'),
|
||||||
'META_PORT': getattr(args, 'meta_port'),
|
'META_PORT': getattr(args, 'meta_port'),
|
||||||
'KEYSTORE_FILE_PATH': getattr(args, 'y')
|
'KEYSTORE_FILE_PATH': getattr(args, 'y')
|
||||||
}
|
}
|
||||||
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')
|
||||||
@@ -81,14 +79,19 @@ redis_host = config.get('REDIS_HOST')
|
|||||||
redis_port = config.get('REDIS_PORT')
|
redis_port = config.get('REDIS_PORT')
|
||||||
redis_db = config.get('REDIS_DB')
|
redis_db = config.get('REDIS_DB')
|
||||||
r = redis.Redis(redis_host, redis_port, redis_db)
|
r = redis.Redis(redis_host, redis_port, redis_db)
|
||||||
celery_app = celery.Celery(backend=config.get('CELERY_RESULT_URL'), broker=config.get('CELERY_BROKER_URL'))
|
|
||||||
|
# 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
|
signer_address = None
|
||||||
keystore = DictKeystore()
|
keystore = DictKeystore()
|
||||||
if args.y != None:
|
if args.y is not None:
|
||||||
logg.debug('loading keystore file {}'.format(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('now have key for signer address {}'.format(signer_address))
|
logg.debug('now have key for signer address {}'.format(signer_address))
|
||||||
|
|
||||||
|
# define signer
|
||||||
signer = EIP155Signer(keystore)
|
signer = EIP155Signer(keystore)
|
||||||
|
|
||||||
queue = args.q
|
queue = args.q
|
||||||
@@ -103,7 +106,7 @@ chain_spec = ChainSpec.from_chain_str(chain_str)
|
|||||||
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
|
user_dir = args.user_dir # user_out_dir from import_users.py
|
||||||
|
|
||||||
token_symbol = args.token_symbol
|
token_symbol = args.token_symbol
|
||||||
|
|
||||||
@@ -111,20 +114,22 @@ 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
|
ImportTask.chain_spec = chain_spec
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
conn = EthHTTPConnection(config.get('ETH_PROVIDER'))
|
conn = EthHTTPConnection(config.get('ETH_PROVIDER'))
|
||||||
|
|
||||||
ImportTask.balance_processor = BalanceProcessor(conn, chain_spec, config.get('CIC_REGISTRY_ADDRESS'), signer_address, signer)
|
ImportTask.balance_processor = BalanceProcessor(conn, chain_spec, config.get('CIC_REGISTRY_ADDRESS'),
|
||||||
|
signer_address, signer)
|
||||||
ImportTask.balance_processor.init(token_symbol)
|
ImportTask.balance_processor.init(token_symbol)
|
||||||
|
|
||||||
# TODO get decimals from token
|
# TODO get decimals from token
|
||||||
balances = {}
|
balances = {}
|
||||||
f = open('{}/balances.csv'.format(user_dir, 'r'))
|
f = open('{}/balances.csv'.format(user_dir, 'r'))
|
||||||
remove_zeros = 10**6
|
remove_zeros = 10 ** 6
|
||||||
i = 0
|
i = 0
|
||||||
while True:
|
while True:
|
||||||
l = f.readline()
|
l = f.readline()
|
||||||
if l == None:
|
if l is None:
|
||||||
break
|
break
|
||||||
r = l.split(',')
|
r = l.split(',')
|
||||||
try:
|
try:
|
||||||
@@ -143,15 +148,23 @@ def main():
|
|||||||
ImportTask.import_dir = user_dir
|
ImportTask.import_dir = user_dir
|
||||||
|
|
||||||
s = celery.signature(
|
s = celery.signature(
|
||||||
'import_task.send_txs',
|
'import_task.send_txs',
|
||||||
[
|
[
|
||||||
MetadataTask.balance_processor.nonce_offset,
|
MetadataTask.balance_processor.nonce_offset,
|
||||||
],
|
],
|
||||||
queue='cic-import-ussd',
|
queue=queue,
|
||||||
)
|
)
|
||||||
s.apply_async()
|
s.apply_async()
|
||||||
|
|
||||||
argv = ['worker', '-Q', 'cic-import-ussd', '--loglevel=DEBUG']
|
argv = ['worker']
|
||||||
|
if args.vv:
|
||||||
|
argv.append('--loglevel=DEBUG')
|
||||||
|
elif args.v:
|
||||||
|
argv.append('--loglevel=INFO')
|
||||||
|
argv.append('-Q')
|
||||||
|
argv.append(args.q)
|
||||||
|
argv.append('-n')
|
||||||
|
argv.append(args.q)
|
||||||
celery_app.worker_main(argv)
|
celery_app.worker_main(argv)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import celery
|
|||||||
import confini
|
import confini
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from import_task import *
|
from import_util import get_celery_worker_status
|
||||||
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
logging.basicConfig(level=logging.WARNING)
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
@@ -39,9 +39,12 @@ elif args.vv:
|
|||||||
config_dir = args.c
|
config_dir = args.c
|
||||||
config = confini.Config(config_dir, os.environ.get('CONFINI_ENV_PREFIX'))
|
config = confini.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('config loaded from {}:\n{}'.format(args.c, config))
|
||||||
|
|
||||||
celery_app = celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL'))
|
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 = {
|
db_configs = {
|
||||||
'database': config.get('DATABASE_NAME'),
|
'database': config.get('DATABASE_NAME'),
|
||||||
@@ -61,7 +64,8 @@ def main():
|
|||||||
(db_configs, phone_to_pins),
|
(db_configs, phone_to_pins),
|
||||||
queue=args.q
|
queue=args.q
|
||||||
)
|
)
|
||||||
s_import_pins.apply_async()
|
result = s_import_pins.apply_async()
|
||||||
|
logg.debug(f'TASK: {result.id}, STATUS: {result.status}')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -1,36 +1,33 @@
|
|||||||
# standard imports
|
# standard imports
|
||||||
import os
|
|
||||||
import logging
|
|
||||||
import random
|
|
||||||
import urllib.parse
|
|
||||||
import urllib.error
|
|
||||||
import urllib.request
|
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
import urllib.error
|
||||||
|
import urllib.parse
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
# external imports
|
# external imports
|
||||||
import celery
|
import celery
|
||||||
import psycopg2
|
import psycopg2
|
||||||
from psycopg2 import extras
|
|
||||||
from hexathon import (
|
|
||||||
strip_0x,
|
|
||||||
add_0x,
|
|
||||||
)
|
|
||||||
from chainlib.eth.address import to_checksum_address
|
from chainlib.eth.address import to_checksum_address
|
||||||
from chainlib.eth.tx import (
|
from chainlib.eth.tx import (
|
||||||
unpack,
|
unpack,
|
||||||
raw,
|
raw,
|
||||||
)
|
)
|
||||||
from cic_types.processor import generate_metadata_pointer
|
|
||||||
from cic_types.models.person import Person
|
from cic_types.models.person import Person
|
||||||
|
from cic_types.processor import generate_metadata_pointer
|
||||||
|
from hexathon import (
|
||||||
|
strip_0x,
|
||||||
|
add_0x,
|
||||||
|
)
|
||||||
|
|
||||||
#logg = logging.getLogger().getChild(__name__)
|
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
|
|
||||||
celery_app = celery.current_app
|
celery_app = celery.current_app
|
||||||
|
|
||||||
|
|
||||||
class ImportTask(celery.Task):
|
class ImportTask(celery.Task):
|
||||||
|
|
||||||
balances = None
|
balances = None
|
||||||
import_dir = 'out'
|
import_dir = 'out'
|
||||||
count = 0
|
count = 0
|
||||||
@@ -38,16 +35,16 @@ class ImportTask(celery.Task):
|
|||||||
balance_processor = None
|
balance_processor = None
|
||||||
max_retries = None
|
max_retries = None
|
||||||
|
|
||||||
class MetadataTask(ImportTask):
|
|
||||||
|
|
||||||
|
class MetadataTask(ImportTask):
|
||||||
meta_host = None
|
meta_host = None
|
||||||
meta_port = None
|
meta_port = None
|
||||||
meta_path = ''
|
meta_path = ''
|
||||||
meta_ssl = False
|
meta_ssl = False
|
||||||
autoretry_for = (
|
autoretry_for = (
|
||||||
urllib.error.HTTPError,
|
urllib.error.HTTPError,
|
||||||
OSError,
|
OSError,
|
||||||
)
|
)
|
||||||
retry_jitter = True
|
retry_jitter = True
|
||||||
retry_backoff = True
|
retry_backoff = True
|
||||||
retry_backoff_max = 60
|
retry_backoff_max = 60
|
||||||
@@ -64,12 +61,12 @@ class MetadataTask(ImportTask):
|
|||||||
def old_address_from_phone(base_path, phone):
|
def old_address_from_phone(base_path, phone):
|
||||||
pidx = generate_metadata_pointer(phone.encode('utf-8'), ':cic.phone')
|
pidx = generate_metadata_pointer(phone.encode('utf-8'), ':cic.phone')
|
||||||
phone_idx_path = os.path.join('{}/phone/{}/{}/{}'.format(
|
phone_idx_path = os.path.join('{}/phone/{}/{}/{}'.format(
|
||||||
base_path,
|
base_path,
|
||||||
pidx[:2],
|
pidx[:2],
|
||||||
pidx[2:4],
|
pidx[2:4],
|
||||||
pidx,
|
pidx,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
f = open(phone_idx_path, 'r')
|
f = open(phone_idx_path, 'r')
|
||||||
old_address = f.read()
|
old_address = f.read()
|
||||||
f.close()
|
f.close()
|
||||||
@@ -97,11 +94,11 @@ def generate_metadata(self, address, phone):
|
|||||||
logg.debug('address {}'.format(address))
|
logg.debug('address {}'.format(address))
|
||||||
old_address_upper = strip_0x(old_address).upper()
|
old_address_upper = strip_0x(old_address).upper()
|
||||||
metadata_path = '{}/old/{}/{}/{}.json'.format(
|
metadata_path = '{}/old/{}/{}/{}.json'.format(
|
||||||
self.import_dir,
|
self.import_dir,
|
||||||
old_address_upper[:2],
|
old_address_upper[:2],
|
||||||
old_address_upper[2:4],
|
old_address_upper[2:4],
|
||||||
old_address_upper,
|
old_address_upper,
|
||||||
)
|
)
|
||||||
|
|
||||||
f = open(metadata_path, 'r')
|
f = open(metadata_path, 'r')
|
||||||
o = json.load(f)
|
o = json.load(f)
|
||||||
@@ -116,12 +113,12 @@ def generate_metadata(self, address, phone):
|
|||||||
|
|
||||||
new_address_clean = strip_0x(address)
|
new_address_clean = strip_0x(address)
|
||||||
filepath = os.path.join(
|
filepath = os.path.join(
|
||||||
self.import_dir,
|
self.import_dir,
|
||||||
'new',
|
'new',
|
||||||
new_address_clean[:2].upper(),
|
new_address_clean[:2].upper(),
|
||||||
new_address_clean[2:4].upper(),
|
new_address_clean[2:4].upper(),
|
||||||
new_address_clean.upper() + '.json',
|
new_address_clean.upper() + '.json',
|
||||||
)
|
)
|
||||||
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
||||||
|
|
||||||
o = u.serialize()
|
o = u.serialize()
|
||||||
@@ -131,10 +128,10 @@ def generate_metadata(self, address, phone):
|
|||||||
|
|
||||||
meta_key = generate_metadata_pointer(bytes.fromhex(new_address_clean), ':cic.person')
|
meta_key = generate_metadata_pointer(bytes.fromhex(new_address_clean), ':cic.person')
|
||||||
meta_filepath = os.path.join(
|
meta_filepath = os.path.join(
|
||||||
self.import_dir,
|
self.import_dir,
|
||||||
'meta',
|
'meta',
|
||||||
'{}.json'.format(new_address_clean.upper()),
|
'{}.json'.format(new_address_clean.upper()),
|
||||||
)
|
)
|
||||||
os.symlink(os.path.realpath(filepath), meta_filepath)
|
os.symlink(os.path.realpath(filepath), meta_filepath)
|
||||||
|
|
||||||
# write ussd data
|
# write ussd data
|
||||||
@@ -180,10 +177,8 @@ def generate_metadata(self, address, phone):
|
|||||||
|
|
||||||
@celery_app.task(bind=True, base=MetadataTask)
|
@celery_app.task(bind=True, base=MetadataTask)
|
||||||
def opening_balance_tx(self, address, phone, serial):
|
def opening_balance_tx(self, address, phone, serial):
|
||||||
|
|
||||||
|
|
||||||
old_address = old_address_from_phone(self.import_dir, phone)
|
old_address = old_address_from_phone(self.import_dir, phone)
|
||||||
|
|
||||||
k = to_checksum_address(strip_0x(old_address))
|
k = to_checksum_address(strip_0x(old_address))
|
||||||
balance = self.balances[k]
|
balance = self.balances[k]
|
||||||
logg.debug('found balance {} for address {} phone {}'.format(balance, old_address, phone))
|
logg.debug('found balance {} for address {} phone {}'.format(balance, old_address, phone))
|
||||||
@@ -196,39 +191,39 @@ def opening_balance_tx(self, address, phone, serial):
|
|||||||
logg.debug('generated tx token value {} to {} tx hash {}'.format(decimal_balance, address, tx_hash_hex))
|
logg.debug('generated tx token value {} to {} tx hash {}'.format(decimal_balance, address, tx_hash_hex))
|
||||||
|
|
||||||
tx_path = os.path.join(
|
tx_path = os.path.join(
|
||||||
self.import_dir,
|
self.import_dir,
|
||||||
'txs',
|
'txs',
|
||||||
strip_0x(tx_hash_hex),
|
strip_0x(tx_hash_hex),
|
||||||
)
|
)
|
||||||
|
|
||||||
f = open(tx_path, 'w')
|
f = open(tx_path, 'w')
|
||||||
f.write(strip_0x(o))
|
f.write(strip_0x(o))
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
tx_nonce_path = os.path.join(
|
tx_nonce_path = os.path.join(
|
||||||
self.import_dir,
|
self.import_dir,
|
||||||
'txs',
|
'txs',
|
||||||
'.' + str(tx['nonce']),
|
'.' + str(tx['nonce']),
|
||||||
)
|
)
|
||||||
os.symlink(os.path.realpath(tx_path), tx_nonce_path)
|
os.symlink(os.path.realpath(tx_path), tx_nonce_path)
|
||||||
|
|
||||||
return tx['hash']
|
return tx['hash']
|
||||||
|
|
||||||
|
|
||||||
@celery_app.task(bind=True, base=ImportTask, autoretry_for=(FileNotFoundError,), max_retries=None, default_retry_delay=0.1)
|
@celery_app.task(bind=True, base=ImportTask, autoretry_for=(FileNotFoundError,), max_retries=None,
|
||||||
|
default_retry_delay=0.1)
|
||||||
def send_txs(self, nonce):
|
def send_txs(self, nonce):
|
||||||
|
|
||||||
if nonce == self.count + self.balance_processor.nonce_offset:
|
if nonce == self.count + self.balance_processor.nonce_offset:
|
||||||
logg.info('reached nonce {} (offset {} + count {}) exiting'.format(nonce, self.balance_processor.nonce_offset, self.count))
|
logg.info('reached nonce {} (offset {} + count {}) exiting'.format(nonce, self.balance_processor.nonce_offset,
|
||||||
|
self.count))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
logg.debug('attempt to open symlink for nonce {}'.format(nonce))
|
logg.debug('attempt to open symlink for nonce {}'.format(nonce))
|
||||||
tx_nonce_path = os.path.join(
|
tx_nonce_path = os.path.join(
|
||||||
self.import_dir,
|
self.import_dir,
|
||||||
'txs',
|
'txs',
|
||||||
'.' + str(nonce),
|
'.' + str(nonce),
|
||||||
)
|
)
|
||||||
f = open(tx_nonce_path, 'r')
|
f = open(tx_nonce_path, 'r')
|
||||||
tx_signed_raw_hex = f.read()
|
tx_signed_raw_hex = f.read()
|
||||||
f.close()
|
f.close()
|
||||||
@@ -238,21 +233,20 @@ def send_txs(self, nonce):
|
|||||||
o = raw(add_0x(tx_signed_raw_hex))
|
o = raw(add_0x(tx_signed_raw_hex))
|
||||||
tx_hash_hex = self.balance_processor.conn.do(o)
|
tx_hash_hex = self.balance_processor.conn.do(o)
|
||||||
|
|
||||||
logg.info('sent nonce {} tx hash {}'.format(nonce, tx_hash_hex)) #tx_signed_raw_hex))
|
logg.info('sent nonce {} tx hash {}'.format(nonce, tx_hash_hex)) # tx_signed_raw_hex))
|
||||||
|
|
||||||
nonce += 1
|
nonce += 1
|
||||||
|
|
||||||
queue = self.request.delivery_info.get('routing_key')
|
queue = self.request.delivery_info.get('routing_key')
|
||||||
s = celery.signature(
|
s = celery.signature(
|
||||||
'import_task.send_txs',
|
'import_task.send_txs',
|
||||||
[
|
[
|
||||||
nonce,
|
nonce,
|
||||||
],
|
],
|
||||||
queue=queue,
|
queue=queue,
|
||||||
)
|
)
|
||||||
s.apply_async()
|
s.apply_async()
|
||||||
|
|
||||||
|
|
||||||
return nonce
|
return nonce
|
||||||
|
|
||||||
|
|
||||||
@@ -310,4 +304,3 @@ def set_ussd_data(config: dict, ussd_data: dict):
|
|||||||
# close connections
|
# close connections
|
||||||
db_cursor.close()
|
db_cursor.close()
|
||||||
db_conn.close()
|
db_conn.close()
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ import redis
|
|||||||
from chainlib.chain import ChainSpec
|
from chainlib.chain import ChainSpec
|
||||||
from cic_types.models.person import Person
|
from cic_types.models.person import Person
|
||||||
|
|
||||||
|
# local imports
|
||||||
|
from import_util import get_celery_worker_status
|
||||||
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
logging.basicConfig(level=logging.WARNING)
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
|
|
||||||
@@ -28,11 +31,14 @@ argparser.add_argument('-i', '--chain-spec', dest='i', type=str, help='Chain spe
|
|||||||
argparser.add_argument('--redis-host', dest='redis_host', type=str, help='redis host to use for task submission')
|
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-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('--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-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('--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('--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-host', dest='ussd_host', type=str,
|
||||||
argparser.add_argument('--ussd-port', dest='ussd_port', type=str, help="port to ussd app responsible for processing ussd requests.")
|
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('--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('-q', type=str, default='cic-eth', help='Task queue')
|
||||||
argparser.add_argument('-v', action='store_true', help='Be verbose')
|
argparser.add_argument('-v', action='store_true', help='Be verbose')
|
||||||
@@ -49,13 +55,16 @@ config_dir = args.c
|
|||||||
config = confini.Config(config_dir, os.environ.get('CONFINI_ENV_PREFIX'))
|
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'),
|
||||||
'REDIS_HOST': getattr(args, 'redis_host'),
|
'REDIS_HOST': getattr(args, 'redis_host'),
|
||||||
'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')
|
config.dict_override(args_override, 'cli')
|
||||||
|
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'))
|
celery_app = celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL'))
|
||||||
|
get_celery_worker_status(celery_app=celery_app)
|
||||||
|
|
||||||
redis_host = config.get('REDIS_HOST')
|
redis_host = config.get('REDIS_HOST')
|
||||||
redis_port = config.get('REDIS_PORT')
|
redis_port = config.get('REDIS_PORT')
|
||||||
@@ -65,22 +74,22 @@ r = redis.Redis(redis_host, redis_port, redis_db)
|
|||||||
ps = r.pubsub()
|
ps = r.pubsub()
|
||||||
|
|
||||||
user_new_dir = os.path.join(args.user_dir, 'new')
|
user_new_dir = os.path.join(args.user_dir, 'new')
|
||||||
os.makedirs(user_new_dir)
|
os.makedirs(user_new_dir, exist_ok=True)
|
||||||
|
|
||||||
ussd_data_dir = os.path.join(args.user_dir, 'ussd')
|
ussd_data_dir = os.path.join(args.user_dir, 'ussd')
|
||||||
os.makedirs(ussd_data_dir)
|
os.makedirs(ussd_data_dir, exist_ok=True)
|
||||||
|
|
||||||
preferences_dir = os.path.join(args.user_dir, 'preferences')
|
preferences_dir = os.path.join(args.user_dir, 'preferences')
|
||||||
os.makedirs(os.path.join(preferences_dir, 'meta'))
|
os.makedirs(os.path.join(preferences_dir, 'meta'), exist_ok=True)
|
||||||
|
|
||||||
meta_dir = os.path.join(args.user_dir, 'meta')
|
meta_dir = os.path.join(args.user_dir, 'meta')
|
||||||
os.makedirs(meta_dir)
|
os.makedirs(meta_dir, exist_ok=True)
|
||||||
|
|
||||||
user_old_dir = os.path.join(args.user_dir, 'old')
|
user_old_dir = os.path.join(args.user_dir, 'old')
|
||||||
os.stat(user_old_dir)
|
os.stat(user_old_dir)
|
||||||
|
|
||||||
txs_dir = os.path.join(args.user_dir, 'txs')
|
txs_dir = os.path.join(args.user_dir, 'txs')
|
||||||
os.makedirs(txs_dir)
|
os.makedirs(txs_dir, exist_ok=True)
|
||||||
|
|
||||||
chain_spec = ChainSpec.from_chain_str(config.get('CIC_CHAIN_SPEC'))
|
chain_spec = ChainSpec.from_chain_str(config.get('CIC_CHAIN_SPEC'))
|
||||||
chain_str = str(chain_spec)
|
chain_str = str(chain_spec)
|
||||||
@@ -95,6 +104,7 @@ if ussd_no_ssl is True:
|
|||||||
else:
|
else:
|
||||||
ussd_ssl = True
|
ussd_ssl = True
|
||||||
|
|
||||||
|
|
||||||
def build_ussd_request(phone, host, port, service_code, username, password, ssl=False):
|
def build_ussd_request(phone, host, port, service_code, username, password, ssl=False):
|
||||||
url = 'http'
|
url = 'http'
|
||||||
if ssl:
|
if ssl:
|
||||||
@@ -109,13 +119,13 @@ def build_ussd_request(phone, host, port, service_code, username, password, ssl=
|
|||||||
|
|
||||||
session = uuid.uuid4().hex
|
session = uuid.uuid4().hex
|
||||||
data = {
|
data = {
|
||||||
'sessionId': session,
|
'sessionId': session,
|
||||||
'serviceCode': service_code,
|
'serviceCode': service_code,
|
||||||
'phoneNumber': phone,
|
'phoneNumber': phone,
|
||||||
'text': service_code,
|
'text': service_code,
|
||||||
}
|
}
|
||||||
req = urllib.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')
|
||||||
req.add_header('Content-Type', 'application/x-www-form-urlencoded')
|
req.add_header('Content-Type', 'application/x-www-form-urlencoded')
|
||||||
@@ -150,7 +160,7 @@ if __name__ == '__main__':
|
|||||||
j = 0
|
j = 0
|
||||||
for x in os.walk(user_old_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
|
# handle json containing person object
|
||||||
filepath = os.path.join(x[0], y)
|
filepath = os.path.join(x[0], y)
|
||||||
@@ -164,35 +174,35 @@ if __name__ == '__main__':
|
|||||||
f.close()
|
f.close()
|
||||||
u = Person.deserialize(o)
|
u = Person.deserialize(o)
|
||||||
|
|
||||||
new_address = register_ussd(i, u)
|
register_ussd(i, u)
|
||||||
|
|
||||||
phone_object = phonenumbers.parse(u.tel)
|
phone_object = phonenumbers.parse(u.tel)
|
||||||
phone = phonenumbers.format_number(phone_object, phonenumbers.PhoneNumberFormat.E164)
|
phone = phonenumbers.format_number(phone_object, phonenumbers.PhoneNumberFormat.E164)
|
||||||
|
|
||||||
s_phone = celery.signature(
|
s_phone = celery.signature(
|
||||||
'import_task.resolve_phone',
|
'import_task.resolve_phone',
|
||||||
[
|
[
|
||||||
phone,
|
phone,
|
||||||
],
|
],
|
||||||
queue='cic-import-ussd',
|
queue='cic-import-ussd',
|
||||||
)
|
)
|
||||||
|
|
||||||
s_meta = celery.signature(
|
s_meta = celery.signature(
|
||||||
'import_task.generate_metadata',
|
'import_task.generate_metadata',
|
||||||
[
|
[
|
||||||
phone,
|
phone,
|
||||||
],
|
],
|
||||||
queue='cic-import-ussd',
|
queue='cic-import-ussd',
|
||||||
)
|
)
|
||||||
|
|
||||||
s_balance = celery.signature(
|
s_balance = celery.signature(
|
||||||
'import_task.opening_balance_tx',
|
'import_task.opening_balance_tx',
|
||||||
[
|
[
|
||||||
phone,
|
phone,
|
||||||
i,
|
i,
|
||||||
],
|
],
|
||||||
queue='cic-import-ussd',
|
queue='cic-import-ussd',
|
||||||
)
|
)
|
||||||
|
|
||||||
s_meta.link(s_balance)
|
s_meta.link(s_balance)
|
||||||
s_phone.link(s_meta)
|
s_phone.link(s_meta)
|
||||||
@@ -206,4 +216,3 @@ if __name__ == '__main__':
|
|||||||
if j == batch_size:
|
if j == batch_size:
|
||||||
time.sleep(batch_delay)
|
time.sleep(batch_delay)
|
||||||
j = 0
|
j = 0
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,16 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
# external imports
|
# external imports
|
||||||
from eth_contract_registry import Registry
|
|
||||||
from eth_token_index import TokenUniqueSymbolIndex
|
|
||||||
from chainlib.eth.gas import OverrideGasOracle
|
from chainlib.eth.gas import OverrideGasOracle
|
||||||
from chainlib.eth.nonce import OverrideNonceOracle
|
from chainlib.eth.nonce import OverrideNonceOracle
|
||||||
from eth_erc20 import ERC20
|
|
||||||
from chainlib.eth.tx import (
|
from chainlib.eth.tx import (
|
||||||
count,
|
count,
|
||||||
TxFormat,
|
TxFormat,
|
||||||
)
|
)
|
||||||
|
from celery import Celery
|
||||||
|
from eth_contract_registry import Registry
|
||||||
|
from eth_erc20 import ERC20
|
||||||
|
from eth_token_index import TokenUniqueSymbolIndex
|
||||||
|
|
||||||
logg = logging.getLogger().getChild(__name__)
|
logg = logging.getLogger().getChild(__name__)
|
||||||
|
|
||||||
@@ -18,10 +19,9 @@ logg = logging.getLogger().getChild(__name__)
|
|||||||
class BalanceProcessor:
|
class BalanceProcessor:
|
||||||
|
|
||||||
def __init__(self, conn, chain_spec, registry_address, signer_address, signer):
|
def __init__(self, conn, chain_spec, registry_address, signer_address, signer):
|
||||||
|
|
||||||
self.chain_spec = chain_spec
|
self.chain_spec = chain_spec
|
||||||
self.conn = conn
|
self.conn = conn
|
||||||
#self.signer_address = signer_address
|
# self.signer_address = signer_address
|
||||||
self.registry_address = registry_address
|
self.registry_address = registry_address
|
||||||
|
|
||||||
self.token_index_address = None
|
self.token_index_address = None
|
||||||
@@ -35,7 +35,6 @@ class BalanceProcessor:
|
|||||||
self.gas_oracle = OverrideGasOracle(conn=conn, limit=8000000)
|
self.gas_oracle = OverrideGasOracle(conn=conn, limit=8000000)
|
||||||
|
|
||||||
self.value_multiplier = 1
|
self.value_multiplier = 1
|
||||||
|
|
||||||
|
|
||||||
def init(self, token_symbol):
|
def init(self, token_symbol):
|
||||||
# Get Token registry address
|
# Get Token registry address
|
||||||
@@ -57,16 +56,25 @@ class BalanceProcessor:
|
|||||||
n = tx_factory.parse_decimals(r)
|
n = tx_factory.parse_decimals(r)
|
||||||
self.value_multiplier = 10 ** n
|
self.value_multiplier = 10 ** n
|
||||||
|
|
||||||
|
|
||||||
def get_rpc_tx(self, recipient, value, i):
|
def get_rpc_tx(self, recipient, value, i):
|
||||||
logg.debug('initiating nonce offset {} for recipient {}'.format(self.nonce_offset + i, recipient))
|
logg.debug('initiating nonce offset {} for recipient {}'.format(self.nonce_offset + i, recipient))
|
||||||
nonce_oracle = OverrideNonceOracle(self.signer_address, self.nonce_offset + i)
|
nonce_oracle = OverrideNonceOracle(self.signer_address, self.nonce_offset + i)
|
||||||
tx_factory = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle, gas_oracle=self.gas_oracle)
|
tx_factory = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle, gas_oracle=self.gas_oracle)
|
||||||
return tx_factory.transfer(self.token_address, self.signer_address, recipient, value, tx_format=TxFormat.RLP_SIGNED)
|
return tx_factory.transfer(self.token_address, self.signer_address, recipient, value,
|
||||||
#(tx_hash_hex, o) = tx_factory.transfer(self.token_address, self.signer_address, recipient, value)
|
tx_format=TxFormat.RLP_SIGNED)
|
||||||
#self.conn.do(o)
|
# (tx_hash_hex, o) = tx_factory.transfer(self.token_address, self.signer_address, recipient, value)
|
||||||
#return tx_hash_hex
|
# self.conn.do(o)
|
||||||
|
# return tx_hash_hex
|
||||||
|
|
||||||
def get_decimal_amount(self, value):
|
def get_decimal_amount(self, value):
|
||||||
return value * self.value_multiplier
|
return value * self.value_multiplier
|
||||||
|
|
||||||
|
|
||||||
|
def get_celery_worker_status(celery_app: Celery):
|
||||||
|
inspector = celery_app.control.inspect()
|
||||||
|
availability = inspector.ping()
|
||||||
|
status = {
|
||||||
|
'availability': availability,
|
||||||
|
}
|
||||||
|
logg.debug(f'RUNNING WITH STATUS: {status}')
|
||||||
|
return status
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ approval_escrow_address =
|
|||||||
chain_spec = evm:bloxberg:8996
|
chain_spec = evm:bloxberg:8996
|
||||||
tx_retry_delay =
|
tx_retry_delay =
|
||||||
trust_address = 0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C
|
trust_address = 0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C
|
||||||
user_ussd_svc_service_port=
|
user_ussd_svc_service_port =
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,2 @@
|
|||||||
[eth]
|
[eth]
|
||||||
#ws_provider = ws://localhost:8546
|
|
||||||
#ttp_provider = http://localhost:8545
|
|
||||||
provider = http://localhost:63545
|
provider = http://localhost:63545
|
||||||
gas_provider_address =
|
|
||||||
#chain_id =
|
|
||||||
abi_dir = /usr/local/share/cic/solidity/abi
|
|
||||||
account_accounts_index_writer =
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[pgp]
|
[pgp]
|
||||||
exports_dir = ../contract-migration/testdata/pgp
|
exports_dir = testdata/pgp
|
||||||
private_key_file = privatekeys_meta.asc
|
private_key_file = privatekeys_meta.asc
|
||||||
public_key_file = publickeys_meta.asc
|
public_key_file = publickeys_meta.asc
|
||||||
passphrase = merman
|
passphrase = merman
|
||||||
|
|||||||
@@ -204,9 +204,9 @@ def gen():
|
|||||||
]))
|
]))
|
||||||
if random.randint(0, 1):
|
if random.randint(0, 1):
|
||||||
# fake.local_latitude()
|
# fake.local_latitude()
|
||||||
p.location['latitude'] = (random.random() + 180) - 90
|
p.location['latitude'] = (random.random() * 180) - 90
|
||||||
# fake.local_latitude()
|
# fake.local_latitude()
|
||||||
p.location['longitude'] = (random.random() + 360) - 180
|
p.location['longitude'] = (random.random() * 360) - 179
|
||||||
|
|
||||||
return (old_blockchain_checksum_address, phone, p)
|
return (old_blockchain_checksum_address, phone, p)
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,24 @@
|
|||||||
# syntax = docker/dockerfile:1.2
|
# syntax = docker/dockerfile:1.2
|
||||||
FROM python:3.8.6-slim-buster as compile-image
|
FROM registry.gitlab.com/grassrootseconomics/cic-base-images:python-3.8.6-dev-5ab8bf45
|
||||||
|
|
||||||
WORKDIR /root
|
WORKDIR /root
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y --no-install-recommends git gcc g++ libpq-dev gawk jq telnet wget openssl iputils-ping gnupg socat bash procps make python2 cargo
|
|
||||||
|
|
||||||
RUN mkdir -vp /usr/local/etc/cic
|
RUN mkdir -vp /usr/local/etc/cic
|
||||||
|
|
||||||
|
COPY data-seeding/package.json \
|
||||||
|
data-seeding/package-lock.json \
|
||||||
|
.
|
||||||
|
|
||||||
|
RUN --mount=type=cache,mode=0755,target=/root/node_modules npm install
|
||||||
|
|
||||||
COPY data-seeding/requirements.txt .
|
COPY data-seeding/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 --mount=type=cache,mode=0755,target=/root/.cache/pip pip install \
|
||||||
|
--extra-index-url $GITLAB_PYTHON_REGISTRY \
|
||||||
|
--extra-index-url $EXTRA_INDEX_URL -r requirements.txt
|
||||||
|
|
||||||
COPY data-seeding/ .
|
COPY data-seeding/ .
|
||||||
|
|
||||||
ARG EXTRA_INDEX_URL="https://pip.grassrootseconomics.net:8433"
|
|
||||||
RUN pip install --extra-index-url $EXTRA_INDEX_URL -r requirements.txt
|
|
||||||
|
|
||||||
|
|
||||||
ENTRYPOINT [ ]
|
ENTRYPOINT [ ]
|
||||||
|
|||||||
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 data-seeding/package.json \
|
||||||
|
data-seeding/package-lock.json \
|
||||||
|
.
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
COPY data-seeding/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 data-seeding/ .
|
||||||
|
|
||||||
|
ENTRYPOINT [ ]
|
||||||
@@ -18,25 +18,24 @@ from hexathon import (
|
|||||||
add_0x,
|
add_0x,
|
||||||
)
|
)
|
||||||
from chainsyncer.backend.memory import MemBackend
|
from chainsyncer.backend.memory import MemBackend
|
||||||
from chainsyncer.driver import HeadSyncer
|
from chainsyncer.driver.head import HeadSyncer
|
||||||
from chainlib.eth.connection import EthHTTPConnection
|
from chainlib.eth.connection import EthHTTPConnection
|
||||||
from chainlib.eth.block import (
|
from chainlib.eth.block import (
|
||||||
block_latest,
|
block_latest,
|
||||||
block_by_number,
|
|
||||||
Block,
|
|
||||||
)
|
)
|
||||||
from chainlib.hash import keccak256_string_to_hex
|
from chainlib.hash import keccak256_string_to_hex
|
||||||
from chainlib.eth.address import to_checksum_address
|
from chainlib.eth.address import to_checksum_address
|
||||||
from chainlib.eth.gas import OverrideGasOracle
|
from chainlib.eth.gas import OverrideGasOracle
|
||||||
from chainlib.eth.nonce import RPCNonceOracle
|
from chainlib.eth.nonce import RPCNonceOracle
|
||||||
from chainlib.eth.tx import TxFactory
|
from chainlib.eth.tx import TxFactory
|
||||||
from chainlib.jsonrpc import jsonrpc_template
|
from chainlib.jsonrpc import JSONRPCRequest
|
||||||
from chainlib.eth.error import EthException
|
from chainlib.eth.error import EthException
|
||||||
from chainlib.chain import ChainSpec
|
from chainlib.chain import ChainSpec
|
||||||
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
|
||||||
from cic_types.models.person import Person
|
from cic_types.models.person import Person
|
||||||
from eth_erc20 import ERC20
|
from eth_erc20 import ERC20
|
||||||
|
from cic_base.eth.syncer import chain_interface
|
||||||
|
|
||||||
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
logging.basicConfig(level=logging.WARNING)
|
||||||
@@ -75,7 +74,7 @@ args_override = {
|
|||||||
'CIC_CHAIN_SPEC': getattr(args, 'i'),
|
'CIC_CHAIN_SPEC': getattr(args, 'i'),
|
||||||
'ETH_PROVIDER': getattr(args, 'p'),
|
'ETH_PROVIDER': getattr(args, 'p'),
|
||||||
'CIC_REGISTRY_ADDRESS': getattr(args, 'r'),
|
'CIC_REGISTRY_ADDRESS': getattr(args, 'r'),
|
||||||
'KEYSTORE_FILE_PATH': getattr(args, 'key-file')
|
'KEYSTORE_FILE_PATH': getattr(args, 'y')
|
||||||
}
|
}
|
||||||
config.dict_override(args_override, 'cli flag')
|
config.dict_override(args_override, 'cli flag')
|
||||||
config.censor('PASSWORD', 'DATABASE')
|
config.censor('PASSWORD', 'DATABASE')
|
||||||
@@ -184,27 +183,6 @@ class Handler:
|
|||||||
# logg.error('key record not found in imports: {}'.format(e).ljust(200))
|
# logg.error('key record not found in imports: {}'.format(e).ljust(200))
|
||||||
|
|
||||||
|
|
||||||
#class BlockGetter:
|
|
||||||
#
|
|
||||||
# def __init__(self, conn, gas_oracle, nonce_oracle, chain_spec):
|
|
||||||
# self.conn = conn
|
|
||||||
# self.tx_factory = ERC20(signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle, chain_id=chain_id)
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# def get(self, n):
|
|
||||||
# o = block_by_number(n)
|
|
||||||
# r = self.conn.do(o)
|
|
||||||
# b = None
|
|
||||||
# try:
|
|
||||||
# b = Block(r)
|
|
||||||
# except TypeError as e:
|
|
||||||
# if r == None:
|
|
||||||
# logg.debug('block not found {}'.format(n))
|
|
||||||
# else:
|
|
||||||
# logg.error('block retrieve error {}'.format(e))
|
|
||||||
# return b
|
|
||||||
|
|
||||||
|
|
||||||
def progress_callback(block_number, tx_index):
|
def progress_callback(block_number, tx_index):
|
||||||
sys.stdout.write(str(block_number).ljust(200) + "\n")
|
sys.stdout.write(str(block_number).ljust(200) + "\n")
|
||||||
|
|
||||||
@@ -225,11 +203,13 @@ def main():
|
|||||||
data = add_0x(registry_addressof_method)
|
data = add_0x(registry_addressof_method)
|
||||||
data += eth_abi.encode_single('bytes32', b'TokenRegistry').hex()
|
data += eth_abi.encode_single('bytes32', b'TokenRegistry').hex()
|
||||||
txf.set_code(tx, data)
|
txf.set_code(tx, data)
|
||||||
|
|
||||||
o = jsonrpc_template()
|
j = JSONRPCRequest()
|
||||||
|
o = j.template()
|
||||||
o['method'] = 'eth_call'
|
o['method'] = 'eth_call'
|
||||||
o['params'].append(txf.normalize(tx))
|
o['params'].append(txf.normalize(tx))
|
||||||
o['params'].append('latest')
|
o['params'].append('latest')
|
||||||
|
o = j.finalize(o)
|
||||||
r = conn.do(o)
|
r = conn.do(o)
|
||||||
token_index_address = to_checksum_address(eth_abi.decode_single('address', bytes.fromhex(strip_0x(r))))
|
token_index_address = to_checksum_address(eth_abi.decode_single('address', bytes.fromhex(strip_0x(r))))
|
||||||
logg.info('found token index address {}'.format(token_index_address))
|
logg.info('found token index address {}'.format(token_index_address))
|
||||||
@@ -243,10 +223,11 @@ def main():
|
|||||||
z = h.digest()
|
z = h.digest()
|
||||||
data += eth_abi.encode_single('bytes32', z).hex()
|
data += eth_abi.encode_single('bytes32', z).hex()
|
||||||
txf.set_code(tx, data)
|
txf.set_code(tx, data)
|
||||||
o = jsonrpc_template()
|
o = j.template()
|
||||||
o['method'] = 'eth_call'
|
o['method'] = 'eth_call'
|
||||||
o['params'].append(txf.normalize(tx))
|
o['params'].append(txf.normalize(tx))
|
||||||
o['params'].append('latest')
|
o['params'].append('latest')
|
||||||
|
o = j.finalize(o)
|
||||||
r = conn.do(o)
|
r = conn.do(o)
|
||||||
try:
|
try:
|
||||||
sarafu_token_address = to_checksum_address(eth_abi.decode_single('address', bytes.fromhex(strip_0x(r))))
|
sarafu_token_address = to_checksum_address(eth_abi.decode_single('address', bytes.fromhex(strip_0x(r))))
|
||||||
@@ -300,7 +281,7 @@ def main():
|
|||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
syncer_backend.set(block_offset, 0)
|
syncer_backend.set(block_offset, 0)
|
||||||
syncer = HeadSyncer(syncer_backend, block_callback=progress_callback)
|
syncer = HeadSyncer(syncer_backend, chain_interface, block_callback=progress_callback)
|
||||||
handler = Handler(conn, chain_spec, user_dir, balances, sarafu_token_address, signer, gas_oracle, nonce_oracle)
|
handler = Handler(conn, chain_spec, user_dir, balances, sarafu_token_address, signer, gas_oracle, nonce_oracle)
|
||||||
syncer.add_filter(handler)
|
syncer.add_filter(handler)
|
||||||
syncer.loop(1, conn)
|
syncer.loop(1, conn)
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ config.process()
|
|||||||
args_override = {
|
args_override = {
|
||||||
'CIC_REGISTRY_ADDRESS': getattr(args, 'r'),
|
'CIC_REGISTRY_ADDRESS': getattr(args, 'r'),
|
||||||
'CIC_CHAIN_SPEC': getattr(args, 'i'),
|
'CIC_CHAIN_SPEC': getattr(args, 'i'),
|
||||||
'KEYSTORE_FILE_PATH': getattr(args, 'key-file')
|
'KEYSTORE_FILE_PATH': getattr(args, 'y')
|
||||||
}
|
}
|
||||||
config.dict_override(args_override, 'cli')
|
config.dict_override(args_override, 'cli')
|
||||||
config.add(args.user_dir, '_USERDIR', True)
|
config.add(args.user_dir, '_USERDIR', True)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
cic-base[full_graph]==0.1.2b15
|
sarafu-faucet==0.0.4a1
|
||||||
sarafu-faucet==0.0.3a3
|
cic-eth[tools]==0.12.0a1
|
||||||
cic-eth==0.11.0b16
|
cic-types==0.1.0a13
|
||||||
cic-types==0.1.0a11
|
crypto-dev-signer==0.4.14b6
|
||||||
crypto-dev-signer==0.4.14b3
|
|
||||||
|
|||||||
83
apps/data-seeding/testdata/pgp/alice.priv.asc
vendored
Normal file
83
apps/data-seeding/testdata/pgp/alice.priv.asc
vendored
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
=zMNq
|
||||||
|
-----END PGP PRIVATE KEY BLOCK-----
|
||||||
41
apps/data-seeding/testdata/pgp/alice.pub.asc
vendored
Normal file
41
apps/data-seeding/testdata/pgp/alice.pub.asc
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
xgjhMwawpFV3APdc0dOIvUdZAFQ=
|
||||||
|
=BKz+
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
83
apps/data-seeding/testdata/pgp/bob.priv.asc
vendored
Normal file
83
apps/data-seeding/testdata/pgp/bob.priv.asc
vendored
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
=qmcx
|
||||||
|
-----END PGP PRIVATE KEY BLOCK-----
|
||||||
41
apps/data-seeding/testdata/pgp/bob.pub.asc
vendored
Normal file
41
apps/data-seeding/testdata/pgp/bob.pub.asc
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
n0OSM7kpK5v6VPdtByaN6w==
|
||||||
|
=EmWr
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
83
apps/data-seeding/testdata/pgp/ge.priv.asc
vendored
Normal file
83
apps/data-seeding/testdata/pgp/ge.priv.asc
vendored
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
=B12U
|
||||||
|
-----END PGP PRIVATE KEY BLOCK-----
|
||||||
41
apps/data-seeding/testdata/pgp/ge.pub.asc
vendored
Normal file
41
apps/data-seeding/testdata/pgp/ge.pub.asc
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
32d1dwRCBUARSk9jwmwsycaIC9eupit1mLY=
|
||||||
|
=vg+T
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
241
apps/data-seeding/testdata/pgp/privatekeys_meta.asc
vendored
Normal file
241
apps/data-seeding/testdata/pgp/privatekeys_meta.asc
vendored
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
1VrzRbOS5ymseDJcjejtMxuCOuSTN9R5KuQ=
|
||||||
|
=VqO+
|
||||||
|
-----END PGP PRIVATE KEY BLOCK-----
|
||||||
114
apps/data-seeding/testdata/pgp/publickeys.asc
vendored
Normal file
114
apps/data-seeding/testdata/pgp/publickeys.asc
vendored
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
wmwsycaIC9eupit1mLY=
|
||||||
|
=1aEW
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
151
apps/data-seeding/testdata/pgp/publickeys_meta.asc
vendored
Normal file
151
apps/data-seeding/testdata/pgp/publickeys_meta.asc
vendored
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
KuNFGWsKI1qTd1aEMRQzT4s+JJM=
|
||||||
|
=8257
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
29
apps/data-seeding/testdata/ssl/client.crt
vendored
Normal file
29
apps/data-seeding/testdata/ssl/client.crt
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIE4DCCAsgCAQMwDQYJKoZIhvcNAQELBQAwgaExCzAJBgNVBAYTAktZMQ8wDQYD
|
||||||
|
VQQIDAZLaWxpZmkxEDAOBgNVBAcMB01uYXJhbmkxHTAbBgNVBAoMFEdyYXNzcm9v
|
||||||
|
dHMgRWNvbm9taWNzMQswCQYDVQQLDAJIUTEgMB4GA1UEAwwXZ3Jhc3Nyb290c2Vj
|
||||||
|
b25vbWljcy5vcmcxITAfBgkqhkiG9w0BCQEWEndpbGxAZ3Jhc3NlY29uLm9yZzAe
|
||||||
|
Fw0yMDAzMjgwMDE3MzRaFw0yMjEyMjQwMDE3MzRaMIHJMQswCQYDVQQGEwJNTjEU
|
||||||
|
MBIGA1UECgwLVGhlIE1vbmdvbHMxGzAZBgNVBAMMEnd3dy51bGFhbmJhYXRhci5t
|
||||||
|
bjEVMBMGA1UEKQwMS2h1YmxhaSBLaGFuMR8wHQYJKoZIhvcNAQkBFhBmb29Ac2Vj
|
||||||
|
aG9zdC5pbmZvMRAwDgYDVQQqDAdLaHVibGFpMQ0wCwYDVQQEDARLaGFuMRQwEgYD
|
||||||
|
VQQHDAtVbGFhbmJhYXRhcjEYMBYGA1UECAwPVGhlIFdob2xlIFdvcmxkMIIBIjAN
|
||||||
|
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtT1IP3Ls0ha5cX5RiMnyjPzjGjvS
|
||||||
|
GrWhDU579+qQ4T4k9ONq8fxNv95ZdxkccUyXZVR24pq+ALxmV65soCAGNJHb00lE
|
||||||
|
XWY3mQ9Jd10pC8UQPqfQ4Ez/J0Q+oIwpTdUCQStIe8QHz6sh8AVmPrTKWphjD5Up
|
||||||
|
PuWjFz4qs6h46hzNDoc90HPr4rqnxzBIo4Phs4a8/46FWvphufybKgorz+B5uWeB
|
||||||
|
Uzi3fOOKNAk8UmZK8fWB8DMIm8NFcOZV7METJmMBH1v5sY6zQWNBOHJmin02VkCW
|
||||||
|
rie16Ll+vfWp1jQEh442qgBFk0NiZBoGWJamYa7RmwH5d4LPGLiDUVgsnwIDAQAB
|
||||||
|
MA0GCSqGSIb3DQEBCwUAA4ICAQBy0DIHBXVDPy4dTrmjcr78ytxy26p+8kjlzTQF
|
||||||
|
w9a9F+CPsRNV4KAmXJKUlyBTPiVocVhhSmj2Mz9OtI9FFWkSleKzxUtWlDEjIwGj
|
||||||
|
PRqWKhj/Y8LJsgdcUGCBtraBMCD5D1xyNx3n+zwhNp+HNB4ThVlV0iGCoOOq7XZu
|
||||||
|
4QHwkuy0ILcXt3NU6tWNXXsP544BxsCFHgyu+Ks+JkJzSFzGe+ybEMblXyHJZtOC
|
||||||
|
uyCLQN2Uo44Mtdo728p00mRGSFlouFfQWMu/7lQPNYouQ7XiLXy+mNeNN0CYUjpg
|
||||||
|
a7wfPExMljJEkgYyWT4JMuTB5RTsjQqw41aGtfy021L7yCZnVR2GG3pmeRQtqe4r
|
||||||
|
+V+WHV3YOkW5vObd5RE3ykntFkbrZNodBzxp6qKF4qsfqQH6WJFVXh0b36VmOdSa
|
||||||
|
qWxidz+SeCI379nemy93bcusQxRDXc+j5hbpW2pTtz2uxN5Y86DWEdSjpmiu6ExT
|
||||||
|
eBUyoK/5Zes/oZ3R9vj0V9jhpGN1/FahkXfkjZcuwXXFXuwk8rODU9DKGOEqFPKI
|
||||||
|
P/MZSVkfNvkBhiNozBXx1X/vJ2QoQKqE9zPfXlmvZkLiUaMjqd+h3qRe0vqXlQU+
|
||||||
|
ZH8NrKTi5xS/2VGtz4ksGlQp7GMZ0XFWL23BGhUfQVRLKMPCqta+GTuJUo3r5HVL
|
||||||
|
YiI4dw==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
30
apps/data-seeding/testdata/ssl/client.key
vendored
Normal file
30
apps/data-seeding/testdata/ssl/client.key
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
Proc-Type: 4,ENCRYPTED
|
||||||
|
DEK-Info: AES-256-CBC,A748148F1C16F6129F04A346A324170A
|
||||||
|
|
||||||
|
k5K2EMTBDsaa9LqsnWnDV2Ocd14fZ6lXsNBoPZR1axrOV+zNZtDDIQwFP0FHmTN6
|
||||||
|
KrxDuDvPjkhoebMiLkRyWc6d4fslWQnr3vASi8gONYGT3pXKbuPNEMSXJeRfxvzC
|
||||||
|
CAcSh9rItcVxKv7m8+vuUWUy8m6TGBLRpDwiYf/9KTjGaPO2fnDBLHPlBuHVEmQW
|
||||||
|
xa0MOknleWnMucGMAtNdsiOVULgyljnoexgbES0VAosegnCKaRA5mRt47V0XUFDl
|
||||||
|
cFxXsHlZ4Wo4R9BowkWhpxX+IBVBmr1Rbmhkl8Z/k3SWfmAd2PNqHckl4oZsG0NN
|
||||||
|
kfi/x5RvMFXGwfW0q5XK/4oK1KbxV7UTn/lozkyvixSWDrN+2jETNCJyL//oXUcS
|
||||||
|
ZTr1+qic92fAAonx1JkX1QwQlNTb0ogmgpJzvAKqGqlNpSL3D0xySNTsSM0fEeZV
|
||||||
|
1qEnWTp1WpoyxG1CeiV0MDN9wkh9aV+KYm0FFo8PEqG6L1jsVNJKMtySeCXmWETK
|
||||||
|
S6iUBwiNf8atQwERfWx0wqSwHtJs9+zqUasskqYWJcO9T3TGqdc8UBaeVGAGdWFF
|
||||||
|
soGsBqrVyU8TEAuK6UReJyFQtHqXbm7kFIJ8J6fgc/QG4Dhy4laBKpR5Lg1W3fCa
|
||||||
|
g+o4OvkWr0Mvu0/y528qL0cqb3JoxvAtsZ8cHiiy1g3AiSr9ehlvtVboyg1ViP5d
|
||||||
|
cZZyU0NaeEUYOIULeBap4LNUBPQUSN5lw15C7N/reI8uuTNp8u8/6ITXKH3tknJr
|
||||||
|
n6Jhd6uFuYNImRhHgQ5rKgai5+Nhc6RqdO5K05fVMt8wIng5RkShQzQEZtaynWyg
|
||||||
|
3VbmJrKXjYesMxYFuKYP4efEVH/9tUeHiqlgVBF2N2Ntd4vKYied3mllthAo8BVC
|
||||||
|
0S0A+cZ2K65MKSoh/FHxxqfXo3AF6dL58DC+9jnzhKNgErVSTti0/Ps6pxrloNuN
|
||||||
|
ILUVeUQNhVlZu7KpJHININCnicohj8wAJDVZo7bb3iZfRGDIAFfgKuEALk+CRd0H
|
||||||
|
D6PukualFGd9w+KDLmUVdpkUTq9+UaZcJMXqGAN1ihIz44Xvk4QgFRN+9Szz4HbL
|
||||||
|
j5rTNqRmXjWjPahk90D/cOQuuE81GsVdiLnFzEacAlDGoGgV+Wcr/lQ06H099Hz1
|
||||||
|
v9hSwXoI+EbeQTjoqenQV62V7wuOiAKg3SpekGsYAsuuPElCBwYGTzWvotf9BBFe
|
||||||
|
LxhfVTCXD1cOQo3pgC8nHBwQSJ6TEXMrR52lgIkOZq/EPhPAYyO5A6ab2tKD1Zah
|
||||||
|
7qlkDDov7f4eTJrXfPnOu/tl3voN+VOxVbxFqsJuMPRCDc/DI18mOi+4yeUFK22W
|
||||||
|
pOCa+Etv7tGa3KlOuU/VWQfGTsICC8ejCIBgwmcbJ5HndEtzrPQv0ESziIcy/ybr
|
||||||
|
zkmlKJ7n7MZLNx/if5Ly9rxg+Y1al5JkOWpIqGKIhP075M2H9Kcg08TqHY6YoG5w
|
||||||
|
eJuudcyosGggxo/oTCCPrHNnPSvaauaZRynF02AQ1hle83V7T1Sy0jbtoGRXM7Hq
|
||||||
|
7AyQDLAcCregAkUuCMF/pktcJLQ2rY738RzNyaR3OiaTgKjko553QkciLP28qwZh
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user