Compare commits
35 Commits
lash/task-
...
feat/autom
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e88b947e52 | ||
|
|
fa96f6adce | ||
|
|
2b4771d97a | ||
|
|
078c2720f9 | ||
|
|
c3a63d0942 | ||
|
|
c72bb56220 | ||
|
|
a6384a46b8 | ||
|
|
aa92c7e5e0 | ||
|
|
0856d26fc7 | ||
|
|
1f50abe13c | ||
| 035531ba49 | |||
| d155566735 | |||
| 0d5bd8edb2 | |||
| ab70ecee26 | |||
| d77deb28f0 | |||
|
|
8f1afa094d | ||
|
|
1d9f134125 | ||
|
|
b6a4bab1c8 | ||
| 805fc56c7b | |||
|
|
e3d39a2144 | ||
|
|
90176f2806 | ||
| f42f223ce9 | |||
|
|
045a279ac2 | ||
|
|
6b59c87f68 | ||
|
|
9ee42b908d | ||
| 3343c4163e | |||
|
|
f5bfc8ace2 | ||
|
8bf5c1fec5
|
|||
|
df1c38a6f0
|
|||
| 68184c6e00 | |||
| 21c48a7a5f | |||
| bbc13fb03b | |||
| bdb825bfb8 | |||
| f9518d01d7 | |||
| 25c75a1218 |
@@ -10,6 +10,7 @@ include:
|
||||
#- local: 'apps/data-seeding/.gitlab-ci.yml'
|
||||
|
||||
stages:
|
||||
- version
|
||||
- build
|
||||
- test
|
||||
- deploy
|
||||
@@ -20,9 +21,39 @@ variables:
|
||||
DOCKER_BUILDKIT: "1"
|
||||
COMPOSE_DOCKER_CLI_BUILD: "1"
|
||||
CI_DEBUG_TRACE: "true"
|
||||
SEMVERBOT_VERSION: "0.2.0"
|
||||
|
||||
before_script:
|
||||
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
|
||||
#before_script:
|
||||
# - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
|
||||
|
||||
version:
|
||||
#image: python:3.7-stretch
|
||||
image: registry.gitlab.com/grassrootseconomics/cic-base-images/ci-version:b01318ae
|
||||
stage: version
|
||||
script:
|
||||
- mkdir -p ~/.ssh && chmod 700 ~/.ssh
|
||||
- ssh-keyscan gitlab.com >> ~/.ssh/known_hosts && chmod 644 ~/.ssh/known_hosts
|
||||
- eval $(ssh-agent -s)
|
||||
- ssh-add <(echo "$SSH_PRIVATE_KEY")
|
||||
- git remote set-url origin git@gitlab.com:grassrootseconomics/cic-internal-integration.git
|
||||
- export TAG=$(sbot predict version -m auto)
|
||||
- |
|
||||
if [[ -z $TAG ]]
|
||||
then
|
||||
echo "tag could not be set $@"
|
||||
exit 1
|
||||
fi
|
||||
- echo $TAG > version
|
||||
- git tag -a v$TAG -m "ci tagged"
|
||||
- git push origin v$TAG
|
||||
artifacts:
|
||||
paths:
|
||||
- version
|
||||
rules:
|
||||
- if: $CI_COMMIT_REF_PROTECTED == "true"
|
||||
when: always
|
||||
- if: $CI_COMMIT_REF_NAME == "master"
|
||||
when: always
|
||||
|
||||
# runs on protected branches and pushes to repo
|
||||
build-push:
|
||||
@@ -30,12 +61,17 @@ build-push:
|
||||
tags:
|
||||
- integration
|
||||
#script:
|
||||
# - TAG=$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA sh ./scripts/build-push.sh
|
||||
# - TAG=$CI_Cbefore_script:
|
||||
before_script:
|
||||
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
|
||||
script:
|
||||
- TAG=latest sh ./scripts/build-push.sh
|
||||
- TAG=latest ./scripts/build-push.sh
|
||||
- TAG=$(cat ./version) ./scripts/build-push.sh
|
||||
rules:
|
||||
- if: $CI_COMMIT_REF_PROTECTED == "true"
|
||||
when: always
|
||||
- if: $CI_COMMIT_REF_NAME == "master"
|
||||
when: always
|
||||
|
||||
deploy-dev:
|
||||
stage: deploy
|
||||
|
||||
16
.semverbot.toml
Normal file
16
.semverbot.toml
Normal file
@@ -0,0 +1,16 @@
|
||||
[git]
|
||||
|
||||
[git.config]
|
||||
email = "semverbot@grassroots.org"
|
||||
name = "semvervot"
|
||||
|
||||
[git.tags]
|
||||
prefix = "v"
|
||||
|
||||
[semver]
|
||||
mode = "git-commit"
|
||||
|
||||
[semver.detection]
|
||||
patch = ["fix", "[fix]", "patch", "[patch]"]
|
||||
minor = ["minor", "[minor]", "feat", "[feat]", "release", "[release]", "bump", "[bump]"]
|
||||
major = ["BREAKING CHANGE"]
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
This repo uses docker-compose and docker buildkit. Set the following environment variables to get started:
|
||||
|
||||
|
||||
```
|
||||
export COMPOSE_DOCKER_CLI_BUILD=1
|
||||
export DOCKER_BUILDKIT=1
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
celery==4.4.7
|
||||
erc20-demurrage-token~=0.0.3a1
|
||||
cic-eth-registry>=0.6.1a2,<0.7.0
|
||||
cic-eth[services]~=0.12.4a8
|
||||
erc20-demurrage-token~=0.0.5a3
|
||||
cic-eth-registry~=0.6.1a5
|
||||
chainlib~=0.0.9rc3
|
||||
cic_eth~=0.12.4a9
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
SQLAlchemy==1.3.20
|
||||
cic-eth-registry>=0.6.1a2,<0.7.0
|
||||
cic-eth-registry>=0.6.1a5,<0.7.0
|
||||
hexathon~=0.0.1a8
|
||||
chainqueue>=0.0.4a6,<0.1.0
|
||||
eth-erc20>=0.1.2a2,<0.2.0
|
||||
|
||||
@@ -1,21 +1,2 @@
|
||||
# standard imports
|
||||
import logging
|
||||
|
||||
# external imports
|
||||
import celery
|
||||
|
||||
# local imports
|
||||
from cic_eth.task import BaseTask
|
||||
|
||||
celery_app = celery.current_app
|
||||
logg = logging.getLogger()
|
||||
|
||||
|
||||
@celery_app.task(bind=True, base=BaseTask)
|
||||
def default_token(self):
|
||||
return {
|
||||
'symbol': self.default_token_symbol,
|
||||
'address': self.default_token_address,
|
||||
'name': self.default_token_name,
|
||||
'decimals': self.default_token_decimals,
|
||||
}
|
||||
from cic_eth.eth.erc20 import default_token
|
||||
|
||||
@@ -9,6 +9,7 @@ import logging
|
||||
# external imports
|
||||
import celery
|
||||
from chainlib.chain import ChainSpec
|
||||
from hexathon import strip_0x
|
||||
|
||||
# local imports
|
||||
from cic_eth.api.base import ApiBase
|
||||
@@ -16,15 +17,50 @@ from cic_eth.enum import LockEnum
|
||||
|
||||
app = celery.current_app
|
||||
|
||||
logg = logging.getLogger(__name__)
|
||||
#logg = logging.getLogger(__name__)
|
||||
logg = logging.getLogger()
|
||||
|
||||
|
||||
class Api(ApiBase):
|
||||
|
||||
|
||||
@staticmethod
|
||||
def to_v_list(v, n):
|
||||
"""Translate an arbitrary number of string and/or list arguments to a list of list of string arguments
|
||||
|
||||
:param v: Arguments
|
||||
:type v: str or list
|
||||
:param n: Number of elements to generate arguments for
|
||||
:type n: int
|
||||
:rtype: list
|
||||
:returns: list of assembled arguments
|
||||
"""
|
||||
if isinstance(v, str):
|
||||
vv = v
|
||||
v = []
|
||||
for i in range(n):
|
||||
v.append([vv])
|
||||
elif not isinstance(v, list):
|
||||
raise ValueError('argument must be single string, or list or strings or lists')
|
||||
else:
|
||||
if len(v) != n:
|
||||
raise ValueError('v argument count must match integer n')
|
||||
for i in range(n):
|
||||
if isinstance(v[i], str):
|
||||
v[i] = [v[i]]
|
||||
elif not isinstance(v, list):
|
||||
raise ValueError('proof argument must be single string, or list or strings or lists')
|
||||
|
||||
return v
|
||||
|
||||
|
||||
def default_token(self):
|
||||
"""Retrieves the default fallback token of the custodial network.
|
||||
|
||||
:returns: uuid of root task
|
||||
:rtype: celery.Task
|
||||
"""
|
||||
s_token = celery.signature(
|
||||
'cic_eth.admin.token.default_token',
|
||||
'cic_eth.eth.erc20.default_token',
|
||||
[],
|
||||
queue=self.queue,
|
||||
)
|
||||
@@ -34,6 +70,97 @@ class Api(ApiBase):
|
||||
return s_token.apply_async()
|
||||
|
||||
|
||||
def token(self, token_symbol, proof=None):
|
||||
"""Single-token alias for tokens method.
|
||||
|
||||
See tokens method for details.
|
||||
|
||||
:param token_symbol: Token symbol to look up
|
||||
:type token_symbol: str
|
||||
:param proof: Proofs to add to signature verification for the token
|
||||
:type proof: str or list
|
||||
:returns: uuid of root task
|
||||
:rtype: celery.Task
|
||||
"""
|
||||
if not isinstance(token_symbol, str):
|
||||
raise ValueError('token symbol must be string')
|
||||
|
||||
return self.tokens([token_symbol], proof=proof)
|
||||
|
||||
|
||||
def tokens(self, token_symbols, proof=None):
|
||||
"""Perform a token data lookup from the token index. The token index will enforce unique associations between token symbol and contract address.
|
||||
|
||||
Token symbols are always strings, and should be specified using uppercase letters.
|
||||
|
||||
If the proof argument is included, the network will be queried for trusted signatures on the given proof(s). There must exist at least one trusted signature for every given proof for every token. Trusted signatures for the custodial system are provided at service startup.
|
||||
|
||||
The proof argument may be specified in a number of ways:
|
||||
|
||||
- as None, in which case proof checks are skipped (although there may still be builtin proof checks being performed)
|
||||
- as a single string, where the same proof is used for each token lookup
|
||||
- as an array of strings, where the respective proof is used for the respective token. number of proofs must match the number of tokens.
|
||||
- as an array of lists, where the respective proofs in each list is used for the respective token. number of lists of proofs must match the number of tokens.
|
||||
|
||||
The success callback provided at the Api object instantiation will receive individual calls for each token that passes the proof checks. Each token that does not pass is passed to the Api error callback.
|
||||
|
||||
This method is not intended to be used synchronously. Do so at your peril.
|
||||
|
||||
:param token_symbols: Token symbol strings to look up
|
||||
:type token_symbol: list
|
||||
:param proof: Proof(s) to verify tokens against
|
||||
:type proof: None, str or list
|
||||
:returns: uuid of root task
|
||||
:rtype: celery.Task
|
||||
"""
|
||||
if not isinstance(token_symbols, list):
|
||||
raise ValueError('token symbols argument must be list')
|
||||
|
||||
if proof == None:
|
||||
logg.debug('looking up tokens without external proof check: {}'.format(','.join(token_symbols)))
|
||||
proof = ''
|
||||
|
||||
logg.debug('proof is {}'.format(proof))
|
||||
l = len(token_symbols)
|
||||
if len(proof) == 0:
|
||||
l = 0
|
||||
proof = Api.to_v_list(proof, l)
|
||||
|
||||
chain_spec_dict = self.chain_spec.asdict()
|
||||
|
||||
s_token_resolve = celery.signature(
|
||||
'cic_eth.eth.erc20.resolve_tokens_by_symbol',
|
||||
[
|
||||
token_symbols,
|
||||
chain_spec_dict,
|
||||
],
|
||||
queue=self.queue,
|
||||
)
|
||||
|
||||
s_token_info = celery.signature(
|
||||
'cic_eth.eth.erc20.token_info',
|
||||
[
|
||||
chain_spec_dict,
|
||||
proof,
|
||||
],
|
||||
queue=self.queue,
|
||||
)
|
||||
|
||||
s_token_verify = celery.signature(
|
||||
'cic_eth.eth.erc20.verify_token_info',
|
||||
[
|
||||
chain_spec_dict,
|
||||
self.callback_success,
|
||||
self.callback_error,
|
||||
],
|
||||
queue=self.queue,
|
||||
)
|
||||
|
||||
s_token_info.link(s_token_verify)
|
||||
s_token_resolve.link(s_token_info)
|
||||
return s_token_resolve.apply_async()
|
||||
|
||||
|
||||
# def convert_transfer(self, from_address, to_address, target_return, minimum_return, from_token_symbol, to_token_symbol):
|
||||
# """Executes a chain of celery tasks that performs conversion between two ERC20 tokens, and transfers to a specified receipient after convert has completed.
|
||||
#
|
||||
@@ -254,6 +381,8 @@ class Api(ApiBase):
|
||||
:returns: uuid of root task
|
||||
:rtype: celery.Task
|
||||
"""
|
||||
#from_address = strip_0x(from_address)
|
||||
#to_address = strip_0x(to_address)
|
||||
s_check = celery.signature(
|
||||
'cic_eth.admin.ctrl.check_lock',
|
||||
[
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import logging
|
||||
|
||||
import celery
|
||||
|
||||
celery_app = celery.current_app
|
||||
logg = celery_app.log.get_default_logger()
|
||||
#logg = celery_app.log.get_default_logger()
|
||||
logg = logging.getLogger()
|
||||
|
||||
|
||||
@celery_app.task(bind=True)
|
||||
|
||||
@@ -48,8 +48,6 @@ class RoleMissingError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
class IntegrityError(Exception):
|
||||
"""Exception raised to signal irregularities with deduplication and ordering of tasks
|
||||
|
||||
@@ -85,3 +83,8 @@ class RoleAgencyError(SeppukuError):
|
||||
class YouAreBrokeError(Exception):
|
||||
"""Exception raised when a value transfer is attempted without access to sufficient funds
|
||||
"""
|
||||
|
||||
|
||||
class TrustError(Exception):
|
||||
"""Exception raised when required trust proofs are missing for a request
|
||||
"""
|
||||
|
||||
@@ -13,7 +13,7 @@ from chainlib.eth.sign import (
|
||||
new_account,
|
||||
sign_message,
|
||||
)
|
||||
from chainlib.eth.address import to_checksum_address
|
||||
from chainlib.eth.address import to_checksum_address, is_address
|
||||
from chainlib.eth.tx import TxFormat
|
||||
from chainlib.chain import ChainSpec
|
||||
from chainlib.error import JSONRPCException
|
||||
@@ -31,6 +31,7 @@ from cic_eth.eth.gas import (
|
||||
from cic_eth.db.models.nonce import Nonce
|
||||
from cic_eth.db.models.base import SessionBase
|
||||
from cic_eth.db.models.role import AccountRole
|
||||
from cic_eth.encode import tx_normalize
|
||||
from cic_eth.error import (
|
||||
RoleMissingError,
|
||||
SignerError,
|
||||
@@ -49,6 +50,7 @@ from cic_eth.queue.tx import (
|
||||
from cic_eth.encode import (
|
||||
unpack_normal,
|
||||
ZERO_ADDRESS_NORMAL,
|
||||
tx_normalize,
|
||||
)
|
||||
|
||||
logg = logging.getLogger()
|
||||
@@ -84,7 +86,7 @@ def create(self, password, chain_spec_dict):
|
||||
# TODO: It seems infeasible that a can be None in any case, verify
|
||||
if a == None:
|
||||
raise SignerError('create account')
|
||||
|
||||
a = tx_normalize.wallet_address(a)
|
||||
logg.debug('created account {}'.format(a))
|
||||
|
||||
# Initialize nonce provider record for account
|
||||
@@ -175,6 +177,9 @@ def gift(self, account_address, chain_spec_dict):
|
||||
"""
|
||||
chain_spec = ChainSpec.from_dict(chain_spec_dict)
|
||||
|
||||
if is_address(account_address):
|
||||
account_address = tx_normalize.wallet_address(account_address)
|
||||
|
||||
logg.debug('gift account address {} to index'.format(account_address))
|
||||
queue = self.request.delivery_info.get('routing_key')
|
||||
|
||||
@@ -248,8 +253,9 @@ def have(self, account, chain_spec_dict):
|
||||
|
||||
@celery_app.task(bind=True, base=CriticalSQLAlchemyTask)
|
||||
def set_role(self, tag, address, chain_spec_dict):
|
||||
if not to_checksum_address(address):
|
||||
raise ValueError('invalid checksum address {}'.format(address))
|
||||
if not is_address(address):
|
||||
raise ValueError('invalid address {}'.format(address))
|
||||
address = tx_normalize.wallet_address(address)
|
||||
session = SessionBase.create_session()
|
||||
role = AccountRole.set(tag, address, session=session)
|
||||
session.add(role)
|
||||
@@ -298,13 +304,15 @@ def cache_gift_data(
|
||||
tx_signed_raw_bytes = bytes.fromhex(strip_0x(tx_signed_raw_hex))
|
||||
tx = unpack_normal(tx_signed_raw_bytes, chain_spec)
|
||||
tx_data = Faucet.parse_give_to_request(tx['data'])
|
||||
sender_address = tx_normalize.wallet_address(tx['from'])
|
||||
recipient_address = tx_normalize.wallet_address(tx['to'])
|
||||
|
||||
session = self.create_session()
|
||||
|
||||
tx_dict = {
|
||||
'hash': tx['hash'],
|
||||
'from': tx['from'],
|
||||
'to': tx['to'],
|
||||
'from': sender_address,
|
||||
'to': recipient_address,
|
||||
'source_token': ZERO_ADDRESS_NORMAL,
|
||||
'destination_token': ZERO_ADDRESS_NORMAL,
|
||||
'from_value': 0,
|
||||
@@ -338,12 +346,14 @@ def cache_account_data(
|
||||
tx_signed_raw_bytes = bytes.fromhex(strip_0x(tx_signed_raw_hex))
|
||||
tx = unpack_normal(tx_signed_raw_bytes, chain_spec)
|
||||
tx_data = AccountsIndex.parse_add_request(tx['data'])
|
||||
sender_address = tx_normalize.wallet_address(tx['from'])
|
||||
recipient_address = tx_normalize.wallet_address(tx['to'])
|
||||
|
||||
session = SessionBase.create_session()
|
||||
tx_dict = {
|
||||
'hash': tx['hash'],
|
||||
'from': tx['from'],
|
||||
'to': tx['to'],
|
||||
'from': sender_address,
|
||||
'to': recipient_address,
|
||||
'source_token': ZERO_ADDRESS_NORMAL,
|
||||
'destination_token': ZERO_ADDRESS_NORMAL,
|
||||
'from_value': 0,
|
||||
|
||||
@@ -12,10 +12,14 @@ from chainlib.eth.tx import (
|
||||
)
|
||||
from cic_eth_registry import CICRegistry
|
||||
from cic_eth_registry.erc20 import ERC20Token
|
||||
from hexathon import strip_0x
|
||||
from hexathon import (
|
||||
strip_0x,
|
||||
add_0x,
|
||||
)
|
||||
from chainqueue.error import NotLocalTxError
|
||||
from eth_erc20 import ERC20
|
||||
from chainqueue.sql.tx import cache_tx_dict
|
||||
from okota.token_index import to_identifier
|
||||
|
||||
# local imports
|
||||
from cic_eth.db.models.base import SessionBase
|
||||
@@ -36,8 +40,11 @@ from cic_eth.task import (
|
||||
CriticalSQLAlchemyTask,
|
||||
CriticalWeb3Task,
|
||||
CriticalSQLAlchemyAndSignerTask,
|
||||
BaseTask,
|
||||
)
|
||||
from cic_eth.eth.nonce import CustodialTaskNonceOracle
|
||||
from cic_eth.encode import tx_normalize
|
||||
from cic_eth.eth.trust import verify_proofs
|
||||
|
||||
celery_app = celery.current_app
|
||||
logg = logging.getLogger()
|
||||
@@ -62,7 +69,8 @@ def balance(tokens, holder_address, chain_spec_dict):
|
||||
|
||||
for t in tokens:
|
||||
address = t['address']
|
||||
token = ERC20Token(chain_spec, rpc, address)
|
||||
logg.debug('address {} {}'.format(address, holder_address))
|
||||
token = ERC20Token(chain_spec, rpc, add_0x(address))
|
||||
c = ERC20(chain_spec)
|
||||
o = c.balance_of(address, holder_address, sender_address=caller_address)
|
||||
r = rpc.do(o)
|
||||
@@ -371,13 +379,15 @@ def cache_transfer_data(
|
||||
tx = unpack(tx_signed_raw_bytes, chain_spec)
|
||||
|
||||
tx_data = ERC20.parse_transfer_request(tx['data'])
|
||||
recipient_address = tx_data[0]
|
||||
sender_address = tx_normalize.wallet_address(tx['from'])
|
||||
recipient_address = tx_normalize.wallet_address(tx_data[0])
|
||||
token_value = tx_data[1]
|
||||
|
||||
|
||||
session = SessionBase.create_session()
|
||||
tx_dict = {
|
||||
'hash': tx_hash_hex,
|
||||
'from': tx['from'],
|
||||
'from': sender_address,
|
||||
'to': recipient_address,
|
||||
'source_token': tx['to'],
|
||||
'destination_token': tx['to'],
|
||||
@@ -448,13 +458,14 @@ def cache_approve_data(
|
||||
tx = unpack(tx_signed_raw_bytes, chain_spec)
|
||||
|
||||
tx_data = ERC20.parse_approve_request(tx['data'])
|
||||
recipient_address = tx_data[0]
|
||||
sender_address = tx_normalize.wallet_address(tx['from'])
|
||||
recipient_address = tx_normalize.wallet_address(tx_data[0])
|
||||
token_value = tx_data[1]
|
||||
|
||||
session = SessionBase.create_session()
|
||||
tx_dict = {
|
||||
'hash': tx_hash_hex,
|
||||
'from': tx['from'],
|
||||
'from': sender_address,
|
||||
'to': recipient_address,
|
||||
'source_token': tx['to'],
|
||||
'destination_token': tx['to'],
|
||||
@@ -465,3 +476,69 @@ def cache_approve_data(
|
||||
session.close()
|
||||
return (tx_hash_hex, cache_id)
|
||||
|
||||
|
||||
@celery_app.task(bind=True, base=BaseTask)
|
||||
def token_info(self, tokens, chain_spec_dict, proofs=[]):
|
||||
chain_spec = ChainSpec.from_dict(chain_spec_dict)
|
||||
rpc = RPCConnection.connect(chain_spec, 'default')
|
||||
|
||||
i = 0
|
||||
|
||||
for token in tokens:
|
||||
result_data = []
|
||||
token_chain_object = ERC20Token(chain_spec, rpc, add_0x(token['address']))
|
||||
token_chain_object.load(rpc)
|
||||
|
||||
token_symbol_proof_hex = to_identifier(token_chain_object.symbol)
|
||||
token_proofs = [token_symbol_proof_hex]
|
||||
if len(proofs) > 0:
|
||||
token_proofs += proofs[i]
|
||||
|
||||
tokens[i] = {
|
||||
'decimals': token_chain_object.decimals,
|
||||
'name': token_chain_object.name,
|
||||
'symbol': token_chain_object.symbol,
|
||||
'address': tx_normalize.executable_address(token_chain_object.address),
|
||||
'proofs': token_proofs,
|
||||
'converters': tokens[i]['converters'],
|
||||
}
|
||||
i += 1
|
||||
|
||||
return tokens
|
||||
|
||||
|
||||
@celery_app.task(bind=True, base=BaseTask)
|
||||
def verify_token_info(self, tokens, chain_spec_dict, success_callback, error_callback):
|
||||
queue = self.request.delivery_info.get('routing_key')
|
||||
|
||||
for token in tokens:
|
||||
s = celery.signature(
|
||||
'cic_eth.eth.trust.verify_proofs',
|
||||
[
|
||||
token,
|
||||
token['address'],
|
||||
token['proofs'],
|
||||
chain_spec_dict,
|
||||
success_callback,
|
||||
error_callback,
|
||||
],
|
||||
queue=queue,
|
||||
)
|
||||
|
||||
if success_callback != None:
|
||||
s.link(success_callback)
|
||||
if error_callback != None:
|
||||
s.on_error(error_callback)
|
||||
s.apply_async()
|
||||
|
||||
return tokens
|
||||
|
||||
|
||||
@celery_app.task(bind=True, base=BaseTask)
|
||||
def default_token(self):
|
||||
return {
|
||||
'symbol': self.default_token_symbol,
|
||||
'address': self.default_token_address,
|
||||
'name': self.default_token_name,
|
||||
'decimals': self.default_token_decimals,
|
||||
}
|
||||
|
||||
@@ -9,7 +9,11 @@ from hexathon import (
|
||||
)
|
||||
#from chainlib.eth.constant import ZERO_ADDRESS
|
||||
from chainlib.chain import ChainSpec
|
||||
from chainlib.eth.address import is_checksum_address
|
||||
from chainlib.eth.address import (
|
||||
is_checksum_address,
|
||||
to_checksum_address,
|
||||
is_address
|
||||
)
|
||||
from chainlib.connection import RPCConnection
|
||||
from chainqueue.db.enum import StatusBits
|
||||
from chainqueue.sql.tx import cache_tx_dict
|
||||
@@ -74,7 +78,6 @@ class MaxGasOracle:
|
||||
return MAXIMUM_FEE_UNITS
|
||||
|
||||
|
||||
#def create_check_gas_task(tx_signed_raws_hex, chain_spec, holder_address, gas=None, tx_hashes_hex=None, queue=None):
|
||||
def create_check_gas_task(tx_signed_raws_hex, chain_spec, holder_address, gas=None, tx_hashes_hex=None, queue=None):
|
||||
"""Creates a celery task signature for a check_gas task that adds the task to the outgoing queue to be processed by the dispatcher.
|
||||
|
||||
@@ -179,8 +182,9 @@ def check_gas(self, tx_hashes_hex, chain_spec_dict, txs_hex=[], address=None, ga
|
||||
:return: Signed raw transaction data list
|
||||
:rtype: param txs, unchanged
|
||||
"""
|
||||
rpc_format_address = None
|
||||
if address != None:
|
||||
if not is_checksum_address(address):
|
||||
if not is_address(address):
|
||||
raise ValueError('invalid address {}'.format(address))
|
||||
address = tx_normalize.wallet_address(address)
|
||||
address = add_0x(address)
|
||||
@@ -195,7 +199,6 @@ def check_gas(self, tx_hashes_hex, chain_spec_dict, txs_hex=[], address=None, ga
|
||||
txs.append(tx)
|
||||
|
||||
chain_spec = ChainSpec.from_dict(chain_spec_dict)
|
||||
logg.debug('txs {} tx_hashes {}'.format(txs, tx_hashes))
|
||||
|
||||
addresspass = None
|
||||
if len(txs) == 0:
|
||||
@@ -211,13 +214,15 @@ def check_gas(self, tx_hashes_hex, chain_spec_dict, txs_hex=[], address=None, ga
|
||||
raise ValueError('txs passed to check gas must all have same sender; had {} got {}'.format(address, tx['from']))
|
||||
addresspass.append(address)
|
||||
|
||||
rpc_format_address = add_0x(to_checksum_address(address))
|
||||
|
||||
queue = self.request.delivery_info.get('routing_key')
|
||||
|
||||
conn = RPCConnection.connect(chain_spec)
|
||||
|
||||
gas_balance = 0
|
||||
try:
|
||||
o = balance(address)
|
||||
o = balance(rpc_format_address)
|
||||
r = conn.do(o)
|
||||
conn.disconnect()
|
||||
gas_balance = abi_decode_single(ABIContractType.UINT256, r)
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
from chainlib.eth.constant import ZERO_ADDRESS
|
||||
from chainlib.status import Status as TxStatus
|
||||
from cic_eth_registry.erc20 import ERC20Token
|
||||
from hexathon import add_0x
|
||||
|
||||
# local imports
|
||||
# local impor:ts
|
||||
from cic_eth.ext.address import translate_address
|
||||
|
||||
|
||||
@@ -44,8 +45,8 @@ class ExtendedTx:
|
||||
destination = source
|
||||
if destination_value == None:
|
||||
destination_value = source_value
|
||||
st = ERC20Token(self.chain_spec, self.rpc, source)
|
||||
dt = ERC20Token(self.chain_spec, self.rpc, destination)
|
||||
st = ERC20Token(self.chain_spec, self.rpc, add_0x(source))
|
||||
dt = ERC20Token(self.chain_spec, self.rpc, add_0x(destination))
|
||||
self.source_token = source
|
||||
self.source_token_symbol = st.symbol
|
||||
self.source_token_name = st.name
|
||||
|
||||
@@ -3,11 +3,12 @@ import logging
|
||||
|
||||
# external imports
|
||||
import celery
|
||||
from chainlib.eth.address import is_checksum_address
|
||||
from chainlib.eth.address import is_checksum_address, is_address, strip_0x
|
||||
|
||||
# local imports
|
||||
from cic_eth.db.models.role import AccountRole
|
||||
from cic_eth.db.models.base import SessionBase
|
||||
from cic_eth.encode import tx_normalize
|
||||
from cic_eth.task import CriticalSQLAlchemyTask
|
||||
from cic_eth.db.models.nonce import (
|
||||
Nonce,
|
||||
@@ -42,7 +43,8 @@ class CustodialTaskNonceOracle():
|
||||
:returns: Nonce
|
||||
:rtype: number
|
||||
"""
|
||||
r = NonceReservation.release(self.address, self.uuid, session=self.session)
|
||||
address = tx_normalize.wallet_address(self.address)
|
||||
r = NonceReservation.release(address, self.uuid, session=self.session)
|
||||
return r[1]
|
||||
|
||||
|
||||
@@ -58,17 +60,18 @@ def reserve_nonce(self, chained_input, chain_spec_dict, signer_address=None):
|
||||
address = chained_input
|
||||
logg.debug('non-explicit address for reserve nonce, using arg head {}'.format(chained_input))
|
||||
else:
|
||||
if is_checksum_address(signer_address):
|
||||
if is_address(signer_address):
|
||||
address = signer_address
|
||||
logg.debug('explicit address for reserve nonce {}'.format(signer_address))
|
||||
else:
|
||||
address = AccountRole.get_address(signer_address, session=session)
|
||||
logg.debug('role for reserve nonce {} -> {}'.format(signer_address, address))
|
||||
|
||||
if not is_checksum_address(address):
|
||||
if not is_address(address):
|
||||
raise ValueError('invalid result when resolving address for nonce {}'.format(address))
|
||||
|
||||
root_id = self.request.root_id
|
||||
address = tx_normalize.wallet_address(address)
|
||||
r = NonceReservation.next(address, root_id, session=session)
|
||||
logg.debug('nonce {} reserved for address {} task {}'.format(r[1], address, r[0]))
|
||||
|
||||
|
||||
77
apps/cic-eth/cic_eth/eth/trust.py
Normal file
77
apps/cic-eth/cic_eth/eth/trust.py
Normal file
@@ -0,0 +1,77 @@
|
||||
# standard imports
|
||||
import logging
|
||||
|
||||
# external imports
|
||||
import celery
|
||||
from eth_address_declarator import Declarator
|
||||
from chainlib.connection import RPCConnection
|
||||
from chainlib.chain import ChainSpec
|
||||
from cic_eth.db.models.role import AccountRole
|
||||
from cic_eth_registry import CICRegistry
|
||||
from hexathon import strip_0x
|
||||
|
||||
# local imports
|
||||
from cic_eth.task import BaseTask
|
||||
from cic_eth.error import TrustError
|
||||
|
||||
celery_app = celery.current_app
|
||||
logg = logging.getLogger()
|
||||
|
||||
|
||||
@celery_app.task(bind=True, base=BaseTask)
|
||||
def verify_proof(self, chained_input, proof, subject, chain_spec_dict, success_callback, error_callback):
|
||||
proof = strip_0x(proof)
|
||||
|
||||
proofs = []
|
||||
|
||||
logg.debug('proof count {}'.format(len(proofs)))
|
||||
if len(proofs) == 0:
|
||||
logg.debug('error {}'.format(len(proofs)))
|
||||
raise TrustError('foo')
|
||||
|
||||
return (chained_input, (proof, proofs))
|
||||
|
||||
|
||||
@celery_app.task(bind=True, base=BaseTask)
|
||||
def verify_proofs(self, chained_input, subject, proofs, chain_spec_dict, success_callback, error_callback):
|
||||
queue = self.request.delivery_info.get('routing_key')
|
||||
|
||||
chain_spec = ChainSpec.from_dict(chain_spec_dict)
|
||||
rpc = RPCConnection.connect(chain_spec, 'default')
|
||||
|
||||
session = self.create_session()
|
||||
sender_address = AccountRole.get_address('DEFAULT', session)
|
||||
|
||||
registry = CICRegistry(chain_spec, rpc)
|
||||
declarator_address = registry.by_name('AddressDeclarator', sender_address=sender_address)
|
||||
|
||||
declarator = Declarator(chain_spec)
|
||||
|
||||
have_proofs = {}
|
||||
|
||||
for proof in proofs:
|
||||
|
||||
proof = strip_0x(proof)
|
||||
|
||||
have_proofs[proof] = []
|
||||
|
||||
for trusted_address in self.trusted_addresses:
|
||||
o = declarator.declaration(declarator_address, trusted_address, subject, sender_address=sender_address)
|
||||
r = rpc.do(o)
|
||||
declarations = declarator.parse_declaration(r)
|
||||
logg.debug('comparing proof {} with declarations for {} by {}: {}'.format(proof, subject, trusted_address, declarations))
|
||||
|
||||
for declaration in declarations:
|
||||
declaration = strip_0x(declaration)
|
||||
if declaration == proof:
|
||||
logg.debug('have token proof {} match for trusted address {}'.format(declaration, trusted_address))
|
||||
have_proofs[proof].append(trusted_address)
|
||||
|
||||
out_proofs = {}
|
||||
for proof in have_proofs.keys():
|
||||
if len(have_proofs[proof]) == 0:
|
||||
logg.error('missing signer for proof {} subject {}'.format(proof, subject))
|
||||
raise TrustError((subject, proof,))
|
||||
out_proofs[proof] = have_proofs[proof]
|
||||
|
||||
return (chained_input, out_proofs)
|
||||
@@ -32,6 +32,7 @@ from potaahto.symbols import snake_and_camel
|
||||
from cic_eth.queue.time import tx_times
|
||||
from cic_eth.task import BaseTask
|
||||
from cic_eth.db.models.base import SessionBase
|
||||
from cic_eth.encode import tx_normalize
|
||||
|
||||
celery_app = celery.current_app
|
||||
logg = logging.getLogger()
|
||||
@@ -134,7 +135,7 @@ def list_tx_by_bloom(self, bloomspec, address, chain_spec_dict):
|
||||
tx_address = transfer_data[0]
|
||||
tx_token_value = transfer_data[1]
|
||||
|
||||
if address == tx_address:
|
||||
if tx_normalize.wallet_address(address) == tx_normalize.wallet_address(tx_address):
|
||||
status = StatusEnum.SENT
|
||||
try:
|
||||
o = receipt(tx['hash'])
|
||||
@@ -152,8 +153,8 @@ def list_tx_by_bloom(self, bloomspec, address, chain_spec_dict):
|
||||
times = tx_times(tx['hash'], chain_spec)
|
||||
tx_r = {
|
||||
'hash': tx['hash'],
|
||||
'sender': tx['from'],
|
||||
'recipient': tx_address,
|
||||
'sender': tx_normalize.wallet_address(tx['from']),
|
||||
'recipient': tx_normalize.wallet_address(tx_address),
|
||||
'source_value': tx_token_value,
|
||||
'destination_value': tx_token_value,
|
||||
'source_token': tx['to'],
|
||||
@@ -164,10 +165,10 @@ def list_tx_by_bloom(self, bloomspec, address, chain_spec_dict):
|
||||
tx_r['date_created'] = times['queue']
|
||||
else:
|
||||
tx_r['date_created'] = times['network']
|
||||
txs[tx['hash']] = tx_r
|
||||
txs[strip_0x(tx['hash'])] = tx_r
|
||||
break
|
||||
return txs
|
||||
|
||||
return txs
|
||||
|
||||
|
||||
# TODO: Surely it must be possible to optimize this
|
||||
@@ -230,6 +231,8 @@ def tx_collate(self, tx_batches, chain_spec_dict, offset, limit, newest_first=Tr
|
||||
except UnknownContractError:
|
||||
logg.error('verify failed on tx {}, skipping'.format(tx['hash']))
|
||||
continue
|
||||
tx['recipient'] = tx_normalize.wallet_address(tx['recipient'])
|
||||
tx['sender'] = tx_normalize.wallet_address(tx['sender'])
|
||||
txs.append(tx)
|
||||
|
||||
return txs
|
||||
|
||||
@@ -4,18 +4,21 @@ import tempfile
|
||||
import logging
|
||||
import shutil
|
||||
|
||||
# local impors
|
||||
# local imports
|
||||
from cic_eth.task import BaseTask
|
||||
|
||||
#logg = logging.getLogger(__name__)
|
||||
logg = logging.getLogger()
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def init_celery_tasks(
|
||||
contract_roles,
|
||||
):
|
||||
BaseTask.call_address = contract_roles['DEFAULT']
|
||||
BaseTask.trusted_addresses = [
|
||||
contract_roles['TRUSTED_DECLARATOR'],
|
||||
contract_roles['CONTRACT_DEPLOYER'],
|
||||
]
|
||||
|
||||
|
||||
# celery fixtures
|
||||
@@ -38,6 +41,7 @@ def celery_includes():
|
||||
'cic_eth.callbacks.noop',
|
||||
'cic_eth.callbacks.http',
|
||||
'cic_eth.pytest.mock.filter',
|
||||
'cic_eth.pytest.mock.callback',
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
from .filter import *
|
||||
from .callback import *
|
||||
|
||||
38
apps/cic-eth/cic_eth/pytest/mock/callback.py
Normal file
38
apps/cic-eth/cic_eth/pytest/mock/callback.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# standard imports
|
||||
import os
|
||||
import logging
|
||||
import mmap
|
||||
|
||||
# standard imports
|
||||
import tempfile
|
||||
|
||||
# external imports
|
||||
import celery
|
||||
|
||||
#logg = logging.getLogger(__name__)
|
||||
logg = logging.getLogger()
|
||||
|
||||
celery_app = celery.current_app
|
||||
|
||||
|
||||
class CallbackTask(celery.Task):
|
||||
|
||||
mmap_path = tempfile.mkdtemp()
|
||||
|
||||
|
||||
@celery_app.task(bind=True, base=CallbackTask)
|
||||
def test_callback(self, a, b, c):
|
||||
s = 'ok'
|
||||
if c > 0:
|
||||
s = 'err'
|
||||
|
||||
fp = os.path.join(self.mmap_path, b)
|
||||
f = open(fp, 'wb+')
|
||||
f.write(b'\x00')
|
||||
f.seek(0)
|
||||
m = mmap.mmap(f.fileno(), length=1)
|
||||
m.write(c.to_bytes(1, 'big'))
|
||||
m.close()
|
||||
f.close()
|
||||
|
||||
logg.debug('test callback ({}): {} {} {}'.format(s, a, b, c))
|
||||
@@ -58,6 +58,7 @@ def get_tx_local(chain_spec, tx_hash, session=None):
|
||||
|
||||
@celery_app.task(base=CriticalSQLAlchemyTask)
|
||||
def get_account_tx(chain_spec_dict, address, as_sender=True, as_recipient=True, counterpart=None):
|
||||
address = tx_normalize.wallet_address(address)
|
||||
chain_spec = ChainSpec.from_dict(chain_spec_dict)
|
||||
return get_account_tx_local(chain_spec, address, as_sender=as_sender, as_recipient=as_recipient, counterpart=counterpart)
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ from erc20_faucet import Faucet
|
||||
# local imports
|
||||
from .base import SyncFilter
|
||||
from cic_eth.eth.meta import ExtendedTx
|
||||
from cic_eth.encode import tx_normalize
|
||||
|
||||
logg = logging.getLogger().getChild(__name__)
|
||||
|
||||
@@ -42,9 +43,9 @@ class CallbackFilter(SyncFilter):
|
||||
return (None, None)
|
||||
r = ERC20.parse_transfer_request(tx.payload)
|
||||
transfer_data = {}
|
||||
transfer_data['to'] = r[0]
|
||||
transfer_data['to'] = tx_normalize.wallet_address(r[0])
|
||||
transfer_data['value'] = r[1]
|
||||
transfer_data['from'] = tx.outputs[0]
|
||||
transfer_data['from'] = tx_normalize.wallet_address(tx.outputs[0])
|
||||
transfer_data['token_address'] = tx.inputs[0]
|
||||
return ('transfer', transfer_data)
|
||||
|
||||
@@ -54,8 +55,8 @@ class CallbackFilter(SyncFilter):
|
||||
return (None, None)
|
||||
r = ERC20.parse_transfer_from_request(tx.payload)
|
||||
transfer_data = {}
|
||||
transfer_data['from'] = r[0]
|
||||
transfer_data['to'] = r[1]
|
||||
transfer_data['from'] = tx_normalize.wallet_address(r[0])
|
||||
transfer_data['to'] = tx_normalize.wallet_address(r[1])
|
||||
transfer_data['value'] = r[2]
|
||||
transfer_data['token_address'] = tx.inputs[0]
|
||||
return ('transferfrom', transfer_data)
|
||||
@@ -66,9 +67,9 @@ class CallbackFilter(SyncFilter):
|
||||
return (None, None)
|
||||
r = Faucet.parse_give_to_request(tx.payload)
|
||||
transfer_data = {}
|
||||
transfer_data['to'] = r[0]
|
||||
transfer_data['to'] = tx_normalize.wallet_address(r[0])
|
||||
transfer_data['value'] = tx.value
|
||||
transfer_data['from'] = tx.outputs[0]
|
||||
transfer_data['from'] = tx_normalize.wallet_address(tx.outputs[0])
|
||||
#transfer_data['token_address'] = tx.inputs[0]
|
||||
faucet_contract = tx.inputs[0]
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@ from hexathon import (
|
||||
# local imports
|
||||
from .base import SyncFilter
|
||||
|
||||
logg = logging.getLogger(__name__)
|
||||
#logg = logging.getLogger(__name__)
|
||||
logg = logging.getLogger()
|
||||
|
||||
account_registry_add_log_hash = '0x9cc987676e7d63379f176ea50df0ae8d2d9d1141d1231d4ce15b5965f73c9430'
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ from cic_eth_registry import CICRegistry
|
||||
from erc20_transfer_authorization import TransferAuthorization
|
||||
|
||||
# local imports
|
||||
from cic_eth.encode import tx_normalize
|
||||
from .base import SyncFilter
|
||||
|
||||
|
||||
@@ -52,9 +53,9 @@ class TransferAuthFilter(SyncFilter):
|
||||
|
||||
r = TransferAuthorization.parse_create_request_request(tx.payload)
|
||||
|
||||
sender = r[0]
|
||||
recipient = r[1]
|
||||
token = r[2]
|
||||
sender = tx_normalize.wallet_address(r[0])
|
||||
recipient = tx_normalize.wallet_address(r[1])
|
||||
token = tx_normalize.executable_address(r[2])
|
||||
value = r[3]
|
||||
|
||||
token_data = {
|
||||
|
||||
@@ -206,10 +206,11 @@ def main():
|
||||
|
||||
BaseTask.default_token_symbol = config.get('CIC_DEFAULT_TOKEN_SYMBOL')
|
||||
BaseTask.default_token_address = registry.by_name(BaseTask.default_token_symbol)
|
||||
default_token = ERC20Token(chain_spec, conn, BaseTask.default_token_address)
|
||||
default_token = ERC20Token(chain_spec, conn, add_0x(BaseTask.default_token_address))
|
||||
default_token.load(conn)
|
||||
BaseTask.default_token_decimals = default_token.decimals
|
||||
BaseTask.default_token_name = default_token.name
|
||||
BaseTask.trusted_addresses = trusted_addresses
|
||||
|
||||
BaseTask.run_dir = config.get('CIC_RUN_DIR')
|
||||
logg.info('default token set to {} {}'.format(BaseTask.default_token_symbol, BaseTask.default_token_address))
|
||||
|
||||
@@ -28,6 +28,7 @@ class BaseTask(celery.Task):
|
||||
|
||||
session_func = SessionBase.create_session
|
||||
call_address = ZERO_ADDRESS
|
||||
trusted_addresses = []
|
||||
create_nonce_oracle = RPCNonceOracle
|
||||
create_gas_oracle = RPCGasOracle
|
||||
default_token_address = None
|
||||
|
||||
@@ -10,7 +10,7 @@ version = (
|
||||
0,
|
||||
12,
|
||||
4,
|
||||
'alpha.8',
|
||||
'alpha.11',
|
||||
)
|
||||
|
||||
version_object = semver.VersionInfo(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
celery==4.4.7
|
||||
chainlib-eth>=0.0.9a14,<0.1.0
|
||||
chainlib-eth>=0.0.9rc4,<0.1.0
|
||||
semver==2.13.0
|
||||
crypto-dev-signer>=0.4.15rc2,<0.5.0
|
||||
|
||||
@@ -6,10 +6,11 @@ redis==3.5.3
|
||||
hexathon~=0.0.1a8
|
||||
pycryptodome==3.10.1
|
||||
liveness~=0.0.1a7
|
||||
eth-address-index>=0.2.3a4,<0.3.0
|
||||
eth-address-index>=0.2.4a1,<0.3.0
|
||||
eth-accounts-index>=0.1.2a3,<0.2.0
|
||||
cic-eth-registry>=0.6.1a2,<0.7.0
|
||||
cic-eth-registry>=0.6.1a5,<0.7.0
|
||||
erc20-faucet>=0.3.2a2,<0.4.0
|
||||
erc20-transfer-authorization>=0.3.5a2,<0.4.0
|
||||
sarafu-faucet>=0.0.7a2,<0.1.0
|
||||
moolb~=0.1.1b2
|
||||
okota>=0.2.4a6,<0.3.0
|
||||
|
||||
@@ -18,7 +18,10 @@ from eth_erc20 import ERC20
|
||||
from sarafu_faucet import MinterFaucet
|
||||
from eth_accounts_index.registry import AccountRegistry
|
||||
from potaahto.symbols import snake_and_camel
|
||||
from hexathon import add_0x
|
||||
from hexathon import (
|
||||
add_0x,
|
||||
strip_0x,
|
||||
)
|
||||
|
||||
# local imports
|
||||
from cic_eth.runnable.daemons.filters.callback import CallbackFilter
|
||||
@@ -160,7 +163,7 @@ def test_faucet_gift_to_tx(
|
||||
assert transfer_data['token_address'] == foo_token
|
||||
|
||||
|
||||
def test_callback_filter(
|
||||
def test_callback_filter_filter(
|
||||
default_chain_spec,
|
||||
init_database,
|
||||
eth_rpc,
|
||||
@@ -213,6 +216,7 @@ def test_callback_filter(
|
||||
|
||||
def call_back(self, transfer_type, result):
|
||||
self.results[transfer_type] = result
|
||||
logg.debug('result {}'.format(result))
|
||||
return self
|
||||
|
||||
mock = CallbackMock()
|
||||
@@ -221,4 +225,4 @@ def test_callback_filter(
|
||||
fltr.filter(eth_rpc, mockblock, tx, init_database)
|
||||
|
||||
assert mock.results.get('transfer') != None
|
||||
assert mock.results['transfer']['destination_token'] == foo_token
|
||||
assert mock.results['transfer']['destination_token'] == strip_0x(foo_token)
|
||||
|
||||
@@ -17,6 +17,9 @@ from chainlib.eth.block import (
|
||||
block_by_number,
|
||||
Block,
|
||||
)
|
||||
from chainlib.eth.address import (
|
||||
to_checksum_address,
|
||||
)
|
||||
from erc20_faucet import Faucet
|
||||
from hexathon import (
|
||||
strip_0x,
|
||||
@@ -25,7 +28,6 @@ from hexathon import (
|
||||
|
||||
# local imports
|
||||
from cic_eth.runnable.daemons.filters.register import RegistrationFilter
|
||||
from cic_eth.encode import tx_normalize
|
||||
from cic_eth.queue.query import get_account_tx_local
|
||||
|
||||
logg = logging.getLogger()
|
||||
@@ -70,12 +72,13 @@ def test_register_filter(
|
||||
tx = Tx(tx_src, block=block, rcpt=rcpt)
|
||||
tx.apply_receipt(rcpt)
|
||||
|
||||
fltr = RegistrationFilter(default_chain_spec, add_0x(os.urandom(20).hex()), queue=None)
|
||||
fltr = RegistrationFilter(default_chain_spec, to_checksum_address(os.urandom(20).hex()), queue=None)
|
||||
t = fltr.filter(eth_rpc, block, tx, db_session=init_database)
|
||||
assert t == None
|
||||
|
||||
fltr = RegistrationFilter(default_chain_spec, account_registry, queue=None)
|
||||
fltr = RegistrationFilter(default_chain_spec, to_checksum_address(account_registry), queue=None)
|
||||
t = fltr.filter(eth_rpc, block, tx, db_session=init_database)
|
||||
logg.debug('t {}'.format(t))
|
||||
|
||||
t.get_leaf()
|
||||
assert t.successful()
|
||||
@@ -89,4 +92,4 @@ def test_register_filter(
|
||||
gift_tx = unpack(tx_raw_signed_bytes, default_chain_spec)
|
||||
|
||||
gift = Faucet.parse_give_to_request(gift_tx['data'])
|
||||
assert gift[0] == agent_roles['ALICE']
|
||||
assert add_0x(gift[0]) == agent_roles['ALICE']
|
||||
|
||||
@@ -19,6 +19,7 @@ from chainqueue.sql.query import get_account_tx
|
||||
|
||||
# local imports
|
||||
from cic_eth.runnable.daemons.filters.transferauth import TransferAuthFilter
|
||||
from cic_eth.encode import tx_normalize
|
||||
|
||||
|
||||
def test_filter_transferauth(
|
||||
@@ -66,7 +67,8 @@ def test_filter_transferauth(
|
||||
t.get_leaf()
|
||||
assert t.successful()
|
||||
|
||||
approve_txs = get_account_tx(default_chain_spec.asdict(), agent_roles['ALICE'], as_sender=True, session=init_database)
|
||||
#approve_txs = get_account_tx(default_chain_spec.asdict(), agent_roles['ALICE'], as_sender=True, session=init_database)
|
||||
approve_txs = get_account_tx(default_chain_spec.asdict(), tx_normalize.wallet_address(agent_roles['ALICE']), as_sender=True, session=init_database)
|
||||
ks = list(approve_txs.keys())
|
||||
assert len(ks) == 1
|
||||
|
||||
@@ -76,4 +78,4 @@ def test_filter_transferauth(
|
||||
|
||||
c = ERC20(default_chain_spec)
|
||||
approve = c.parse_approve_request(approve_tx['data'])
|
||||
assert approve[0] == agent_roles['BOB']
|
||||
assert approve[0] == strip_0x(agent_roles['BOB'])
|
||||
|
||||
@@ -110,8 +110,8 @@ def test_tag_account(
|
||||
t = api.tag_account('bar', agent_roles['CAROL'], default_chain_spec)
|
||||
t.get()
|
||||
|
||||
assert AccountRole.get_address('foo', init_database) == agent_roles['ALICE']
|
||||
assert AccountRole.get_address('bar', init_database) == agent_roles['CAROL']
|
||||
assert AccountRole.get_address('foo', init_database) == tx_normalize.wallet_address(agent_roles['ALICE'])
|
||||
assert AccountRole.get_address('bar', init_database) == tx_normalize.wallet_address(agent_roles['CAROL'])
|
||||
|
||||
|
||||
def test_tx(
|
||||
|
||||
@@ -10,6 +10,7 @@ from cic_eth_registry.erc20 import ERC20Token
|
||||
from chainlib.chain import ChainSpec
|
||||
from eth_accounts_index import AccountsIndex
|
||||
from chainlib.eth.tx import (
|
||||
receipt,
|
||||
transaction,
|
||||
)
|
||||
from chainqueue.sql.state import (
|
||||
@@ -29,6 +30,7 @@ def test_account_api(
|
||||
init_database,
|
||||
init_eth_rpc,
|
||||
account_registry,
|
||||
cic_registry,
|
||||
custodial_roles,
|
||||
celery_session_worker,
|
||||
):
|
||||
@@ -49,6 +51,7 @@ def test_account_api_register(
|
||||
eth_rpc,
|
||||
celery_session_worker,
|
||||
):
|
||||
|
||||
api = Api(str(default_chain_spec), callback_param='accounts', callback_task='cic_eth.callbacks.noop.noop', queue=None)
|
||||
t = api.create_account('')
|
||||
register_tx_hash = t.get_leaf()
|
||||
@@ -69,12 +72,18 @@ def test_account_api_register(
|
||||
r = t.get_leaf()
|
||||
assert t.successful()
|
||||
|
||||
o = receipt(register_tx_hash)
|
||||
r = eth_rpc.do(o)
|
||||
assert r['status'] == 1
|
||||
|
||||
o = transaction(register_tx_hash)
|
||||
tx_src = eth_rpc.do(o)
|
||||
|
||||
c = AccountsIndex(default_chain_spec)
|
||||
address = c.parse_add_request(tx_src['data'])
|
||||
logg.debug('address {} '.format(address))
|
||||
o = c.have(account_registry, address[0], sender_address=custodial_roles['CONTRACT_DEPLOYER'])
|
||||
logg.debug('o {}'.format(o))
|
||||
r = eth_rpc.do(o)
|
||||
assert c.parse_have(r)
|
||||
|
||||
|
||||
@@ -1,6 +1,27 @@
|
||||
# standard imports
|
||||
import logging
|
||||
import os
|
||||
import uuid
|
||||
import time
|
||||
import mmap
|
||||
|
||||
# external imports
|
||||
import celery
|
||||
import pytest
|
||||
from hexathon import (
|
||||
strip_0x,
|
||||
uniform as hex_uniform,
|
||||
)
|
||||
|
||||
# local imports
|
||||
from cic_eth.api.api_task import Api
|
||||
from cic_eth.task import BaseTask
|
||||
from cic_eth.error import TrustError
|
||||
from cic_eth.encode import tx_normalize
|
||||
from cic_eth.pytest.mock.callback import CallbackTask
|
||||
|
||||
logg = logging.getLogger()
|
||||
|
||||
|
||||
def test_default_token(
|
||||
default_chain_spec,
|
||||
@@ -17,3 +38,175 @@ def test_default_token(
|
||||
t = api.default_token()
|
||||
r = t.get_leaf()
|
||||
assert r['address'] == foo_token
|
||||
|
||||
|
||||
def test_to_v_list():
|
||||
assert Api.to_v_list('', 0) == []
|
||||
assert Api.to_v_list([], 0) == []
|
||||
assert Api.to_v_list('foo', 1) == [['foo']]
|
||||
assert Api.to_v_list(['foo'], 1) == [['foo']]
|
||||
assert Api.to_v_list(['foo', 'bar'], 2) == [['foo'], ['bar']]
|
||||
assert Api.to_v_list('foo', 3) == [['foo'], ['foo'], ['foo']]
|
||||
assert Api.to_v_list([['foo'], ['bar']], 2) == [['foo'], ['bar']]
|
||||
with pytest.raises(ValueError):
|
||||
Api.to_v_list([['foo'], ['bar']], 3)
|
||||
with pytest.raises(ValueError):
|
||||
Api.to_v_list(['foo', 'bar'], 3)
|
||||
with pytest.raises(ValueError):
|
||||
Api.to_v_list([['foo'], ['bar'], ['baz']], 2)
|
||||
|
||||
assert Api.to_v_list([
|
||||
['foo'],
|
||||
'bar',
|
||||
['inky', 'pinky', 'blinky', 'clyde'],
|
||||
], 3) == [
|
||||
['foo'],
|
||||
['bar'],
|
||||
['inky', 'pinky', 'blinky', 'clyde'],
|
||||
]
|
||||
|
||||
|
||||
def test_token_single(
|
||||
default_chain_spec,
|
||||
foo_token,
|
||||
bar_token,
|
||||
token_registry,
|
||||
register_tokens,
|
||||
register_lookups,
|
||||
cic_registry,
|
||||
init_database,
|
||||
init_celery_tasks,
|
||||
custodial_roles,
|
||||
foo_token_declaration,
|
||||
bar_token_declaration,
|
||||
celery_session_worker,
|
||||
):
|
||||
|
||||
api = Api(str(default_chain_spec), queue=None, callback_param='foo')
|
||||
|
||||
t = api.token('FOO', proof=None)
|
||||
r = t.get()
|
||||
logg.debug('rr {}'.format(r))
|
||||
assert len(r) == 1
|
||||
assert r[0]['address'] == strip_0x(foo_token)
|
||||
|
||||
|
||||
t = api.token('FOO', proof=foo_token_declaration)
|
||||
r = t.get()
|
||||
assert len(r) == 1
|
||||
assert r[0]['address'] == strip_0x(foo_token)
|
||||
|
||||
|
||||
def test_tokens_noproof(
|
||||
default_chain_spec,
|
||||
foo_token,
|
||||
bar_token,
|
||||
token_registry,
|
||||
register_tokens,
|
||||
register_lookups,
|
||||
cic_registry,
|
||||
init_database,
|
||||
init_celery_tasks,
|
||||
custodial_roles,
|
||||
foo_token_declaration,
|
||||
bar_token_declaration,
|
||||
celery_worker,
|
||||
):
|
||||
|
||||
api = Api(str(default_chain_spec), queue=None, callback_param='foo')
|
||||
|
||||
t = api.tokens(['FOO'], proof=[])
|
||||
r = t.get()
|
||||
assert len(r) == 1
|
||||
assert r[0]['address'] == strip_0x(foo_token)
|
||||
|
||||
t = api.tokens(['BAR'], proof='')
|
||||
r = t.get()
|
||||
assert len(r) == 1
|
||||
assert r[0]['address'] == strip_0x(bar_token)
|
||||
|
||||
t = api.tokens(['FOO'], proof=None)
|
||||
r = t.get()
|
||||
assert len(r) == 1
|
||||
assert r[0]['address'] == strip_0x(foo_token)
|
||||
|
||||
|
||||
def test_tokens(
|
||||
default_chain_spec,
|
||||
foo_token,
|
||||
bar_token,
|
||||
token_registry,
|
||||
register_tokens,
|
||||
register_lookups,
|
||||
cic_registry,
|
||||
init_database,
|
||||
init_celery_tasks,
|
||||
custodial_roles,
|
||||
foo_token_declaration,
|
||||
bar_token_declaration,
|
||||
celery_session_worker,
|
||||
):
|
||||
|
||||
api = Api(str(default_chain_spec), queue=None, callback_param='foo')
|
||||
|
||||
t = api.tokens(['FOO'], proof=[[foo_token_declaration]])
|
||||
r = t.get()
|
||||
logg.debug('rr {}'.format(r))
|
||||
assert len(r) == 1
|
||||
assert r[0]['address'] == strip_0x(foo_token)
|
||||
|
||||
t = api.tokens(['BAR', 'FOO'], proof=[[bar_token_declaration], [foo_token_declaration]])
|
||||
r = t.get()
|
||||
logg.debug('results {}'.format(r))
|
||||
assert len(r) == 2
|
||||
assert r[1]['address'] == strip_0x(foo_token)
|
||||
assert r[0]['address'] == strip_0x(bar_token)
|
||||
|
||||
celery_app = celery.current_app
|
||||
|
||||
results = []
|
||||
targets = []
|
||||
|
||||
api_param = str(uuid.uuid4())
|
||||
api = Api(str(default_chain_spec), queue=None, callback_param=api_param, callback_task='cic_eth.pytest.mock.callback.test_callback')
|
||||
bogus_proof = os.urandom(32).hex()
|
||||
t = api.tokens(['FOO'], proof=[[bogus_proof]])
|
||||
r = t.get()
|
||||
logg.debug('r {}'.format(r))
|
||||
|
||||
while True:
|
||||
fp = os.path.join(CallbackTask.mmap_path, api_param)
|
||||
try:
|
||||
f = open(fp, 'rb')
|
||||
except FileNotFoundError:
|
||||
time.sleep(0.1)
|
||||
logg.debug('look for {}'.format(fp))
|
||||
continue
|
||||
f = open(fp, 'rb')
|
||||
m = mmap.mmap(f.fileno(), access=mmap.ACCESS_READ, length=1)
|
||||
v = m.read(1)
|
||||
m.close()
|
||||
f.close()
|
||||
assert v == b'\x01'
|
||||
break
|
||||
|
||||
api_param = str(uuid.uuid4())
|
||||
api = Api(str(default_chain_spec), queue=None, callback_param=api_param, callback_task='cic_eth.pytest.mock.callback.test_callback')
|
||||
t = api.tokens(['BAR'], proof=[[bar_token_declaration]])
|
||||
r = t.get()
|
||||
logg.debug('rr {} {}'.format(r, t.children))
|
||||
|
||||
while True:
|
||||
fp = os.path.join(CallbackTask.mmap_path, api_param)
|
||||
try:
|
||||
f = open(fp, 'rb')
|
||||
except FileNotFoundError:
|
||||
time.sleep(0.1)
|
||||
continue
|
||||
m = mmap.mmap(f.fileno(), access=mmap.ACCESS_READ, length=1)
|
||||
v = m.read(1)
|
||||
m.close()
|
||||
f.close()
|
||||
assert v == b'\x00'
|
||||
break
|
||||
|
||||
|
||||
@@ -3,18 +3,22 @@ import os
|
||||
import logging
|
||||
|
||||
# external imports
|
||||
import pytest
|
||||
from chainlib.eth.address import to_checksum_address
|
||||
from hexathon import add_0x
|
||||
|
||||
# local imports
|
||||
from cic_eth.api.api_task import Api
|
||||
|
||||
logg = logging.getLogger()
|
||||
|
||||
|
||||
def test_balance_simple_api(
|
||||
default_chain_spec,
|
||||
init_database,
|
||||
cic_registry,
|
||||
foo_token,
|
||||
register_lookups,
|
||||
register_tokens,
|
||||
api,
|
||||
celery_session_worker,
|
||||
@@ -22,7 +26,7 @@ def test_balance_simple_api(
|
||||
|
||||
chain_str = str(default_chain_spec)
|
||||
|
||||
a = to_checksum_address('0x' + os.urandom(20).hex())
|
||||
a = add_0x(to_checksum_address(os.urandom(20).hex()))
|
||||
t = api.balance(a, 'FOO', include_pending=False)
|
||||
r = t.get_leaf()
|
||||
assert t.successful()
|
||||
@@ -36,6 +40,7 @@ def test_balance_complex_api(
|
||||
init_database,
|
||||
cic_registry,
|
||||
foo_token,
|
||||
register_lookups,
|
||||
register_tokens,
|
||||
api,
|
||||
celery_session_worker,
|
||||
@@ -43,7 +48,7 @@ def test_balance_complex_api(
|
||||
|
||||
chain_str = str(default_chain_spec)
|
||||
|
||||
a = to_checksum_address('0x' + os.urandom(20).hex())
|
||||
a = add_0x(to_checksum_address(os.urandom(20).hex()))
|
||||
t = api.balance(a, 'FOO', include_pending=True)
|
||||
r = t.get_leaf()
|
||||
assert t.successful()
|
||||
|
||||
@@ -6,6 +6,7 @@ import pytest
|
||||
from chainlib.eth.nonce import RPCNonceOracle
|
||||
from eth_erc20 import ERC20
|
||||
from chainlib.eth.tx import receipt
|
||||
from hexathon import strip_0x
|
||||
|
||||
# local imports
|
||||
from cic_eth.api.api_task import Api
|
||||
@@ -23,7 +24,6 @@ from cic_eth.pytest.mock.filter import (
|
||||
logg = logging.getLogger()
|
||||
|
||||
|
||||
@pytest.mark.xfail()
|
||||
def test_list_tx(
|
||||
default_chain_spec,
|
||||
init_database,
|
||||
@@ -34,8 +34,10 @@ def test_list_tx(
|
||||
agent_roles,
|
||||
foo_token,
|
||||
register_tokens,
|
||||
register_lookups,
|
||||
init_eth_tester,
|
||||
celery_session_worker,
|
||||
init_celery_tasks,
|
||||
):
|
||||
|
||||
tx_hashes = []
|
||||
@@ -63,13 +65,16 @@ def test_list_tx(
|
||||
o = receipt(tx_hash_hex)
|
||||
r = eth_rpc.do(o)
|
||||
assert r['status'] == 1
|
||||
|
||||
a = r['block_number']
|
||||
block_filter.add(a.to_bytes(4, 'big'))
|
||||
ab = a.to_bytes(4, 'big')
|
||||
block_filter.add(ab)
|
||||
|
||||
a = r['block_number'] + r['transaction_index']
|
||||
tx_filter.add(a.to_bytes(4, 'big'))
|
||||
bb = r['transaction_index'].to_bytes(4, 'big')
|
||||
cb = ab + bb
|
||||
tx_filter.add(cb)
|
||||
|
||||
tx_hashes.append(tx_hash_hex)
|
||||
tx_hashes.append(strip_0x(tx_hash_hex))
|
||||
|
||||
# external tx two
|
||||
Nonce.next(agent_roles['ALICE'], 'foo', session=init_database)
|
||||
@@ -83,26 +88,29 @@ def test_list_tx(
|
||||
o = receipt(tx_hash_hex)
|
||||
r = eth_rpc.do(o)
|
||||
assert r['status'] == 1
|
||||
|
||||
a = r['block_number']
|
||||
block_filter.add(a.to_bytes(4, 'big'))
|
||||
ab = a.to_bytes(4, 'big')
|
||||
block_filter.add(ab)
|
||||
|
||||
a = r['block_number'] + r['transaction_index']
|
||||
tx_filter.add(a.to_bytes(4, 'big'))
|
||||
bb = r['transaction_index'].to_bytes(4, 'big')
|
||||
cb = ab + bb
|
||||
tx_filter.add(cb)
|
||||
|
||||
tx_hashes.append(tx_hash_hex)
|
||||
tx_hashes.append(strip_0x(tx_hash_hex))
|
||||
|
||||
init_eth_tester.mine_blocks(28)
|
||||
|
||||
# custodial tx 1
|
||||
api = Api(str(default_chain_spec), queue=None)
|
||||
t = api.transfer(agent_roles['ALICE'], agent_roles['CAROL'], 64, 'FOO') #, 'blinky')
|
||||
t = api.transfer(agent_roles['ALICE'], agent_roles['CAROL'], 64, 'FOO')
|
||||
r = t.get_leaf()
|
||||
assert t.successful()
|
||||
tx_hashes.append(r)
|
||||
|
||||
# custodial tx 2
|
||||
api = Api(str(default_chain_spec), queue=None)
|
||||
t = api.transfer(agent_roles['ALICE'], agent_roles['DAVE'], 16, 'FOO') #, 'blinky')
|
||||
t = api.transfer(agent_roles['ALICE'], agent_roles['DAVE'], 16, 'FOO')
|
||||
r = t.get_leaf()
|
||||
assert t.successful()
|
||||
tx_hashes.append(r)
|
||||
@@ -117,7 +125,8 @@ def test_list_tx(
|
||||
assert len(r) == 3
|
||||
logg.debug('rrrr {}'.format(r))
|
||||
|
||||
logg.debug('testing against hashes {}'.format(tx_hashes))
|
||||
for tx in r:
|
||||
logg.debug('have tx {}'.format(tx))
|
||||
tx_hashes.remove(tx['hash'])
|
||||
tx_hashes.remove(strip_0x(tx['hash']))
|
||||
assert len(tx_hashes) == 1
|
||||
|
||||
@@ -10,6 +10,7 @@ from chainlib.eth.tx import (
|
||||
)
|
||||
from eth_erc20 import ERC20
|
||||
from chainlib.eth.nonce import RPCNonceOracle
|
||||
from hexathon import add_0x
|
||||
|
||||
# local imports
|
||||
from cic_eth.db.models.nonce import (
|
||||
@@ -91,5 +92,5 @@ def test_filter_process(
|
||||
|
||||
assert len(r) == 2
|
||||
for tx_hash in r.keys():
|
||||
tx_hashes.remove(tx_hash)
|
||||
tx_hashes.remove(add_0x(tx_hash))
|
||||
assert len(tx_hashes) == 0
|
||||
|
||||
@@ -10,7 +10,7 @@ def test_default_token(
|
||||
):
|
||||
|
||||
s = celery.signature(
|
||||
'cic_eth.admin.token.default_token',
|
||||
'cic_eth.eth.erc20.default_token',
|
||||
[],
|
||||
queue=None,
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
crypto-dev-signer>=0.4.15a7,<=0.4.15
|
||||
crypto-dev-signer>=0.4.15rc2,<=0.4.15
|
||||
chainqueue>=0.0.5a1,<0.1.0
|
||||
cic-eth-registry>=0.6.1a2,<0.7.0
|
||||
cic-eth-registry>=0.6.1a5,<0.7.0
|
||||
redis==3.5.3
|
||||
hexathon~=0.0.1a8
|
||||
pycryptodome==3.10.1
|
||||
|
||||
@@ -101,7 +101,7 @@ def get_cached_available_balance(blockchain_address: str) -> float:
|
||||
:return: Operational balance of an account.
|
||||
:rtype: float
|
||||
"""
|
||||
identifier = bytes.fromhex(blockchain_address[2:])
|
||||
identifier = bytes.fromhex(blockchain_address)
|
||||
key = cache_data_key(identifier, salt=':cic.balances')
|
||||
cached_balances = get_cached_data(key=key)
|
||||
if cached_balances:
|
||||
|
||||
@@ -4,7 +4,6 @@ import logging
|
||||
from typing import Optional
|
||||
|
||||
# external imports
|
||||
from chainlib.hash import strip_0x
|
||||
from cic_types.models.person import Person
|
||||
|
||||
# local imports
|
||||
@@ -20,7 +19,7 @@ def get_cached_preferred_language(blockchain_address: str) -> Optional[str]:
|
||||
:return: Account's set preferred language | Fallback preferred language.
|
||||
:rtype: str
|
||||
"""
|
||||
identifier = bytes.fromhex(strip_0x(blockchain_address))
|
||||
identifier = bytes.fromhex(blockchain_address)
|
||||
preferences_metadata_handler = PreferencesMetadata(identifier)
|
||||
cached_preferences_metadata = preferences_metadata_handler.get_cached_metadata()
|
||||
if cached_preferences_metadata:
|
||||
|
||||
@@ -86,7 +86,7 @@ def query_statement(blockchain_address: str, limit: int = 9):
|
||||
:param limit: Number of transactions to be returned.
|
||||
:type limit: int
|
||||
"""
|
||||
logg.debug(f'retrieving balance for address: {blockchain_address}')
|
||||
logg.debug(f'retrieving statement for address: {blockchain_address}')
|
||||
chain_str = Chain.spec.__str__()
|
||||
cic_eth_api = Api(
|
||||
chain_str=chain_str,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import json
|
||||
|
||||
# external imports
|
||||
from chainlib.hash import strip_0x
|
||||
from cic_eth.api import Api
|
||||
|
||||
# local imports
|
||||
@@ -101,7 +100,7 @@ class Account(SessionBase):
|
||||
session.add(self)
|
||||
session.flush()
|
||||
SessionBase.release_session(session=session)
|
||||
return f'Pin reset successful.'
|
||||
return 'Pin reset successful.'
|
||||
|
||||
def standard_metadata_id(self) -> str:
|
||||
"""This function creates an account's standard metadata identification information that contains an account owner's
|
||||
@@ -109,7 +108,7 @@ class Account(SessionBase):
|
||||
:return: Standard metadata identification information | e164 formatted phone number.
|
||||
:rtype: str
|
||||
"""
|
||||
identifier = bytes.fromhex(strip_0x(self.blockchain_address))
|
||||
identifier = bytes.fromhex(self.blockchain_address)
|
||||
key = cache_data_key(identifier, ':cic.person')
|
||||
account_metadata = get_cached_data(key)
|
||||
if not account_metadata:
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# external imports
|
||||
|
||||
# local imports
|
||||
from .base import Metadata
|
||||
from .custom import CustomMetadata
|
||||
from .person import PersonMetadata
|
||||
from .phone import PhonePointerMetadata
|
||||
|
||||
@@ -1,99 +1,30 @@
|
||||
# standard imports
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from typing import Dict, Union
|
||||
|
||||
# third-part imports
|
||||
from cic_types.models.person import generate_metadata_pointer, Person
|
||||
# external imports
|
||||
from cic_types.condiments import MetadataPointer
|
||||
from cic_types.ext.metadata import MetadataRequestsHandler
|
||||
from cic_types.processor import generate_metadata_pointer
|
||||
|
||||
# local imports
|
||||
from cic_ussd.cache import cache_data, get_cached_data
|
||||
from cic_ussd.http.requests import error_handler, make_request
|
||||
from cic_ussd.metadata.signer import Signer
|
||||
|
||||
logg = logging.getLogger(__file__)
|
||||
|
||||
|
||||
class Metadata:
|
||||
"""
|
||||
:cvar base_url: The base url or the metadata server.
|
||||
:type base_url: str
|
||||
"""
|
||||
class UssdMetadataHandler(MetadataRequestsHandler):
|
||||
def __init__(self, cic_type: MetadataPointer, identifier: bytes):
|
||||
super().__init__(cic_type, identifier)
|
||||
|
||||
base_url = None
|
||||
|
||||
|
||||
class MetadataRequestsHandler(Metadata):
|
||||
|
||||
def __init__(self, cic_type: str, identifier: bytes, engine: str = 'pgp'):
|
||||
""""""
|
||||
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]):
|
||||
""""""
|
||||
data = json.dumps(data).encode('utf-8')
|
||||
result = make_request(method='POST', url=self.url, data=data, headers=self.headers)
|
||||
|
||||
error_handler(result=result)
|
||||
metadata = result.json()
|
||||
return self.edit(data=metadata)
|
||||
|
||||
def edit(self, data: Union[Dict, str]):
|
||||
""""""
|
||||
cic_meta_signer = Signer()
|
||||
signature = cic_meta_signer.sign_digest(data=data)
|
||||
algorithm = cic_meta_signer.get_operational_key().get('algo')
|
||||
formatted_data = {
|
||||
'm': json.dumps(data),
|
||||
's': {
|
||||
'engine': self.engine,
|
||||
'algo': algorithm,
|
||||
'data': signature,
|
||||
'digest': data.get('digest'),
|
||||
}
|
||||
}
|
||||
formatted_data = json.dumps(formatted_data)
|
||||
result = make_request(method='PUT', url=self.url, data=formatted_data, headers=self.headers)
|
||||
logg.info(f'signed metadata submission status: {result.status_code}.')
|
||||
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: {data}.')
|
||||
return result
|
||||
|
||||
def query(self):
|
||||
""""""
|
||||
result = make_request(method='GET', url=self.url)
|
||||
error_handler(result=result)
|
||||
result_data = result.json()
|
||||
if not isinstance(result_data, dict):
|
||||
raise ValueError(f'Invalid result data object: {result_data}.')
|
||||
if result.status_code == 200:
|
||||
if self.cic_type == ':cic.person':
|
||||
person = Person()
|
||||
person_data = person.deserialize(person_data=result_data)
|
||||
serialized_person_data = person_data.serialize()
|
||||
data = json.dumps(serialized_person_data)
|
||||
else:
|
||||
data = json.dumps(result_data)
|
||||
cache_data(key=self.metadata_pointer, data=data)
|
||||
logg.debug(f'caching: {data} with key: {self.metadata_pointer}')
|
||||
return result_data
|
||||
def cache_metadata(self, data: str):
|
||||
"""
|
||||
:param data:
|
||||
:type data:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
cache_data(self.metadata_pointer, data)
|
||||
logg.debug(f'caching: {data} with key: {self.metadata_pointer}')
|
||||
|
||||
def get_cached_metadata(self):
|
||||
""""""
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
# standard imports
|
||||
|
||||
# external imports
|
||||
from cic_types.condiments import MetadataPointer
|
||||
|
||||
# local imports
|
||||
from .base import MetadataRequestsHandler
|
||||
from .base import UssdMetadataHandler
|
||||
|
||||
|
||||
class CustomMetadata(MetadataRequestsHandler):
|
||||
class CustomMetadata(UssdMetadataHandler):
|
||||
|
||||
def __init__(self, identifier: bytes):
|
||||
super().__init__(cic_type=':cic.custom', identifier=identifier)
|
||||
super().__init__(cic_type=MetadataPointer.CUSTOM, identifier=identifier)
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
# standard imports
|
||||
|
||||
# external imports
|
||||
from cic_types.condiments import MetadataPointer
|
||||
|
||||
# local imports
|
||||
from .base import MetadataRequestsHandler
|
||||
from .base import UssdMetadataHandler
|
||||
|
||||
|
||||
class PersonMetadata(MetadataRequestsHandler):
|
||||
class PersonMetadata(UssdMetadataHandler):
|
||||
|
||||
def __init__(self, identifier: bytes):
|
||||
super().__init__(cic_type=':cic.person', identifier=identifier)
|
||||
super().__init__(cic_type=MetadataPointer.PERSON, identifier=identifier)
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
import logging
|
||||
|
||||
# external imports
|
||||
from cic_types.condiments import MetadataPointer
|
||||
|
||||
# local imports
|
||||
from .base import MetadataRequestsHandler
|
||||
from .base import UssdMetadataHandler
|
||||
|
||||
|
||||
class PhonePointerMetadata(MetadataRequestsHandler):
|
||||
class PhonePointerMetadata(UssdMetadataHandler):
|
||||
|
||||
def __init__(self, identifier: bytes):
|
||||
super().__init__(cic_type=':cic.phone', identifier=identifier)
|
||||
super().__init__(cic_type=MetadataPointer.PHONE, identifier=identifier)
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# standard imports
|
||||
|
||||
# external imports
|
||||
import celery
|
||||
from cic_types.condiments import MetadataPointer
|
||||
|
||||
# local imports
|
||||
from .base import MetadataRequestsHandler
|
||||
from .base import UssdMetadataHandler
|
||||
|
||||
|
||||
class PreferencesMetadata(MetadataRequestsHandler):
|
||||
class PreferencesMetadata(UssdMetadataHandler):
|
||||
|
||||
def __init__(self, identifier: bytes):
|
||||
super().__init__(cic_type=':cic.preferences', identifier=identifier)
|
||||
super().__init__(cic_type=MetadataPointer.PREFERENCES, identifier=identifier)
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
# standard imports
|
||||
import json
|
||||
import logging
|
||||
from typing import Optional
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
# third-party imports
|
||||
import gnupg
|
||||
|
||||
# local imports
|
||||
|
||||
logg = logging.getLogger()
|
||||
|
||||
|
||||
class Signer:
|
||||
"""
|
||||
:cvar gpg_path:
|
||||
:type gpg_path:
|
||||
:cvar gpg_passphrase:
|
||||
:type gpg_passphrase:
|
||||
:cvar key_file_path:
|
||||
:type key_file_path:
|
||||
|
||||
"""
|
||||
gpg_path: str = None
|
||||
gpg_passphrase: str = None
|
||||
key_file_path: str = None
|
||||
|
||||
def __init__(self):
|
||||
self.gpg = gnupg.GPG(gnupghome=self.gpg_path)
|
||||
|
||||
with open(self.key_file_path, 'r') as key_file:
|
||||
self.key_data = key_file.read()
|
||||
|
||||
def get_operational_key(self):
|
||||
"""
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
# import key data into keyring
|
||||
self.gpg.import_keys(key_data=self.key_data)
|
||||
gpg_keys = self.gpg.list_keys()
|
||||
key_algorithm = gpg_keys[0].get('algo')
|
||||
key_id = gpg_keys[0].get("keyid")
|
||||
logg.debug(f'using signing key: {key_id}, algorithm: {key_algorithm}')
|
||||
return gpg_keys[0]
|
||||
|
||||
def sign_digest(self, data: dict):
|
||||
"""
|
||||
:param data:
|
||||
:type data:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
digest = data['digest']
|
||||
key_id = self.get_operational_key().get('keyid')
|
||||
signature = self.gpg.sign(digest, passphrase=self.gpg_passphrase, keyid=key_id)
|
||||
return str(signature)
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ class MenuProcessor:
|
||||
def __init__(self, account: Account, display_key: str, menu_name: str, session: Session, ussd_session: dict):
|
||||
self.account = account
|
||||
self.display_key = display_key
|
||||
self.identifier = bytes.fromhex(self.account.blockchain_address[2:])
|
||||
self.identifier = bytes.fromhex(self.account.blockchain_address)
|
||||
self.menu_name = menu_name
|
||||
self.session = session
|
||||
self.ussd_session = ussd_session
|
||||
|
||||
@@ -5,7 +5,6 @@ from datetime import timedelta
|
||||
|
||||
# third-party imports
|
||||
import celery
|
||||
from chainlib.hash import strip_0x
|
||||
|
||||
# local imports
|
||||
from cic_ussd.account.balance import get_balances, calculate_available_balance
|
||||
@@ -55,6 +54,7 @@ def account_creation_callback(self, result: str, url: str, status_code: int):
|
||||
session.add(account)
|
||||
session.commit()
|
||||
session.close()
|
||||
logg.debug(f'recorded account with identifier: {result}')
|
||||
|
||||
queue = self.request.delivery_info.get('routing_key')
|
||||
s_phone_pointer = celery.signature(
|
||||
@@ -86,7 +86,7 @@ def balances_callback(result: list, param: str, status_code: int):
|
||||
raise ValueError(f'Unexpected status code: {status_code}.')
|
||||
|
||||
balances = result[0]
|
||||
identifier = bytes.fromhex(strip_0x(param))
|
||||
identifier = bytes.fromhex(param)
|
||||
key = cache_data_key(identifier, ':cic.balances')
|
||||
cache_data(key, json.dumps(balances))
|
||||
|
||||
@@ -113,8 +113,10 @@ def statement_callback(self, result, param: str, status_code: int):
|
||||
for transaction in statement_transactions:
|
||||
recipient_transaction, sender_transaction = transaction_actors(transaction)
|
||||
if recipient_transaction.get('blockchain_address') == param:
|
||||
recipient_transaction['alt_blockchain_address'] = sender_transaction.get('blockchain_address')
|
||||
generate(param, queue, recipient_transaction)
|
||||
if sender_transaction.get('blockchain_address') == param:
|
||||
sender_transaction['alt_blockchain_address'] = recipient_transaction.get('blockchain_address')
|
||||
generate(param, queue, sender_transaction)
|
||||
|
||||
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
# standard imports
|
||||
import json
|
||||
import logging
|
||||
|
||||
# third-party imports
|
||||
import celery
|
||||
from hexathon import strip_0x
|
||||
from cic_types.models.person import Person
|
||||
|
||||
# local imports
|
||||
from cic_ussd.metadata import CustomMetadata, PersonMetadata, PhonePointerMetadata, PreferencesMetadata
|
||||
from cic_ussd.tasks.base import CriticalMetadataTask
|
||||
|
||||
celery_app = celery.current_app
|
||||
logg = logging.getLogger().getChild(__name__)
|
||||
logg = logging.getLogger(__file__)
|
||||
|
||||
|
||||
@celery_app.task
|
||||
@@ -21,9 +22,15 @@ def query_person_metadata(blockchain_address: str):
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
identifier = bytes.fromhex(strip_0x(blockchain_address))
|
||||
identifier = bytes.fromhex(blockchain_address)
|
||||
person_metadata_client = PersonMetadata(identifier=identifier)
|
||||
person_metadata_client.query()
|
||||
response = person_metadata_client.query()
|
||||
data = response.json()
|
||||
person = Person()
|
||||
person_data = person.deserialize(person_data=data)
|
||||
serialized_person_data = person_data.serialize()
|
||||
data = json.dumps(serialized_person_data)
|
||||
person_metadata_client.cache_metadata(data=data)
|
||||
|
||||
|
||||
@celery_app.task
|
||||
@@ -36,14 +43,14 @@ def create_person_metadata(blockchain_address: str, data: dict):
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
identifier = bytes.fromhex(strip_0x(blockchain_address))
|
||||
identifier = bytes.fromhex(blockchain_address)
|
||||
person_metadata_client = PersonMetadata(identifier=identifier)
|
||||
person_metadata_client.create(data=data)
|
||||
|
||||
|
||||
@celery_app.task
|
||||
def edit_person_metadata(blockchain_address: str, data: dict):
|
||||
identifier = bytes.fromhex(strip_0x(blockchain_address))
|
||||
identifier = bytes.fromhex(blockchain_address)
|
||||
person_metadata_client = PersonMetadata(identifier=identifier)
|
||||
person_metadata_client.edit(data=data)
|
||||
|
||||
@@ -51,21 +58,21 @@ def edit_person_metadata(blockchain_address: str, data: dict):
|
||||
@celery_app.task(bind=True, base=CriticalMetadataTask)
|
||||
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 = blockchain_address
|
||||
phone_metadata_client = PhonePointerMetadata(identifier=identifier)
|
||||
phone_metadata_client.create(data=stripped_address)
|
||||
|
||||
|
||||
@celery_app.task()
|
||||
def add_custom_metadata(blockchain_address: str, data: dict):
|
||||
identifier = bytes.fromhex(strip_0x(blockchain_address))
|
||||
identifier = bytes.fromhex(blockchain_address)
|
||||
custom_metadata_client = CustomMetadata(identifier=identifier)
|
||||
custom_metadata_client.create(data=data)
|
||||
|
||||
|
||||
@celery_app.task()
|
||||
def add_preferences_metadata(blockchain_address: str, data: dict):
|
||||
identifier = bytes.fromhex(strip_0x(blockchain_address))
|
||||
identifier = bytes.fromhex(blockchain_address)
|
||||
preferences_metadata_client = PreferencesMetadata(identifier=identifier)
|
||||
preferences_metadata_client.create(data=data)
|
||||
|
||||
@@ -76,7 +83,10 @@ def query_preferences_metadata(blockchain_address: str):
|
||||
:param blockchain_address: Blockchain address of an account.
|
||||
:type blockchain_address: str | Ox-hex
|
||||
"""
|
||||
identifier = bytes.fromhex(strip_0x(blockchain_address))
|
||||
logg.debug(f'Retrieving preferences metadata for address: {blockchain_address}.')
|
||||
person_metadata_client = PreferencesMetadata(identifier=identifier)
|
||||
return person_metadata_client.query()
|
||||
identifier = bytes.fromhex(blockchain_address)
|
||||
logg.debug(f'retrieving preferences metadata for address: {blockchain_address}.')
|
||||
preferences_metadata_client = PreferencesMetadata(identifier=identifier)
|
||||
response = preferences_metadata_client.query()
|
||||
data = json.dumps(response.json())
|
||||
preferences_metadata_client.cache_metadata(data)
|
||||
return data
|
||||
|
||||
@@ -5,7 +5,6 @@ import logging
|
||||
# third-party imports
|
||||
import celery
|
||||
import i18n
|
||||
from chainlib.hash import strip_0x
|
||||
|
||||
# local imports
|
||||
from cic_ussd.account.metadata import get_cached_preferred_language
|
||||
@@ -24,17 +23,13 @@ logg = logging.getLogger(__file__)
|
||||
def generate_statement(self, querying_party: str, transaction: dict):
|
||||
""""""
|
||||
queue = self.request.delivery_info.get('routing_key')
|
||||
|
||||
s_preferences = celery.signature(
|
||||
'cic_ussd.tasks.metadata.query_preferences_metadata', [querying_party], queue=queue
|
||||
)
|
||||
s_parse_transaction = celery.signature(
|
||||
'cic_ussd.tasks.processor.parse_transaction', [transaction], queue=queue
|
||||
)
|
||||
s_cache_statement = celery.signature(
|
||||
'cic_ussd.tasks.processor.cache_statement', [querying_party], queue=queue
|
||||
)
|
||||
celery.chain(s_preferences, s_parse_transaction, s_cache_statement).apply_async()
|
||||
celery.chain(s_parse_transaction, s_cache_statement).apply_async()
|
||||
|
||||
|
||||
@celery_app.task
|
||||
@@ -53,7 +48,7 @@ def cache_statement(parsed_transaction: dict, querying_party: str):
|
||||
statement_transactions = json.loads(cached_statement)
|
||||
statement_transactions.append(parsed_transaction)
|
||||
data = json.dumps(statement_transactions)
|
||||
identifier = bytes.fromhex(strip_0x(querying_party))
|
||||
identifier = bytes.fromhex(querying_party)
|
||||
key = cache_data_key(identifier, ':cic.statement')
|
||||
cache_data(key, data)
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@ billiard==3.6.4.0
|
||||
bcrypt==3.2.0
|
||||
celery==4.4.7
|
||||
cffi==1.14.6
|
||||
cic-eth[services]~=0.12.4a7
|
||||
cic-eth[services]~=0.12.4a11
|
||||
cic-notify~=0.4.0a10
|
||||
cic-types~=0.1.0a15
|
||||
confini>=0.4.1a1,<0.5.0
|
||||
cic-types~=0.2.0a3
|
||||
confini>=0.3.6rc4,<0.5.0
|
||||
phonenumbers==8.12.12
|
||||
psycopg2==2.8.6
|
||||
python-i18n[YAML]==0.3.9
|
||||
|
||||
@@ -28,7 +28,6 @@ def test_filter_statement_transactions(transactions_list):
|
||||
|
||||
def test_generate(activated_account,
|
||||
cache_default_token_data,
|
||||
cache_statement,
|
||||
cache_preferences,
|
||||
celery_session_worker,
|
||||
init_cache,
|
||||
@@ -37,22 +36,22 @@ def test_generate(activated_account,
|
||||
preferences,
|
||||
preferences_metadata_url,
|
||||
transactions_list):
|
||||
with requests_mock.Mocker(real_http=False) as request_mocker:
|
||||
request_mocker.register_uri('GET', preferences_metadata_url, status_code=200, reason='OK', json=preferences)
|
||||
statement_transactions = filter_statement_transactions(transactions_list)
|
||||
for transaction in statement_transactions:
|
||||
querying_party = activated_account.blockchain_address
|
||||
recipient_transaction, sender_transaction = transaction_actors(transaction)
|
||||
if recipient_transaction.get('blockchain_address') == querying_party:
|
||||
generate(querying_party, None, recipient_transaction)
|
||||
if sender_transaction.get('blockchain_address') == querying_party:
|
||||
generate(querying_party, None, sender_transaction)
|
||||
time.sleep(2)
|
||||
identifier = bytes.fromhex(strip_0x(activated_account.blockchain_address))
|
||||
key = cache_data_key(identifier, ':cic.statement')
|
||||
statement = get_cached_data(key)
|
||||
statement = json.loads(statement)
|
||||
assert len(statement) == 1
|
||||
statement_transactions = filter_statement_transactions(transactions_list)
|
||||
for transaction in statement_transactions:
|
||||
querying_party = activated_account.blockchain_address
|
||||
recipient_transaction, sender_transaction = transaction_actors(transaction)
|
||||
if recipient_transaction.get('blockchain_address') == querying_party:
|
||||
recipient_transaction['alt_blockchain_address'] = sender_transaction.get('blockchain_address')
|
||||
generate(querying_party, None, recipient_transaction)
|
||||
if sender_transaction.get('blockchain_address') == querying_party:
|
||||
sender_transaction['alt_blockchain_address'] = recipient_transaction.get('blockchain_address')
|
||||
generate(querying_party, None, sender_transaction)
|
||||
time.sleep(2)
|
||||
identifier = bytes.fromhex(activated_account.blockchain_address)
|
||||
key = cache_data_key(identifier, ':cic.statement')
|
||||
statement = get_cached_data(key)
|
||||
statement = json.loads(statement)
|
||||
assert len(statement) == 1
|
||||
|
||||
|
||||
def test_get_cached_statement(activated_account, cache_statement, statement):
|
||||
|
||||
@@ -5,24 +5,25 @@ import os
|
||||
# external imports
|
||||
import requests_mock
|
||||
from chainlib.hash import strip_0x
|
||||
from cic_types.condiments import MetadataPointer
|
||||
from cic_types.processor import generate_metadata_pointer
|
||||
|
||||
# local imports
|
||||
from cic_ussd.metadata.base import MetadataRequestsHandler
|
||||
from cic_ussd.metadata.base import UssdMetadataHandler
|
||||
|
||||
|
||||
# external imports
|
||||
|
||||
|
||||
def test_metadata_requests_handler(activated_account,
|
||||
init_cache,
|
||||
load_config,
|
||||
person_metadata,
|
||||
setup_metadata_request_handler,
|
||||
setup_metadata_signer):
|
||||
def test_ussd_metadata_handler(activated_account,
|
||||
init_cache,
|
||||
load_config,
|
||||
person_metadata,
|
||||
setup_metadata_request_handler,
|
||||
setup_metadata_signer):
|
||||
identifier = bytes.fromhex(strip_0x(activated_account.blockchain_address))
|
||||
cic_type = ':cic.person'
|
||||
metadata_client = MetadataRequestsHandler(cic_type, identifier)
|
||||
cic_type = MetadataPointer.PERSON
|
||||
metadata_client = UssdMetadataHandler(cic_type, identifier)
|
||||
assert metadata_client.cic_type == cic_type
|
||||
assert metadata_client.engine == 'pgp'
|
||||
assert metadata_client.identifier == identifier
|
||||
@@ -38,7 +39,5 @@ def test_metadata_requests_handler(activated_account,
|
||||
assert result.status_code == 200
|
||||
person_metadata.pop('digest')
|
||||
request_mocker.register_uri('GET', metadata_client.url, status_code=200, reason='OK', json=person_metadata)
|
||||
result = metadata_client.query()
|
||||
result = metadata_client.query().json()
|
||||
assert result == person_metadata
|
||||
cached_metadata = metadata_client.get_cached_metadata()
|
||||
assert json.loads(cached_metadata) == person_metadata
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# standard imports
|
||||
import os
|
||||
# external imports
|
||||
from chainlib.hash import strip_0x
|
||||
from cic_types.condiments import MetadataPointer
|
||||
from cic_types.processor import generate_metadata_pointer
|
||||
|
||||
# local imports
|
||||
@@ -11,8 +11,8 @@ from cic_ussd.metadata import CustomMetadata
|
||||
|
||||
|
||||
def test_custom_metadata(activated_account, load_config, setup_metadata_request_handler, setup_metadata_signer):
|
||||
cic_type = ':cic.custom'
|
||||
identifier = bytes.fromhex(strip_0x(activated_account.blockchain_address))
|
||||
cic_type = MetadataPointer.CUSTOM
|
||||
identifier = bytes.fromhex(activated_account.blockchain_address)
|
||||
custom_metadata_client = CustomMetadata(identifier)
|
||||
assert custom_metadata_client.cic_type == cic_type
|
||||
assert custom_metadata_client.engine == 'pgp'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# standard imports
|
||||
import os
|
||||
# external imports
|
||||
from chainlib.hash import strip_0x
|
||||
from cic_types.condiments import MetadataPointer
|
||||
from cic_types.processor import generate_metadata_pointer
|
||||
|
||||
# local imports
|
||||
@@ -11,8 +11,8 @@ from cic_ussd.metadata import PersonMetadata
|
||||
|
||||
|
||||
def test_person_metadata(activated_account, load_config, setup_metadata_request_handler, setup_metadata_signer):
|
||||
cic_type = ':cic.person'
|
||||
identifier = bytes.fromhex(strip_0x(activated_account.blockchain_address))
|
||||
cic_type = MetadataPointer.PERSON
|
||||
identifier = bytes.fromhex(activated_account.blockchain_address)
|
||||
person_metadata_client = PersonMetadata(identifier)
|
||||
assert person_metadata_client.cic_type == cic_type
|
||||
assert person_metadata_client.engine == 'pgp'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# standard imports
|
||||
import os
|
||||
# external imports
|
||||
from chainlib.hash import strip_0x
|
||||
from cic_types.condiments import MetadataPointer
|
||||
from cic_types.processor import generate_metadata_pointer
|
||||
|
||||
# local imports
|
||||
@@ -12,8 +12,8 @@ from cic_ussd.metadata import PhonePointerMetadata
|
||||
|
||||
|
||||
def test_phone_pointer_metadata(activated_account, load_config, setup_metadata_request_handler, setup_metadata_signer):
|
||||
cic_type = ':cic.phone'
|
||||
identifier = bytes.fromhex(strip_0x(activated_account.blockchain_address))
|
||||
cic_type = MetadataPointer.PHONE
|
||||
identifier = bytes.fromhex(activated_account.blockchain_address)
|
||||
phone_pointer_metadata = PhonePointerMetadata(identifier)
|
||||
assert phone_pointer_metadata.cic_type == cic_type
|
||||
assert phone_pointer_metadata.engine == 'pgp'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# standard imports
|
||||
import os
|
||||
# external imports
|
||||
from chainlib.hash import strip_0x
|
||||
from cic_types.condiments import MetadataPointer
|
||||
from cic_types.processor import generate_metadata_pointer
|
||||
|
||||
# local imports
|
||||
@@ -11,8 +11,8 @@ from cic_ussd.metadata import PreferencesMetadata
|
||||
|
||||
|
||||
def test_preferences_metadata(activated_account, load_config, setup_metadata_request_handler, setup_metadata_signer):
|
||||
cic_type = ':cic.preferences'
|
||||
identifier = bytes.fromhex(strip_0x(activated_account.blockchain_address))
|
||||
cic_type = MetadataPointer.PREFERENCES
|
||||
identifier = bytes.fromhex(activated_account.blockchain_address)
|
||||
preferences_metadata_client = PreferencesMetadata(identifier)
|
||||
assert preferences_metadata_client.cic_type == cic_type
|
||||
assert preferences_metadata_client.engine == 'pgp'
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
# standard imports
|
||||
import shutil
|
||||
|
||||
# third-party imports
|
||||
|
||||
# local imports
|
||||
from cic_ussd.metadata.signer import Signer
|
||||
|
||||
|
||||
def test_client(load_config, setup_metadata_signer, person_metadata):
|
||||
signer = Signer()
|
||||
gpg = signer.gpg
|
||||
assert signer.key_data is not None
|
||||
gpg.import_keys(key_data=signer.key_data)
|
||||
gpg_keys = gpg.list_keys()
|
||||
assert signer.get_operational_key() == gpg_keys[0]
|
||||
shutil.rmtree(Signer.gpg_path)
|
||||
@@ -57,7 +57,7 @@ def test_menu_processor(activated_account,
|
||||
available_balance=available_balance,
|
||||
token_symbol=token_symbol)
|
||||
|
||||
identifier = bytes.fromhex(strip_0x(activated_account.blockchain_address))
|
||||
identifier = bytes.fromhex(activated_account.blockchain_address)
|
||||
key = cache_data_key(identifier, ':cic.adjusted_balance')
|
||||
adjusted_balance = 45931650.64654012
|
||||
cache_data(key, json.dumps(adjusted_balance))
|
||||
@@ -108,7 +108,7 @@ def test_menu_processor(activated_account,
|
||||
display_key = 'ussd.kenya.display_user_metadata'
|
||||
ussd_menu = UssdMenu.find_by_name('display_user_metadata')
|
||||
name = ussd_menu.get('name')
|
||||
identifier = bytes.fromhex(strip_0x(activated_account.blockchain_address))
|
||||
identifier = bytes.fromhex(activated_account.blockchain_address)
|
||||
person_metadata = PersonMetadata(identifier)
|
||||
cached_person_metadata = person_metadata.get_cached_metadata()
|
||||
resp = response(activated_account, display_key, name, init_database, generic_ussd_session)
|
||||
|
||||
@@ -114,6 +114,7 @@ def test_statement_callback(activated_account, mocker, transactions_list):
|
||||
s_statement_callback.apply_async().get()
|
||||
statement_transactions = filter_statement_transactions(transactions_list)
|
||||
recipient_transaction, sender_transaction = transaction_actors(statement_transactions[0])
|
||||
sender_transaction['alt_blockchain_address'] = recipient_transaction.get('blockchain_address')
|
||||
mock_statement_generate.assert_called_with(
|
||||
(activated_account.blockchain_address, sender_transaction), {}, queue='cic-ussd')
|
||||
|
||||
|
||||
12
apps/cic-ussd/tests/fixtures/account.py
vendored
12
apps/cic-ussd/tests/fixtures/account.py
vendored
@@ -54,7 +54,7 @@ def cache_account_creation_data(init_cache, account_creation_data):
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def cache_balances(activated_account, balances, init_cache):
|
||||
identifier = bytes.fromhex(strip_0x(activated_account.blockchain_address))
|
||||
identifier = bytes.fromhex(activated_account.blockchain_address)
|
||||
balances = json.dumps(balances[0])
|
||||
key = cache_data_key(identifier, ':cic.balances')
|
||||
cache_data(key, balances)
|
||||
@@ -70,7 +70,7 @@ def cache_default_token_data(default_token_data, init_cache, load_chain_spec):
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def cache_person_metadata(activated_account, init_cache, person_metadata):
|
||||
identifier = bytes.fromhex(strip_0x(activated_account.blockchain_address))
|
||||
identifier = bytes.fromhex(activated_account.blockchain_address)
|
||||
person = json.dumps(person_metadata)
|
||||
key = cache_data_key(identifier, ':cic.person')
|
||||
cache_data(key, person)
|
||||
@@ -78,7 +78,7 @@ def cache_person_metadata(activated_account, init_cache, person_metadata):
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def cache_preferences(activated_account, init_cache, preferences):
|
||||
identifier = bytes.fromhex(strip_0x(activated_account.blockchain_address))
|
||||
identifier = bytes.fromhex(activated_account.blockchain_address)
|
||||
preferences = json.dumps(preferences)
|
||||
key = cache_data_key(identifier, ':cic.preferences')
|
||||
cache_data(key, preferences)
|
||||
@@ -86,10 +86,10 @@ def cache_preferences(activated_account, init_cache, preferences):
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def cache_statement(activated_account, init_cache, statement):
|
||||
identifier = bytes.fromhex(strip_0x(activated_account.blockchain_address))
|
||||
preferences = json.dumps(statement)
|
||||
identifier = bytes.fromhex(activated_account.blockchain_address)
|
||||
statement = json.dumps(statement)
|
||||
key = cache_data_key(identifier, ':cic.statement')
|
||||
cache_data(key, preferences)
|
||||
cache_data(key, statement)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
|
||||
20
apps/cic-ussd/tests/fixtures/metadata.py
vendored
20
apps/cic-ussd/tests/fixtures/metadata.py
vendored
@@ -6,33 +6,19 @@ import tempfile
|
||||
# external imports
|
||||
import pytest
|
||||
from chainlib.hash import strip_0x
|
||||
from cic_types.condiments import MetadataPointer
|
||||
from cic_types.processor import generate_metadata_pointer
|
||||
|
||||
# local imports
|
||||
from cic_ussd.metadata import Metadata, PersonMetadata, PhonePointerMetadata, PreferencesMetadata
|
||||
from cic_ussd.metadata.signer import Signer
|
||||
from cic_ussd.metadata import PersonMetadata, PhonePointerMetadata, PreferencesMetadata
|
||||
|
||||
logg = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def setup_metadata_signer(load_config):
|
||||
temp_dir = tempfile.mkdtemp(dir='/tmp')
|
||||
logg.debug(f'Created temp dir: {temp_dir}')
|
||||
Signer.gpg_path = temp_dir
|
||||
Signer.gpg_passphrase = load_config.get('PGP_PASSPHRASE')
|
||||
Signer.key_file_path = os.path.join(load_config.get('PGP_KEYS_PATH'), load_config.get('PGP_PRIVATE_KEYS'))
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def setup_metadata_request_handler(load_config):
|
||||
Metadata.base_url = load_config.get('CIC_META_URL')
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def account_phone_pointer(activated_account):
|
||||
identifier = bytes.fromhex(strip_0x(activated_account.blockchain_address))
|
||||
return generate_metadata_pointer(identifier, ':cic.phone')
|
||||
return generate_metadata_pointer(identifier, MetadataPointer.PERSON)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
|
||||
14
apps/cic-ussd/tests/fixtures/transaction.py
vendored
14
apps/cic-ussd/tests/fixtures/transaction.py
vendored
@@ -7,6 +7,7 @@ import pytest
|
||||
# local import
|
||||
from cic_ussd.account.balance import get_cached_available_balance
|
||||
|
||||
|
||||
# tests imports
|
||||
|
||||
|
||||
@@ -103,8 +104,8 @@ def transactions_list(activated_account, valid_recipient):
|
||||
'destination_token': '0x0000000000000000000000000000000000000000',
|
||||
'block_number': 80,
|
||||
'tx_index': 0,
|
||||
'sender': '0x367cB0F65137b0A845c1DB4B7Ca47D3DEF32dDe8',
|
||||
'recipient': '0x103d1ed6e370dBa6267045c70d4999384c18a04A',
|
||||
'sender': '367cB0F65137b0A845c1DB4B7Ca47D3DEF32dDe8',
|
||||
'recipient': '103d1ed6e370dBa6267045c70d4999384c18a04A',
|
||||
'from_value': 0,
|
||||
'to_value': 0,
|
||||
'date_created': '2021-07-14T14:13:46.036198',
|
||||
@@ -122,8 +123,8 @@ def transactions_list(activated_account, valid_recipient):
|
||||
'destination_token': '0x0000000000000000000000000000000000000000',
|
||||
'block_number': 78,
|
||||
'tx_index': 0,
|
||||
'sender': '0xb41BfEE260693A473254D62b81aE1ADCC9E51AFb',
|
||||
'recipient': '0x367cB0F65137b0A845c1DB4B7Ca47D3DEF32dDe8',
|
||||
'sender': 'b41BfEE260693A473254D62b81aE1ADCC9E51AFb',
|
||||
'recipient': '367cB0F65137b0A845c1DB4B7Ca47D3DEF32dDe8',
|
||||
'from_value': 1800000000000000,
|
||||
'to_value': 1800000000000000,
|
||||
'date_created': '2021-07-14T14:13:35.839638',
|
||||
@@ -142,8 +143,8 @@ def transactions_list(activated_account, valid_recipient):
|
||||
'destination_token': '0x0000000000000000000000000000000000000000',
|
||||
'block_number': 79,
|
||||
'tx_index': 0,
|
||||
'sender': '0x367cB0F65137b0A845c1DB4B7Ca47D3DEF32dDe8',
|
||||
'recipient': '0x103d1ed6e370dBa6267045c70d4999384c18a04A',
|
||||
'sender': '367cB0F65137b0A845c1DB4B7Ca47D3DEF32dDe8',
|
||||
'recipient': '103d1ed6e370dBa6267045c70d4999384c18a04A',
|
||||
'from_value': 0,
|
||||
'to_value': 0,
|
||||
'date_created': '2021-07-14T14:13:35.638355',
|
||||
@@ -152,4 +153,3 @@ def transactions_list(activated_account, valid_recipient):
|
||||
'timestamp': 1626272015,
|
||||
'hash': '0x32ca3dd3bef06463b452f4d32f5f563d083cb4759219eed90f3d2a9c1791c5fc'}
|
||||
]
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import random
|
||||
import uuid
|
||||
|
||||
# external imports
|
||||
from chainlib.eth.address import to_checksum_address
|
||||
from faker import Faker
|
||||
from faker_e164.providers import E164Provider
|
||||
|
||||
@@ -21,7 +20,7 @@ def phone_number() -> str:
|
||||
|
||||
|
||||
def blockchain_address() -> str:
|
||||
return to_checksum_address('0x' + os.urandom(20).hex())
|
||||
return os.urandom(20).hex().lower()
|
||||
|
||||
|
||||
def session_id() -> str:
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
cic-eth[tools]==0.12.4a8
|
||||
chainlib-eth>=0.0.9a14,<0.1.0
|
||||
cic-eth[tools]==0.12.4a11
|
||||
chainlib-eth>=0.0.9rc4,<0.1.0
|
||||
chainlib==0.0.9rc1,<0.1.0
|
||||
eth-erc20>=0.1.2a3,<0.2.0
|
||||
erc20-demurrage-token>=0.0.5a2,<0.1.0
|
||||
eth-accounts-index>=0.1.2a2,<0.2.0
|
||||
eth-address-index>=0.2.3a4,<0.3.0
|
||||
cic-eth-registry>=0.6.1a2,<0.7.0
|
||||
#eth-accounts-index>=0.1.2a2,<0.2.0
|
||||
eth-address-index>=0.2.4a1,<0.3.0
|
||||
cic-eth-registry>=0.6.1a5,<0.7.0
|
||||
erc20-transfer-authorization>=0.3.5a2,<0.4.0
|
||||
erc20-faucet>=0.3.2a2,<0.4.0
|
||||
sarafu-faucet>=0.0.7a2,<0.1.0
|
||||
confini>=0.4.2rc3,<1.0.0
|
||||
crypto-dev-signer>=0.4.15a7,<=0.4.15
|
||||
crypto-dev-signer>=0.4.15rc2,<=0.4.15
|
||||
eth-token-index>=0.2.4a1,<=0.3.0
|
||||
okota>=0.2.4a5,<0.3.0
|
||||
|
||||
@@ -65,22 +65,25 @@ fi
|
||||
echo "giftable-token-gift $fee_price_arg -p $RPC_PROVIDER -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -vv -w -e $DEV_RESERVE_ADDRESS $DEV_RESERVE_AMOUNT"
|
||||
giftable-token-gift $fee_price_arg -p $RPC_PROVIDER -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -u -vv -s -w -e $DEV_RESERVE_ADDRESS $DEV_RESERVE_AMOUNT
|
||||
|
||||
>&2 echo "deploy account index contract"
|
||||
DEV_ACCOUNT_INDEX_ADDRESS=`eth-accounts-index-deploy $fee_price_arg -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -y $WALLET_KEY_FILE -vv -s -u -w`
|
||||
>&2 echo "add deployer address as account index writer"
|
||||
eth-accounts-index-writer $fee_price_arg -s -u -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -e $DEV_ACCOUNT_INDEX_ADDRESS -ww -vv $debug $DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER
|
||||
|
||||
>&2 echo "deploy contract registry contract"
|
||||
CIC_REGISTRY_ADDRESS=`eth-contract-registry-deploy $fee_price_arg -i $CIC_CHAIN_SPEC -y $WALLET_KEY_FILE --identifier AccountRegistry --identifier TokenRegistry --identifier AddressDeclarator --identifier Faucet --identifier TransferAuthorization --identifier ContractRegistry -p $RPC_PROVIDER -vv -s -u -w`
|
||||
eth-contract-registry-set $fee_price_arg -s -u -w -y $WALLET_KEY_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -vv --identifier ContractRegistry $CIC_REGISTRY_ADDRESS
|
||||
eth-contract-registry-set $fee_price_arg -s -u -w -y $WALLET_KEY_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -vv --identifier AccountRegistry $DEV_ACCOUNT_INDEX_ADDRESS
|
||||
|
||||
# Deploy address declarator registry
|
||||
>&2 echo "deploy address declarator contract"
|
||||
declarator_description=0x546869732069732074686520434943206e6574776f726b000000000000000000
|
||||
DEV_DECLARATOR_ADDRESS=`eth-address-declarator-deploy -s -u -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -w -vv $declarator_description`
|
||||
|
||||
>&2 echo "deploy contract registry contract"
|
||||
#CIC_REGISTRY_ADDRESS=`eth-contract-registry-deploy $fee_price_arg -i $CIC_CHAIN_SPEC -y $WALLET_KEY_FILE --identifier AccountRegistry --identifier TokenRegistry --identifier AddressDeclarator --identifier Faucet --identifier TransferAuthorization --identifier ContractRegistry -p $RPC_PROVIDER -vv -s -u -w`
|
||||
CIC_REGISTRY_ADDRESS=`okota-contract-registry-deploy $fee_price_arg -i $CIC_CHAIN_SPEC -y $WALLET_KEY_FILE --identifier AccountRegistry --identifier TokenRegistry --identifier AddressDeclarator --identifier Faucet --identifier TransferAuthorization --identifier ContractRegistry --address-declarator $DEV_DECLARATOR_ADDRESS -p $RPC_PROVIDER -vv -s -u -w`
|
||||
eth-contract-registry-set $fee_price_arg -s -u -w -y $WALLET_KEY_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -vv --identifier ContractRegistry $CIC_REGISTRY_ADDRESS
|
||||
|
||||
eth-contract-registry-set $fee_price_arg -s -u -w -y $WALLET_KEY_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -vv --identifier AddressDeclarator $DEV_DECLARATOR_ADDRESS
|
||||
|
||||
>&2 echo "deploy account index contract"
|
||||
#DEV_ACCOUNT_INDEX_ADDRESS=`eth-accounts-index-deploy $fee_price_arg -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -y $WALLET_KEY_FILE -vv -s -u -w`
|
||||
DEV_ACCOUNT_INDEX_ADDRESS=`okota-accounts-index-deploy $fee_price_arg -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -y $WALLET_KEY_FILE -vv -s -u -w --address-declarator $DEV_DECLARATOR_ADDRESS --token-address $DEV_RESERVE_ADDRESS`
|
||||
#>&2 echo "add deployer address as account index writer"
|
||||
#eth-accounts-index-writer $fee_price_arg -s -u -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -e $DEV_ACCOUNT_INDEX_ADDRESS -ww -vv $debug $DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER
|
||||
eth-contract-registry-set $fee_price_arg -s -u -w -y $WALLET_KEY_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -vv --identifier AccountRegistry $DEV_ACCOUNT_INDEX_ADDRESS
|
||||
|
||||
# Deploy transfer authorization contact
|
||||
>&2 echo "deploy transfer auth contract"
|
||||
DEV_TRANSFER_AUTHORIZATION_ADDRESS=`erc20-transfer-auth-deploy $gas_price_arg -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -w -vv`
|
||||
@@ -88,7 +91,8 @@ eth-contract-registry-set $fee_price_arg -s -u -w -y $WALLET_KEY_FILE -e $CIC_RE
|
||||
|
||||
# Deploy token index contract
|
||||
>&2 echo "deploy token index contract"
|
||||
DEV_TOKEN_INDEX_ADDRESS=`eth-token-index-deploy -s -u $fee_price_arg -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -w -vv`
|
||||
#DEV_TOKEN_INDEX_ADDRESS=`eth-token-index-deploy -s -u $fee_price_arg -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -w -vv`
|
||||
DEV_TOKEN_INDEX_ADDRESS=`okota-token-index-deploy -s -u $fee_price_arg -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -w -vv --address-declarator $DEV_DECLARATOR_ADDRESS`
|
||||
eth-contract-registry-set $fee_price_arg -s -u -w -y $WALLET_KEY_FILE -e $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -vv --identifier TokenRegistry $DEV_TOKEN_INDEX_ADDRESS
|
||||
>&2 echo "add reserve token to token index"
|
||||
eth-token-index-add $fee_price_arg -s -u -w -y $WALLET_KEY_FILE -i $CIC_CHAIN_SPEC -p $RPC_PROVIDER -vv -e $DEV_TOKEN_INDEX_ADDRESS $DEV_RESERVE_ADDRESS
|
||||
|
||||
@@ -46,7 +46,7 @@ cic-eth-tag -i $CHAIN_SPEC TRANSFER_AUTHORIZATION_OWNER $DEV_ETH_ACCOUNT_TRANSFE
|
||||
DEV_ETH_ACCOUNT_ACCOUNT_REGISTRY_WRITER=`CONFINI_DIR=$empty_config_dir cic-eth-create $debug --redis-host $REDIS_HOST --redis-host-callback=$REDIS_HOST --redis-port-callback=$REDIS_PORT --no-register`
|
||||
cic-eth-tag -i $CHAIN_SPEC ACCOUNT_REGISTRY_WRITER $DEV_ETH_ACCOUNT_ACCOUNT_REGISTRY_WRITER
|
||||
>&2 echo "add acccounts index writer account as writer on contract"
|
||||
eth-accounts-index-writer -s -u -y $WALLET_KEY_FILE -i $CHAIN_SPEC -p $RPC_PROVIDER -e $account_index_address -ww $debug $DEV_ETH_ACCOUNT_ACCOUNT_REGISTRY_WRITER
|
||||
#eth-accounts-index-writer -s -u -y $WALLET_KEY_FILE -i $CHAIN_SPEC -p $RPC_PROVIDER -e $account_index_address -ww $debug $DEV_ETH_ACCOUNT_ACCOUNT_REGISTRY_WRITER
|
||||
|
||||
# Transfer gas to custodial gas provider adddress
|
||||
_CONFINI_DIR=$CONFINI_DIR
|
||||
@@ -78,9 +78,9 @@ export DEV_ETH_SARAFU_TOKEN_ADDRESS=$DEV_ETH_RESERVE_ADDRESS
|
||||
>&2 erc20-transfer -s -u -y $WALLET_KEY_FILE -i $CHAIN_SPEC -p $RPC_PROVIDER --fee-limit 100000 -e $reserve_address -w $debug -a $DEV_ETH_ACCOUNT_SARAFU_GIFTER ${DEV_TOKEN_AMOUNT:0:-1}
|
||||
|
||||
# Remove the SEND (8), QUEUE (16) and INIT (2) locks (or'ed), set by default at migration
|
||||
cic-eth-ctl -i $CHAIN_SPEC unlock INIT
|
||||
cic-eth-ctl -i $CHAIN_SPEC unlock SEND
|
||||
cic-eth-ctl -i $CHAIN_SPEC unlock QUEUE
|
||||
cic-eth-ctl -vv -i $CHAIN_SPEC unlock INIT
|
||||
cic-eth-ctl -vv -i $CHAIN_SPEC unlock SEND
|
||||
cic-eth-ctl -vv -i $CHAIN_SPEC unlock QUEUE
|
||||
|
||||
#confini-dump --schema-module chainlib.eth.data.config --schema-module cic_eth.data.config --schema-dir ./config
|
||||
|
||||
|
||||
@@ -6,4 +6,7 @@ set -e
|
||||
TAG=${TAG?Variable not set} \
|
||||
docker-compose \
|
||||
-f docker-compose.yml \
|
||||
build
|
||||
build \
|
||||
--no-cache \
|
||||
--parallel \
|
||||
--progress plain
|
||||
|
||||
Reference in New Issue
Block a user