Compare commits

...
34 changed files with 335 additions and 329 deletions
@@ -26,7 +26,7 @@ from chainlib.eth.block import (
from hexathon import ( from hexathon import (
strip_0x, strip_0x,
) )
from chainsyncer.backend import SyncerBackend from chainsyncer.backend.sql import SQLBackend
from chainsyncer.driver import ( from chainsyncer.driver import (
HeadSyncer, HeadSyncer,
HistorySyncer, HistorySyncer,
@@ -71,13 +71,13 @@ def main():
syncers = [] syncers = []
#if SyncerBackend.first(chain_spec): #if SQLBackend.first(chain_spec):
# backend = SyncerBackend.initial(chain_spec, block_offset) # backend = SQLBackend.initial(chain_spec, block_offset)
syncer_backends = SyncerBackend.resume(chain_spec, block_offset) syncer_backends = SQLBackend.resume(chain_spec, block_offset)
if len(syncer_backends) == 0: if len(syncer_backends) == 0:
logg.info('found no backends to resume') logg.info('found no backends to resume')
syncers.append(SyncerBackend.initial(chain_spec, block_offset)) syncers.append(SQLBackend.initial(chain_spec, block_offset))
else: else:
for syncer_backend in syncer_backends: for syncer_backend in syncer_backends:
logg.info('resuming sync session {}'.format(syncer_backend)) logg.info('resuming sync session {}'.format(syncer_backend))
@@ -85,7 +85,7 @@ def main():
for syncer_backend in syncer_backends: for syncer_backend in syncer_backends:
syncers.append(HistorySyncer(syncer_backend)) syncers.append(HistorySyncer(syncer_backend))
syncer_backend = SyncerBackend.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))
trusted_addresses_src = config.get('CIC_TRUST_ADDRESS') trusted_addresses_src = config.get('CIC_TRUST_ADDRESS')
+3
View File
@@ -47,6 +47,9 @@ RUN git clone https://gitlab.com/grassrootseconomics/cic-contracts.git && \
mkdir -p /usr/local/share/cic/solidity && \ mkdir -p /usr/local/share/cic/solidity && \
cp -R cic-contracts/abis /usr/local/share/cic/solidity/abi cp -R cic-contracts/abis /usr/local/share/cic/solidity/abi
COPY cic-cache/docker/start_tracker.sh ./start_tracker.sh
COPY cic-cache/docker/db.sh ./db.sh
RUN chmod 755 ./*.sh
# Tracker # Tracker
# ENTRYPOINT ["/usr/local/bin/cic-cache-tracker", "-vv"] # ENTRYPOINT ["/usr/local/bin/cic-cache-tracker", "-vv"]
# Server # Server
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash
set -e
>&2 echo executing database migration
python scripts/migrate.py -c /usr/local/etc/cic-cache --migrations-dir /usr/local/share/cic-cache/alembic -vv
set +e
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
. ./db.sh
/usr/local/bin/cic-cache-trackerd $@
+3 -4
View File
@@ -1,13 +1,12 @@
cic-base~=0.1.2a66 cic-base~=0.1.2a77
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.4a13 cic-eth-registry~=0.5.4a16
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
chainlib~=0.0.2a10 chainsyncer[sql]~=0.0.2a2
chainsyncer[sql]~=0.0.2a1
@@ -15,7 +15,6 @@ from cic_eth_registry import CICRegistry
from chainlib.chain import ChainSpec from chainlib.chain import ChainSpec
from chainlib.eth.tx import unpack from chainlib.eth.tx import unpack
from chainlib.connection import RPCConnection from chainlib.connection import RPCConnection
from chainsyncer.error import SyncDone
from hexathon import strip_0x from hexathon import strip_0x
from chainqueue.db.enum import ( from chainqueue.db.enum import (
StatusEnum, StatusEnum,
@@ -153,10 +152,7 @@ class DispatchSyncer:
def main(): def main():
syncer = DispatchSyncer(chain_spec) syncer = DispatchSyncer(chain_spec)
conn = RPCConnection.connect(chain_spec, 'default') conn = RPCConnection.connect(chain_spec, 'default')
try: syncer.loop(conn, float(config.get('DISPATCHER_LOOP_INTERVAL')))
syncer.loop(conn, float(config.get('DISPATCHER_LOOP_INTERVAL')))
except SyncDone as e:
sys.stderr.write("dispatcher done at block {}\n".format(e))
sys.exit(0) sys.exit(0)
@@ -26,7 +26,7 @@ from chainlib.eth.block import (
from hexathon import ( from hexathon import (
strip_0x, strip_0x,
) )
from chainsyncer.backend import SyncerBackend from chainsyncer.backend.sql import SQLBackend
from chainsyncer.driver import ( from chainsyncer.driver import (
HeadSyncer, HeadSyncer,
HistorySyncer, HistorySyncer,
@@ -88,18 +88,18 @@ def main():
syncers = [] syncers = []
#if SyncerBackend.first(chain_spec): #if SQLBackend.first(chain_spec):
# backend = SyncerBackend.initial(chain_spec, block_offset) # backend = SQLBackend.initial(chain_spec, block_offset)
syncer_backends = SyncerBackend.resume(chain_spec, block_offset) syncer_backends = SQLBackend.resume(chain_spec, block_offset)
if len(syncer_backends) == 0: if len(syncer_backends) == 0:
logg.info('found no backends to resume') logg.info('found no backends to resume')
syncer_backends.append(SyncerBackend.initial(chain_spec, block_offset)) syncer_backends.append(SQLBackend.initial(chain_spec, block_offset))
else: else:
for syncer_backend in syncer_backends: for syncer_backend in syncer_backends:
logg.info('resuming sync session {}'.format(syncer_backend)) logg.info('resuming sync session {}'.format(syncer_backend))
syncer_backends.append(SyncerBackend.live(chain_spec, block_offset+1)) syncer_backends.append(SQLBackend.live(chain_spec, block_offset+1))
for syncer_backend in syncer_backends: for syncer_backend in syncer_backends:
try: try:
+1 -1
View File
@@ -4,7 +4,7 @@ import datetime
# external imports # external imports
from chainsyncer.driver import HeadSyncer from chainsyncer.driver import HeadSyncer
from chainsyncer.backend import MemBackend from chainsyncer.backend.memory import MemBackend
from chainsyncer.error import NoBlockForYou from chainsyncer.error import NoBlockForYou
from chainlib.eth.block import ( from chainlib.eth.block import (
block_by_number, block_by_number,
+1 -1
View File
@@ -10,7 +10,7 @@ version = (
0, 0,
11, 11,
0, 0,
'beta.1', 'beta.3',
) )
version_object = semver.VersionInfo( version_object = semver.VersionInfo(
+2 -1
View File
@@ -29,7 +29,8 @@ RUN /usr/local/bin/python -m pip install --upgrade pip
# python merge_requirements.py | tee merged_requirements.txt # python merge_requirements.py | tee merged_requirements.txt
#RUN cd cic-base && \ #RUN cd cic-base && \
# pip install $pip_extra_index_url_flag -r ./merged_requirements.txt # pip install $pip_extra_index_url_flag -r ./merged_requirements.txt
RUN pip install $pip_extra_index_url_flag cic-base[full_graph]==0.1.2a62 RUN pip install $pip_extra_index_url_flag cic-base[full_graph]==0.1.2a76
RUN pip install $pip_extra_index_url_flag chainsyncer~=0.0.2a2
COPY cic-eth/scripts/ scripts/ COPY cic-eth/scripts/ scripts/
COPY cic-eth/setup.cfg cic-eth/setup.py ./ COPY cic-eth/setup.cfg cic-eth/setup.py ./
+3 -3
View File
@@ -1,8 +1,8 @@
cic-base~=0.1.2a62 cic-base~=0.1.2a67
celery==4.4.7 celery==4.4.7
crypto-dev-signer~=0.4.14a17 crypto-dev-signer~=0.4.14a17
confini~=0.3.6rc3 confini~=0.3.6rc3
cic-eth-registry~=0.5.4a12 cic-eth-registry~=0.5.4a13
#cic-bancor~=0.0.6 #cic-bancor~=0.0.6
redis==3.5.3 redis==3.5.3
alembic==1.4.2 alembic==1.4.2
@@ -18,7 +18,7 @@ moolb~=0.1.1b2
eth-address-index~=0.1.1a7 eth-address-index~=0.1.1a7
chainlib~=0.0.2a5 chainlib~=0.0.2a5
hexathon~=0.0.1a7 hexathon~=0.0.1a7
chainsyncer~=0.0.1a21 chainsyncer[sql]~=0.0.2a2
chainqueue~=0.0.1a7 chainqueue~=0.0.1a7
pysha3==1.0.2 pysha3==1.0.2
coincurve==15.0.0 coincurve==15.0.0
+7
View File
@@ -11,7 +11,14 @@ REGION=KE
[ussd] [ussd]
MENU_FILE=/usr/src/data/ussd_menu.json MENU_FILE=/usr/src/data/ussd_menu.json
user =
pass =
[statemachine] [statemachine]
STATES=/usr/src/cic-ussd/states/ STATES=/usr/src/cic-ussd/states/
TRANSITIONS=/usr/src/cic-ussd/transitions/ TRANSITIONS=/usr/src/cic-ussd/transitions/
[client]
host =
port =
ssl =
+121 -2
View File
@@ -1,7 +1,126 @@
# standard imports
import json
import logging
import os
from typing import Dict, Union
# third-part imports
import requests
from cic_types.models.person import generate_metadata_pointer, Person
# local imports
from cic_ussd.metadata import make_request
from cic_ussd.metadata.signer import Signer
from cic_ussd.redis import cache_data
from cic_ussd.error import MetadataStoreError
logg = logging.getLogger().getChild(__name__)
class Metadata: class Metadata:
""" """
:cvar base_url: :cvar base_url: The base url or the metadata server.
:type base_url: :type base_url: str
""" """
base_url = None base_url = None
def metadata_http_error_handler(result: requests.Response):
""" This function handles and appropriately raises errors from http requests interacting with the metadata server.
:param result: The response object from a http request.
:type result: requests.Response
"""
status_code = result.status_code
if 100 <= status_code < 200:
raise MetadataStoreError(f'Informational errors: {status_code}, reason: {result.reason}')
elif 300 <= status_code < 400:
raise MetadataStoreError(f'Redirect Issues: {status_code}, reason: {result.reason}')
elif 400 <= status_code < 500:
raise MetadataStoreError(f'Client Error: {status_code}, reason: {result.reason}')
elif 500 <= status_code < 600:
raise MetadataStoreError(f'Server Error: {status_code}, reason: {result.reason}')
class MetadataRequestsHandler(Metadata):
def __init__(self, cic_type: str, identifier: bytes, engine: str = 'pgp'):
"""
:param cic_type: The salt value with which to hash a specific metadata identifier.
:type cic_type: str
:param engine: Encryption used for sending data to the metadata server.
:type engine: str
:param identifier: A unique element of data in bytes necessary for creating a metadata pointer.
:type identifier: bytes
"""
self.cic_type = cic_type
self.engine = engine
self.headers = {
'X-CIC-AUTOMERGE': 'server',
'Content-Type': 'application/json'
}
self.identifier = identifier
self.metadata_pointer = generate_metadata_pointer(
identifier=self.identifier,
cic_type=self.cic_type
)
if self.base_url:
self.url = os.path.join(self.base_url, self.metadata_pointer)
def create(self, data: Union[Dict, str]):
""" This function is responsible for posting data to the metadata server with a corresponding metadata pointer
for storage.
:param data: The data to be stored in the metadata server.
:type data: dict|str
"""
data = json.dumps(data).encode('utf-8')
result = make_request(method='POST', url=self.url, data=data, headers=self.headers)
metadata_http_error_handler(result=result)
metadata = result.content
self.edit(data=metadata)
def edit(self, data: bytes):
""" This function is responsible for editing data in the metadata server corresponding to a unique pointer.
:param data: The data to be edited in the metadata server.
:type data: bytes
"""
cic_meta_signer = Signer()
signature = cic_meta_signer.sign_digest(data=data)
algorithm = cic_meta_signer.get_operational_key().get('algo')
decoded_data = data.decode('utf-8')
formatted_data = {
'm': data.decode('utf-8'),
's': {
'engine': self.engine,
'algo': algorithm,
'data': signature,
'digest': json.loads(data).get('digest'),
}
}
formatted_data = json.dumps(formatted_data).encode('utf-8')
result = make_request(method='PUT', url=self.url, data=formatted_data, headers=self.headers)
logg.info(f'signed metadata submission status: {result.status_code}.')
metadata_http_error_handler(result=result)
try:
decoded_identifier = self.identifier.decode("utf-8")
except UnicodeDecodeError:
decoded_identifier = self.identifier.hex()
logg.info(f'identifier: {decoded_identifier}. metadata pointer: {self.metadata_pointer} set to: {decoded_data}.')
def query(self):
"""This function is responsible for querying the metadata server for data corresponding to a unique pointer."""
result = make_request(method='GET', url=self.url)
metadata_http_error_handler(result=result)
response_data = result.content
data = json.loads(response_data.decode('utf-8'))
if result.status_code == 200 and self.cic_type == 'cic.person':
person = Person()
deserialized_person = person.deserialize(person_data=json.loads(data))
data = json.dumps(deserialized_person.serialize())
cache_data(self.metadata_pointer, data=data)
logg.debug(f'caching: {data} with key: {self.metadata_pointer}')
+12
View File
@@ -0,0 +1,12 @@
# standard imports
# third-party imports
# local imports
from .base import MetadataRequestsHandler
class PersonMetadata(MetadataRequestsHandler):
def __init__(self, identifier: bytes):
super().__init__(cic_type='cic.person', identifier=identifier)
+4 -76
View File
@@ -1,85 +1,13 @@
# standard imports # standard imports
import json
import logging import logging
import os
# external imports # external imports
import requests
from cic_types.models.person import generate_metadata_pointer
from cic_ussd.metadata import make_request
from cic_ussd.metadata.signer import Signer
# local imports # local imports
from cic_ussd.error import MetadataStoreError from .base import MetadataRequestsHandler
from .base import Metadata
logg = logging.getLogger().getChild(__name__)
class PhonePointerMetadata(Metadata): class PhonePointerMetadata(MetadataRequestsHandler):
def __init__(self, identifier: bytes, engine: str):
"""
:param identifier:
:type identifier:
"""
self.headers = {
'X-CIC-AUTOMERGE': 'server',
'Content-Type': 'application/json'
}
self.identifier = identifier
self.metadata_pointer = generate_metadata_pointer(
identifier=self.identifier,
cic_type=':cic.phone'
)
if self.base_url:
self.url = os.path.join(self.base_url, self.metadata_pointer)
self.engine = engine
def create(self, data: str):
try:
data = json.dumps(data).encode('utf-8')
result = make_request(method='POST', url=self.url, data=data, headers=self.headers)
metadata = result.content
logg.debug('data {} meta {} resp {} stats {}'.format(data, metadata, result.reason, result.status_code))
self.edit(data=metadata, engine=self.engine)
result.raise_for_status()
except requests.exceptions.HTTPError as error:
raise MetadataStoreError(error)
def edit(self, data: bytes, engine: str):
"""
:param data:
:type data:
:param engine:
:type engine:
:return:
:rtype:
"""
cic_meta_signer = Signer()
signature = cic_meta_signer.sign_digest(data=data)
algorithm = cic_meta_signer.get_operational_key().get('algo')
decoded_data = data.decode('utf-8')
formatted_data = {
'm': decoded_data,
's': {
'engine': engine,
'algo': algorithm,
'data': signature,
'digest': json.loads(data).get('digest'),
}
}
formatted_data = json.dumps(formatted_data).encode('utf-8')
try:
result = make_request(method='PUT', url=self.url, data=formatted_data, headers=self.headers)
logg.debug(f'signed phone pointer metadata submission status: {result.status_code}.')
result.raise_for_status()
logg.info('phone {} metadata pointer {} set to {}'.format(self.identifier.decode('utf-8'), self.metadata_pointer, decoded_data))
except requests.exceptions.HTTPError as error:
raise MetadataStoreError(error)
def __init__(self, identifier: bytes):
super().__init__(cic_type='cic.msisdn', identifier=identifier)
-100
View File
@@ -1,100 +0,0 @@
# standard imports
import json
import logging
import os
# third-party imports
import requests
from cic_types.models.person import generate_metadata_pointer, Person
# local imports
from cic_ussd.chain import Chain
from cic_ussd.metadata import make_request
from cic_ussd.metadata.signer import Signer
from cic_ussd.redis import cache_data
from cic_ussd.error import MetadataStoreError
from .base import Metadata
logg = logging.getLogger()
class UserMetadata(Metadata):
def __init__(self, identifier: bytes):
"""
:param identifier:
:type identifier:
"""
self.headers = {
'X-CIC-AUTOMERGE': 'server',
'Content-Type': 'application/json'
}
self.identifier = identifier
self.metadata_pointer = generate_metadata_pointer(
identifier=self.identifier,
cic_type=':cic.person'
)
if self.base_url:
self.url = os.path.join(self.base_url, self.metadata_pointer)
def create(self, data: dict):
try:
data = json.dumps(data).encode('utf-8')
result = make_request(method='POST', url=self.url, data=data, headers=self.headers)
metadata = result.content
self.edit(data=metadata, engine='pgp')
logg.info(f'Get sign material response status: {result.status_code}')
result.raise_for_status()
except requests.exceptions.HTTPError as error:
raise MetadataStoreError(error)
def edit(self, data: bytes, engine: str):
"""
:param data:
:type data:
:param engine:
:type engine:
:return:
:rtype:
"""
cic_meta_signer = Signer()
signature = cic_meta_signer.sign_digest(data=data)
algorithm = cic_meta_signer.get_operational_key().get('algo')
formatted_data = {
'm': data.decode('utf-8'),
's': {
'engine': engine,
'algo': algorithm,
'data': signature,
'digest': json.loads(data).get('digest'),
}
}
formatted_data = json.dumps(formatted_data).encode('utf-8')
try:
result = make_request(method='PUT', url=self.url, data=formatted_data, headers=self.headers)
logg.debug(f'signed user metadata submission status: {result.status_code}.')
result.raise_for_status()
except requests.exceptions.HTTPError as error:
raise MetadataStoreError(error)
def query(self):
result = make_request(method='GET', url=self.url)
status = result.status_code
logg.info(f'Get latest data status: {status}')
try:
if status == 200:
response_data = result.content
data = json.loads(response_data.decode())
# validate data
person = Person()
deserialized_person = person.deserialize(person_data=json.loads(data))
cache_data(key=self.metadata_pointer, data=json.dumps(deserialized_person.serialize()))
elif status == 404:
logg.info('The data is not available and might need to be added.')
result.raise_for_status()
except requests.exceptions.HTTPError as error:
raise MetadataNotFoundError(error)
+6 -9
View File
@@ -235,7 +235,7 @@ def process_display_user_metadata(user: User, display_key: str):
products=products products=products
) )
else: else:
raise MetadataNotFoundError(f'Expected user metadata but found none in cache for key: {user.blockchain_address}') raise MetadataNotFoundError(f'Expected person metadata but found none in cache for key: {key}')
def process_account_statement(user: User, display_key: str, ussd_session: dict): def process_account_statement(user: User, display_key: str, ussd_session: dict):
@@ -331,11 +331,11 @@ def process_start_menu(display_key: str, user: User):
operational_balance = compute_operational_balance(balances=balances_data) operational_balance = compute_operational_balance(balances=balances_data)
# retrieve and cache account's metadata # retrieve and cache account's metadata
s_query_user_metadata = celery.signature( s_query_person_metadata = celery.signature(
'cic_ussd.tasks.metadata.query_user_metadata', 'cic_ussd.tasks.metadata.query_person_metadata',
[blockchain_address] [blockchain_address]
) )
s_query_user_metadata.apply_async(queue='cic-ussd') s_query_person_metadata.apply_async(queue='cic-ussd')
# retrieve and cache account's statement # retrieve and cache account's statement
retrieve_account_statement(blockchain_address=blockchain_address) retrieve_account_statement(blockchain_address=blockchain_address)
@@ -389,14 +389,11 @@ def process_request(user_input: str, user: User, ussd_session: Optional[dict] =
identifier=blockchain_address_to_metadata_pointer(blockchain_address=user.blockchain_address), identifier=blockchain_address_to_metadata_pointer(blockchain_address=user.blockchain_address),
cic_type='cic.person' cic_type='cic.person'
) )
logg.debug(f'METADATA POINTER: {key}') person_metadata = get_cached_data(key=key)
user_metadata = get_cached_data(key=key)
logg.debug(f'METADATA: {user_metadata}')
if last_ussd_session: if last_ussd_session:
# get last state # get last state
last_state = last_ussd_session.state last_state = last_ussd_session.state
logg.debug(f'LAST USSD SESSION STATE: {last_state}')
# if last state is account_creation_prompt and metadata exists, show start menu # if last state is account_creation_prompt and metadata exists, show start menu
if last_state in [ if last_state in [
'account_creation_prompt', 'account_creation_prompt',
@@ -405,7 +402,7 @@ def process_request(user_input: str, user: User, ussd_session: Optional[dict] =
'exit_invalid_new_pin', 'exit_invalid_new_pin',
'exit_pin_mismatch', 'exit_pin_mismatch',
'exit_invalid_request' 'exit_invalid_request'
] and user_metadata is not None: ] and person_metadata is not None:
return UssdMenu.find_by_name(name='start') return UssdMenu.find_by_name(name='start')
else: else:
return UssdMenu.find_by_name(name=last_state) return UssdMenu.find_by_name(name=last_state)
@@ -97,11 +97,11 @@ def retrieve_recipient_metadata(state_machine_data: Tuple[str, dict, User]):
recipient = get_user_by_phone_number(phone_number=user_input) recipient = get_user_by_phone_number(phone_number=user_input)
blockchain_address = recipient.blockchain_address blockchain_address = recipient.blockchain_address
# retrieve and cache account's metadata # retrieve and cache account's metadata
s_query_user_metadata = celery.signature( s_query_person_metadata = celery.signature(
'cic_ussd.tasks.metadata.query_user_metadata', 'cic_ussd.tasks.metadata.query_person_metadata',
[blockchain_address] [blockchain_address]
) )
s_query_user_metadata.apply_async(queue='cic-ussd') s_query_person_metadata.apply_async(queue='cic-ussd')
def save_transaction_amount_to_session_data(state_machine_data: Tuple[str, dict, User]): def save_transaction_amount_to_session_data(state_machine_data: Tuple[str, dict, User]):
@@ -164,11 +164,11 @@ def save_complete_user_metadata(state_machine_data: Tuple[str, dict, User]):
user_metadata = format_user_metadata(metadata=metadata, user=user) user_metadata = format_user_metadata(metadata=metadata, user=user)
blockchain_address = user.blockchain_address blockchain_address = user.blockchain_address
s_create_user_metadata = celery.signature( s_create_person_metadata = celery.signature(
'cic_ussd.tasks.metadata.create_user_metadata', 'cic_ussd.tasks.metadata.create_person_metadata',
[blockchain_address, user_metadata] [blockchain_address, user_metadata]
) )
s_create_user_metadata.apply_async(queue='cic-ussd') s_create_person_metadata.apply_async(queue='cic-ussd')
def edit_user_metadata_attribute(state_machine_data: Tuple[str, dict, User]): def edit_user_metadata_attribute(state_machine_data: Tuple[str, dict, User]):
@@ -211,18 +211,18 @@ def edit_user_metadata_attribute(state_machine_data: Tuple[str, dict, User]):
edited_metadata = deserialized_person.serialize() edited_metadata = deserialized_person.serialize()
s_edit_user_metadata = celery.signature( s_edit_person_metadata = celery.signature(
'cic_ussd.tasks.metadata.edit_user_metadata', 'cic_ussd.tasks.metadata.edit_person_metadata',
[blockchain_address, edited_metadata, 'pgp'] [blockchain_address, edited_metadata]
) )
s_edit_user_metadata.apply_async(queue='cic-ussd') s_edit_person_metadata.apply_async(queue='cic-ussd')
def get_user_metadata(state_machine_data: Tuple[str, dict, User]): def get_user_metadata(state_machine_data: Tuple[str, dict, User]):
user_input, ussd_session, user = state_machine_data user_input, ussd_session, user = state_machine_data
blockchain_address = user.blockchain_address blockchain_address = user.blockchain_address
s_get_user_metadata = celery.signature( s_get_user_metadata = celery.signature(
'cic_ussd.tasks.metadata.query_user_metadata', 'cic_ussd.tasks.metadata.query_person_metadata',
[blockchain_address] [blockchain_address]
) )
s_get_user_metadata.apply_async(queue='cic-ussd') s_get_user_metadata.apply_async(queue='cic-ussd')
@@ -57,14 +57,9 @@ def process_account_creation_callback(self, result: str, url: str, status_code:
queue = self.request.delivery_info.get('routing_key') queue = self.request.delivery_info.get('routing_key')
s = celery.signature( s = celery.signature(
'cic_ussd.tasks.metadata.add_phone_pointer', 'cic_ussd.tasks.metadata.add_phone_pointer',
[ [result, phone_number]
result,
phone_number,
'pgp',
],
queue=queue,
) )
s.apply_async() s.apply_async(queue=queue)
# expire cache # expire cache
cache.expire(task_id, timedelta(seconds=180)) cache.expire(task_id, timedelta(seconds=180))
+14 -14
View File
@@ -1,14 +1,13 @@
# standard imports # standard imports
import json
import logging import logging
# external imports # third-party imports
import celery import celery
from hexathon import strip_0x from hexathon import strip_0x
# local imports # local imports
from cic_ussd.metadata import blockchain_address_to_metadata_pointer from cic_ussd.metadata import blockchain_address_to_metadata_pointer
from cic_ussd.metadata.user import UserMetadata from cic_ussd.metadata.person import PersonMetadata
from cic_ussd.metadata.phone import PhonePointerMetadata from cic_ussd.metadata.phone import PhonePointerMetadata
from cic_ussd.tasks.base import CriticalMetadataTask from cic_ussd.tasks.base import CriticalMetadataTask
@@ -17,7 +16,7 @@ logg = logging.getLogger().getChild(__name__)
@celery_app.task @celery_app.task
def query_user_metadata(blockchain_address: str): def query_person_metadata(blockchain_address: str):
""" """
:param blockchain_address: :param blockchain_address:
:type blockchain_address: :type blockchain_address:
@@ -25,12 +24,12 @@ def query_user_metadata(blockchain_address: str):
:rtype: :rtype:
""" """
identifier = blockchain_address_to_metadata_pointer(blockchain_address=blockchain_address) identifier = blockchain_address_to_metadata_pointer(blockchain_address=blockchain_address)
user_metadata_client = UserMetadata(identifier=identifier) person_metadata_client = PersonMetadata(identifier=identifier)
user_metadata_client.query() person_metadata_client.query()
@celery_app.task @celery_app.task
def create_user_metadata(blockchain_address: str, data: dict): def create_person_metadata(blockchain_address: str, data: dict):
""" """
:param blockchain_address: :param blockchain_address:
:type blockchain_address: :type blockchain_address:
@@ -40,19 +39,20 @@ def create_user_metadata(blockchain_address: str, data: dict):
:rtype: :rtype:
""" """
identifier = blockchain_address_to_metadata_pointer(blockchain_address=blockchain_address) identifier = blockchain_address_to_metadata_pointer(blockchain_address=blockchain_address)
user_metadata_client = UserMetadata(identifier=identifier) person_metadata_client = PersonMetadata(identifier=identifier)
user_metadata_client.create(data=data) person_metadata_client.create(data=data)
@celery_app.task @celery_app.task
def edit_user_metadata(blockchain_address: str, data: bytes, engine: str): def edit_person_metadata(blockchain_address: str, data: bytes):
identifier = blockchain_address_to_metadata_pointer(blockchain_address=blockchain_address) identifier = blockchain_address_to_metadata_pointer(blockchain_address=blockchain_address)
user_metadata_client = UserMetadata(identifier=identifier) person_metadata_client = PersonMetadata(identifier=identifier)
user_metadata_client.edit(data=data, engine=engine) person_metadata_client.edit(data=data)
@celery_app.task(bind=True, base=CriticalMetadataTask) @celery_app.task(bind=True, base=CriticalMetadataTask)
def add_phone_pointer(self, blockchain_address: str, phone: str, engine: str): def add_phone_pointer(self, blockchain_address: str, phone_number: str):
identifier = phone_number.encode('utf-8')
stripped_address = strip_0x(blockchain_address) stripped_address = strip_0x(blockchain_address)
phone_metadata_client = PhonePointerMetadata(identifier=phone.encode('utf-8'), engine=engine) phone_metadata_client = PhonePointerMetadata(identifier=identifier)
phone_metadata_client.create(data=stripped_address) phone_metadata_client.create(data=stripped_address)
+2 -2
View File
@@ -1,4 +1,4 @@
cic_base[full_graph]~=0.1.2a61 cic_base[full_graph]~=0.1.2a68
cic-eth~=0.11.0b1 cic-eth~=0.11.0b3
cic-notify~=0.4.0a3 cic-notify~=0.4.0a3
cic-types~=0.1.0a10 cic-types~=0.1.0a10
@@ -9,26 +9,26 @@ from cic_types.models.person import generate_metadata_pointer
# local imports # local imports
from cic_ussd.metadata import blockchain_address_to_metadata_pointer from cic_ussd.metadata import blockchain_address_to_metadata_pointer
from cic_ussd.metadata.signer import Signer from cic_ussd.metadata.signer import Signer
from cic_ussd.metadata.user import UserMetadata from cic_ussd.metadata.person import PersonMetadata
from cic_ussd.redis import get_cached_data from cic_ussd.redis import get_cached_data
def test_user_metadata(create_activated_user, define_metadata_pointer_url, load_config): def test_user_metadata(create_activated_user, define_metadata_pointer_url, load_config):
UserMetadata.base_url = load_config.get('CIC_META_URL') PersonMetadata.base_url = load_config.get('CIC_META_URL')
identifier = blockchain_address_to_metadata_pointer(blockchain_address=create_activated_user.blockchain_address) identifier = blockchain_address_to_metadata_pointer(blockchain_address=create_activated_user.blockchain_address)
user_metadata_client = UserMetadata(identifier=identifier) person_metadata_client = PersonMetadata(identifier=identifier)
assert user_metadata_client.url == define_metadata_pointer_url assert person_metadata_client.url == define_metadata_pointer_url
def test_create_user_metadata(caplog, def test_create_person_metadata(caplog,
create_activated_user, create_activated_user,
define_metadata_pointer_url, define_metadata_pointer_url,
load_config, load_config,
mock_meta_post_response, mock_meta_post_response,
person_metadata): person_metadata):
identifier = blockchain_address_to_metadata_pointer(blockchain_address=create_activated_user.blockchain_address) identifier = blockchain_address_to_metadata_pointer(blockchain_address=create_activated_user.blockchain_address)
user_metadata_client = UserMetadata(identifier=identifier) person_metadata_client = PersonMetadata(identifier=identifier)
with requests_mock.Mocker(real_http=False) as request_mocker: with requests_mock.Mocker(real_http=False) as request_mocker:
request_mocker.register_uri( request_mocker.register_uri(
@@ -38,7 +38,7 @@ def test_create_user_metadata(caplog,
reason='CREATED', reason='CREATED',
content=json.dumps(mock_meta_post_response).encode('utf-8') content=json.dumps(mock_meta_post_response).encode('utf-8')
) )
user_metadata_client.create(data=person_metadata) person_metadata_client.create(data=person_metadata)
assert 'Get signed material response status: 201' in caplog.text assert 'Get signed material response status: 201' in caplog.text
with pytest.raises(RuntimeError) as error: with pytest.raises(RuntimeError) as error:
@@ -49,19 +49,19 @@ def test_create_user_metadata(caplog,
status_code=400, status_code=400,
reason='BAD REQUEST' reason='BAD REQUEST'
) )
user_metadata_client.create(data=person_metadata) person_metadata_client.create(data=person_metadata)
assert str(error.value) == f'400 Client Error: BAD REQUEST for url: {define_metadata_pointer_url}' assert str(error.value) == f'400 Client Error: BAD REQUEST for url: {define_metadata_pointer_url}'
def test_edit_user_metadata(caplog, def test_edit_person_metadata(caplog,
create_activated_user, create_activated_user,
define_metadata_pointer_url, define_metadata_pointer_url,
load_config, load_config,
person_metadata, person_metadata,
setup_metadata_signer): setup_metadata_signer):
Signer.gpg_passphrase = load_config.get('KEYS_PASSPHRASE') Signer.gpg_passphrase = load_config.get('KEYS_PASSPHRASE')
identifier = blockchain_address_to_metadata_pointer(blockchain_address=create_activated_user.blockchain_address) identifier = blockchain_address_to_metadata_pointer(blockchain_address=create_activated_user.blockchain_address)
user_metadata_client = UserMetadata(identifier=identifier) person_metadata_client = PersonMetadata(identifier=identifier)
with requests_mock.Mocker(real_http=False) as request_mocker: with requests_mock.Mocker(real_http=False) as request_mocker:
request_mocker.register_uri( request_mocker.register_uri(
'PUT', 'PUT',
@@ -69,7 +69,7 @@ def test_edit_user_metadata(caplog,
status_code=200, status_code=200,
reason='OK' reason='OK'
) )
user_metadata_client.edit(data=person_metadata, engine='pgp') person_metadata_client.edit(data=person_metadata)
assert 'Signed content submission status: 200' in caplog.text assert 'Signed content submission status: 200' in caplog.text
with pytest.raises(RuntimeError) as error: with pytest.raises(RuntimeError) as error:
@@ -80,7 +80,7 @@ def test_edit_user_metadata(caplog,
status_code=400, status_code=400,
reason='BAD REQUEST' reason='BAD REQUEST'
) )
user_metadata_client.edit(data=person_metadata, engine='pgp') person_metadata_client.edit(data=person_metadata)
assert str(error.value) == f'400 Client Error: BAD REQUEST for url: {define_metadata_pointer_url}' assert str(error.value) == f'400 Client Error: BAD REQUEST for url: {define_metadata_pointer_url}'
@@ -92,7 +92,7 @@ def test_get_user_metadata(caplog,
person_metadata, person_metadata,
setup_metadata_signer): setup_metadata_signer):
identifier = blockchain_address_to_metadata_pointer(blockchain_address=create_activated_user.blockchain_address) identifier = blockchain_address_to_metadata_pointer(blockchain_address=create_activated_user.blockchain_address)
user_metadata_client = UserMetadata(identifier=identifier) person_metadata_client = PersonMetadata(identifier=identifier)
with requests_mock.Mocker(real_http=False) as request_mocker: with requests_mock.Mocker(real_http=False) as request_mocker:
request_mocker.register_uri( request_mocker.register_uri(
'GET', 'GET',
@@ -101,7 +101,7 @@ def test_get_user_metadata(caplog,
content=json.dumps(person_metadata).encode('utf-8'), content=json.dumps(person_metadata).encode('utf-8'),
reason='OK' reason='OK'
) )
user_metadata_client.query() person_metadata_client.query()
assert 'Get latest data status: 200' in caplog.text assert 'Get latest data status: 200' in caplog.text
key = generate_metadata_pointer( key = generate_metadata_pointer(
identifier=identifier, identifier=identifier,
@@ -118,6 +118,6 @@ def test_get_user_metadata(caplog,
status_code=404, status_code=404,
reason='NOT FOUND' reason='NOT FOUND'
) )
user_metadata_client.query() person_metadata_client.query()
assert 'The data is not available and might need to be added.' in caplog.text assert 'The data is not available and might need to be added.' in caplog.text
assert str(error.value) == f'400 Client Error: NOT FOUND for url: {define_metadata_pointer_url}' assert str(error.value) == f'400 Client Error: NOT FOUND for url: {define_metadata_pointer_url}'
@@ -15,7 +15,7 @@ from cic_ussd.state_machine.logic.user import (
get_user_metadata, get_user_metadata,
save_complete_user_metadata, save_complete_user_metadata,
process_gender_user_input, process_gender_user_input,
save_profile_attribute_to_session_data, save_metadata_attribute_to_session_data,
update_account_status_to_active) update_account_status_to_active)
@@ -41,14 +41,14 @@ def test_update_account_status_to_active(create_pending_user, create_in_db_ussd_
("enter_location", "location", "Kangemi", "Kangemi"), ("enter_location", "location", "Kangemi", "Kangemi"),
("enter_products", "products", "Mandazi", "Mandazi"), ("enter_products", "products", "Mandazi", "Mandazi"),
]) ])
def test_save_save_profile_attribute_to_session_data(current_state, def test_save_metadata_attribute_to_session_data(current_state,
expected_key, expected_key,
expected_result, expected_result,
user_input, user_input,
celery_session_worker, celery_session_worker,
create_activated_user, create_activated_user,
create_in_db_ussd_session, create_in_db_ussd_session,
create_in_redis_ussd_session): create_in_redis_ussd_session):
create_in_db_ussd_session.state = current_state create_in_db_ussd_session.state = current_state
serialized_in_db_ussd_session = create_in_db_ussd_session.to_json() serialized_in_db_ussd_session = create_in_db_ussd_session.to_json()
state_machine_data = (user_input, serialized_in_db_ussd_session, create_activated_user) state_machine_data = (user_input, serialized_in_db_ussd_session, create_activated_user)
@@ -56,7 +56,7 @@ def test_save_save_profile_attribute_to_session_data(current_state,
in_memory_ussd_session = json.loads(in_memory_ussd_session) in_memory_ussd_session = json.loads(in_memory_ussd_session)
assert in_memory_ussd_session.get('session_data') == {} assert in_memory_ussd_session.get('session_data') == {}
serialized_in_db_ussd_session['state'] = current_state serialized_in_db_ussd_session['state'] = current_state
save_profile_attribute_to_session_data(state_machine_data=state_machine_data) save_metadata_attribute_to_session_data(state_machine_data=state_machine_data)
in_memory_ussd_session = InMemoryStore.cache.get('AT974186') in_memory_ussd_session = InMemoryStore.cache.get('AT974186')
in_memory_ussd_session = json.loads(in_memory_ussd_session) in_memory_ussd_session = json.loads(in_memory_ussd_session)
@@ -87,18 +87,18 @@ def test_format_user_metadata(create_activated_user,
def test_save_complete_user_metadata(celery_session_worker, def test_save_complete_user_metadata(celery_session_worker,
complete_user_metadata, complete_user_metadata,
create_activated_user, create_activated_user,
create_in_redis_ussd_session, create_in_redis_ussd_session,
mocker, mocker,
setup_chain_spec, setup_chain_spec,
ussd_session_data): ussd_session_data):
ussd_session = create_in_redis_ussd_session.get(ussd_session_data.get('external_session_id')) ussd_session = create_in_redis_ussd_session.get(ussd_session_data.get('external_session_id'))
ussd_session = json.loads(ussd_session) ussd_session = json.loads(ussd_session)
ussd_session['session_data'] = complete_user_metadata ussd_session['session_data'] = complete_user_metadata
user_metadata = format_user_metadata(metadata=ussd_session.get('session_data'), user=create_activated_user) user_metadata = format_user_metadata(metadata=ussd_session.get('session_data'), user=create_activated_user)
state_machine_data = ('', ussd_session, create_activated_user) state_machine_data = ('', ussd_session, create_activated_user)
mocked_create_metadata_task = mocker.patch('cic_ussd.tasks.metadata.create_user_metadata.apply_async') mocked_create_metadata_task = mocker.patch('cic_ussd.tasks.metadata.create_person_metadata.apply_async')
save_complete_user_metadata(state_machine_data=state_machine_data) save_complete_user_metadata(state_machine_data=state_machine_data)
mocked_create_metadata_task.assert_called_with( mocked_create_metadata_task.assert_called_with(
(user_metadata, create_activated_user.blockchain_address), (user_metadata, create_activated_user.blockchain_address),
@@ -127,7 +127,7 @@ def test_edit_user_metadata_attribute(celery_session_worker,
} }
state_machine_data = ('', ussd_session, create_activated_user) state_machine_data = ('', ussd_session, create_activated_user)
mocked_edit_metadata = mocker.patch('cic_ussd.tasks.metadata.edit_user_metadata.apply_async') mocked_edit_metadata = mocker.patch('cic_ussd.tasks.metadata.edit_person_metadata.apply_async')
edit_user_metadata_attribute(state_machine_data=state_machine_data) edit_user_metadata_attribute(state_machine_data=state_machine_data)
person_metadata['location']['area_name'] = 'nairobi' person_metadata['location']['area_name'] = 'nairobi'
mocked_edit_metadata.assert_called_with( mocked_edit_metadata.assert_called_with(
@@ -146,7 +146,7 @@ def test_get_user_metadata_attribute(celery_session_worker,
ussd_session = json.loads(ussd_session) ussd_session = json.loads(ussd_session)
state_machine_data = ('', ussd_session, create_activated_user) state_machine_data = ('', ussd_session, create_activated_user)
mocked_get_metadata = mocker.patch('cic_ussd.tasks.metadata.query_user_metadata.apply_async') mocked_get_metadata = mocker.patch('cic_ussd.tasks.metadata.query_person_metadata.apply_async')
get_user_metadata(state_machine_data=state_machine_data) get_user_metadata(state_machine_data=state_machine_data)
mocked_get_metadata.assert_called_with( mocked_get_metadata.assert_called_with(
(create_activated_user.blockchain_address,), (create_activated_user.blockchain_address,),
+4 -4
View File
@@ -18,7 +18,7 @@ from cic_ussd.files.local_files import create_local_file_data_stores, json_file_
from cic_ussd.menu.ussd_menu import UssdMenu from cic_ussd.menu.ussd_menu import UssdMenu
from cic_ussd.metadata import blockchain_address_to_metadata_pointer from cic_ussd.metadata import blockchain_address_to_metadata_pointer
from cic_ussd.metadata.signer import Signer from cic_ussd.metadata.signer import Signer
from cic_ussd.metadata.user import UserMetadata from cic_ussd.metadata.person import PersonMetadata
from cic_ussd.state_machine import UssdStateMachine from cic_ussd.state_machine import UssdStateMachine
@@ -121,9 +121,9 @@ def setup_metadata_signer(load_config):
@pytest.fixture(scope='function') @pytest.fixture(scope='function')
def define_metadata_pointer_url(load_config, create_activated_user): def define_metadata_pointer_url(load_config, create_activated_user):
identifier = blockchain_address_to_metadata_pointer(blockchain_address=create_activated_user.blockchain_address) identifier = blockchain_address_to_metadata_pointer(blockchain_address=create_activated_user.blockchain_address)
UserMetadata.base_url = load_config.get('CIC_META_URL') PersonMetadata.base_url = load_config.get('CIC_META_URL')
user_metadata_client = UserMetadata(identifier=identifier) person_metadata_client = PersonMetadata(identifier=identifier)
return user_metadata_client.url return person_metadata_client.url
@pytest.fixture(scope='function') @pytest.fixture(scope='function')
+3 -3
View File
@@ -57,9 +57,9 @@ WORKDIR /home/grassroots
USER grassroots USER grassroots
ARG pip_extra_index_url=https://pip.grassrootseconomics.net:8433 ARG pip_extra_index_url=https://pip.grassrootseconomics.net:8433
ARG cic_base_version=0.1.2a62 ARG cic_base_version=0.1.2a77
ARG cic_eth_version=0.11.0b1 ARG cic_eth_version=0.11.0b6
ARG sarafu_faucet_version=0.0.2a19 ARG sarafu_faucet_version=0.0.2a28
ARG cic_contracts_version=0.0.2a2 ARG cic_contracts_version=0.0.2a2
RUN pip install --user --extra-index-url $pip_extra_index_url cic-base[full_graph]==$cic_base_version \ RUN pip install --user --extra-index-url $pip_extra_index_url cic-base[full_graph]==$cic_base_version \
cic-eth==$cic_eth_version \ cic-eth==$cic_eth_version \
+3 -2
View File
@@ -72,12 +72,13 @@ if [[ -n "${ETH_PROVIDER}" ]]; then
# Sarafu faucet contract # Sarafu faucet contract
>&2 echo "deploy token faucet contract" >&2 echo "deploy token faucet contract"
DEV_FAUCET_ADDRESS=`sarafu-faucet-deploy -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w -v --account-index-address $DEV_ACCOUNT_INDEX_ADDRESS $DEV_RESERVE_ADDRESS` DEV_FAUCET_ADDRESS=`sarafu-faucet-deploy -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w -v --account-index-address $DEV_ACCOUNT_INDEX_ADDRESS $DEV_RESERVE_ADDRESS`
>&2 echo "set token faucet amount"
sarafu-faucet-set -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -a $DEV_FAUCET_ADDRESS $faucet_amount
eth-contract-registry-set -w -y $keystore_file -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv Faucet $DEV_FAUCET_ADDRESS eth-contract-registry-set -w -y $keystore_file -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv Faucet $DEV_FAUCET_ADDRESS
>&2 echo "set faucet as token minter" >&2 echo "set faucet as token minter"
giftable-token-minter -w -y $keystore_file -a $DEV_RESERVE_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv $DEV_FAUCET_ADDRESS giftable-token-minter -w -y $keystore_file -a $DEV_RESERVE_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv $DEV_FAUCET_ADDRESS
>&2 echo "set token faucet amount"
sarafu-faucet-set -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -a $DEV_FAUCET_ADDRESS $faucet_amount
else else
echo "\$ETH_PROVIDER not set!" echo "\$ETH_PROVIDER not set!"
@@ -17,7 +17,7 @@ from hexathon import (
strip_0x, strip_0x,
add_0x, add_0x,
) )
from chainsyncer.backend import MemBackend from chainsyncer.backend.memory import MemBackend
from chainsyncer.driver import HeadSyncer from chainsyncer.driver import HeadSyncer
from chainlib.eth.connection import EthHTTPConnection from chainlib.eth.connection import EthHTTPConnection
from chainlib.eth.block import ( from chainlib.eth.block import (
@@ -25,13 +25,13 @@ from chainlib.eth.block import (
block_by_number, block_by_number,
Block, Block,
) )
from chainlib.eth.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.erc20 import ERC20 from chainlib.eth.erc20 import ERC20
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.eth.rpc import jsonrpc_template from chainlib.jsonrpc import jsonrpc_template
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
@@ -204,8 +204,8 @@ class Handler:
# return b # return b
def progress_callback(block_number, tx_index, s): def progress_callback(block_number, tx_index):
sys.stdout.write(str(s).ljust(200) + "\n") sys.stdout.write(str(block_number).ljust(200) + "\n")
@@ -299,7 +299,7 @@ def main():
f.close() f.close()
syncer_backend.set(block_offset, 0) syncer_backend.set(block_offset, 0)
syncer = HeadSyncer(syncer_backend, progress_callback=progress_callback) syncer = HeadSyncer(syncer_backend, 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)
@@ -0,0 +1,24 @@
[app]
ALLOWED_IP=0.0.0.0/0
LOCALE_FALLBACK=en
LOCALE_PATH=/usr/src/cic-ussd/var/lib/locale/
MAX_BODY_LENGTH=1024
PASSWORD_PEPPER=QYbzKff6NhiQzY3ygl2BkiKOpER8RE/Upqs/5aZWW+I=
SERVICE_CODE=*483*46#
[phone_number]
REGION=KE
[ussd]
MENU_FILE=/usr/src/data/ussd_menu.json
user =
pass =
[statemachine]
STATES=/usr/src/cic-ussd/states/
TRANSITIONS=/usr/src/cic-ussd/transitions/
[client]
host =
port =
ssl =
@@ -17,7 +17,7 @@ from hexathon import (
strip_0x, strip_0x,
add_0x, add_0x,
) )
from chainsyncer.backend import MemBackend from chainsyncer.backend.memory import MemBackend
from chainsyncer.driver import HeadSyncer from chainsyncer.driver import HeadSyncer
from chainlib.eth.connection import EthHTTPConnection from chainlib.eth.connection import EthHTTPConnection
from chainlib.eth.block import ( from chainlib.eth.block import (
@@ -25,13 +25,13 @@ from chainlib.eth.block import (
block_by_number, block_by_number,
Block, Block,
) )
from chainlib.eth.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.erc20 import ERC20 from chainlib.eth.erc20 import ERC20
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.eth.rpc import jsonrpc_template from chainlib.jsonrpc import jsonrpc_template
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
@@ -204,8 +204,8 @@ class Handler:
# return b # return b
def progress_callback(block_number, tx_index, s): def progress_callback(block_number, tx_index):
sys.stdout.write(str(s).ljust(200) + "\n") sys.stdout.write(str(block_number).ljust(200) + "\n")
@@ -299,7 +299,7 @@ def main():
f.close() f.close()
syncer_backend.set(block_offset, 0) syncer_backend.set(block_offset, 0)
syncer = HeadSyncer(syncer_backend, progress_callback=progress_callback) syncer = HeadSyncer(syncer_backend, 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)
@@ -0,0 +1,6 @@
{
"dependencies": {
"cic-client-meta": "^0.0.7-alpha.6",
"vcard-parser": "^1.0.0"
}
}
@@ -1,5 +1,5 @@
cic-base[full_graph]==0.1.2a61 cic-base[full_graph]==0.1.2a77
sarafu-faucet==0.0.2a17 sarafu-faucet==0.0.2a28
cic-eth==0.11.0b1 cic-eth==0.11.0b6
cic-types==0.1.0a10 cic-types==0.1.0a10
crypto-dev-signer==0.4.14a17 crypto-dev-signer==0.4.14b2
+9 -3
View File
@@ -32,7 +32,7 @@ from chainlib.eth.block import (
block_by_number, block_by_number,
Block, Block,
) )
from chainlib.eth.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.erc20 import ERC20 from chainlib.eth.erc20 import ERC20
from chainlib.eth.gas import ( from chainlib.eth.gas import (
@@ -40,7 +40,7 @@ from chainlib.eth.gas import (
balance, balance,
) )
from chainlib.eth.tx import TxFactory from chainlib.eth.tx import TxFactory
from chainlib.eth.rpc import jsonrpc_template from chainlib.jsonrpc import jsonrpc_template
from chainlib.eth.error import EthException from chainlib.eth.error import EthException
from cic_types.models.person import ( from cic_types.models.person import (
Person, Person,
@@ -343,7 +343,13 @@ class Verifier:
address_recovered = json.loads(b.decode('utf-8')) address_recovered = json.loads(b.decode('utf-8'))
address_recovered = address_recovered.replace('"', '') address_recovered = address_recovered.replace('"', '')
if strip_0x(address) != strip_0x(address_recovered): try:
address = strip_0x(address)
address_recovered = strip_0x(address_recovered)
except ValueError:
raise VerifierError(address_recovered, 'metadata (phone) address {} address recovered {}'.format(address, address_recovered))
if address != address_recovered:
raise VerifierError(address_recovered, 'metadata (phone)') raise VerifierError(address_recovered, 'metadata (phone)')
+10 -9
View File
@@ -145,7 +145,7 @@ services:
- -c - -c
- | - |
if [[ -f /tmp/cic/config/.env ]]; then source /tmp/cic/config/.env; fi if [[ -f /tmp/cic/config/.env ]]; then source /tmp/cic/config/.env; fi
/usr/local/bin/cic-cache-trackerd -vv -c /usr/local/etc/cic-cache ./start_tracker.sh -c /usr/local/etc/cic-cache -vv
volumes: volumes:
- contract-config:/tmp/cic/config/:ro - contract-config:/tmp/cic/config/:ro
@@ -191,13 +191,13 @@ services:
context: apps context: apps
dockerfile: cic-cache/docker/Dockerfile dockerfile: cic-cache/docker/Dockerfile
environment: environment:
DATABASE_USER: $DATABASE_USER DATABASE_USER: ${DATABASE_USER:-grassroots}
DATABASE_HOST: $DATABASE_HOST DATABASE_HOST: ${DATABASE_HOST:-postgres}
DATABASE_PORT: $DATABASE_PORT DATABASE_PORT: ${DATABASE_PORT:-5432}
DATABASE_PASSWORD: $DATABASE_PASSWORD #DATABASE_PASSWORD: ${DATABASE_PASSWORD:-
DATABASE_NAME: $DATABASE_NAME_CIC_CACHE DATABASE_NAME: ${DATABASE_NAME_CIC_CACHE:-cic_cache}
DATABASE_DEBUG: 1 DATABASE_DEBUG: 1
PGPASSWORD: $DATABASE_PASSWORD #PGPASSWORD: $DATABASE_PASSWORD
SERVER_PORT: 8000 SERVER_PORT: 8000
ports: ports:
- ${HTTP_PORT_CIC_CACHE:-63313}:8000 - ${HTTP_PORT_CIC_CACHE:-63313}:8000
@@ -212,9 +212,10 @@ services:
- | - |
if [[ -f /tmp/cic/config/.env ]]; then source /tmp/cic/config/.env; fi if [[ -f /tmp/cic/config/.env ]]; then source /tmp/cic/config/.env; fi
"/usr/local/bin/uwsgi" \ "/usr/local/bin/uwsgi" \
--wsgi-file /usr/src/cic-cache/cic_cache/runnable/serverd.py \ --wsgi-file /usr/src/cic-cache/cic_cache/runnable/daemons/server.py \
--http :8000 \ --http :8000 \
--pyargv -vv --pyargv "-vv"
cic-eth-tasker: cic-eth-tasker:
# image: grassrootseconomics:cic-eth-service # image: grassrootseconomics:cic-eth-service