Compare commits

..

27 Commits

Author SHA1 Message Date
nolash
ed016ca35c Bump ussd cic-eth requirement 2021-04-24 10:38:41 +02:00
nolash
355840f316 Bump version 2021-04-24 10:36:52 +02:00
nolash
0319e0672e Merge remote-tracking branch 'origin/master' into lash/default-token 2021-04-24 08:18:49 +02:00
Louis Holbrook
cd0e702e3a Merge branch 'lash/custom-meta' into 'master'
Add custom meta tags

See merge request grassrootseconomics/cic-internal-integration!114
2021-04-24 06:14:25 +00:00
Louis Holbrook
cfab16f4a9 Add custom meta tags 2021-04-24 06:14:24 +00:00
nolash
3ed263a879 Add test for default token task 2021-04-23 23:31:41 +02:00
nolash
5d96ed5e24 Remove eth health modules config entries 2021-04-23 23:07:04 +02:00
nolash
489796abd8 Merge remote-tracking branch 'origin/master' into lash/default-token 2021-04-23 23:05:32 +02:00
Louis Holbrook
60fdb06034 Merge branch 'lash/emergency-shutdown' into 'master'
cic-eth: Add sanity checks for emergency shutdown / liveness tests

See merge request grassrootseconomics/cic-internal-integration!110
2021-04-23 21:02:52 +00:00
Louis Holbrook
3129a78e06 cic-eth: Add sanity checks for emergency shutdown / liveness tests 2021-04-23 21:02:51 +00:00
nolash
626b1c9a03 Add omitted files 2021-04-23 22:51:51 +02:00
nolash
41a3b2e060 Add default token setting to cic-eth with api 2021-04-23 11:22:12 +02:00
Louis Holbrook
6b6ec8659b Merge branch 'lash/simpler-token-selector' into 'master'
Simplify token selector

See merge request grassrootseconomics/cic-internal-integration!112
2021-04-23 08:17:59 +00:00
nolash
96e755b54d Simplify token selector 2021-04-22 11:58:39 +02:00
nolash
f38458ff4c Merge branch 'master' of gitlab.com:grassrootseconomics/cic-internal-integration 2021-04-22 11:57:15 +02:00
Louis Holbrook
660d524401 Merge branch 'lash/health-util' into 'master'
K8s health utilities for cic containers

See merge request grassrootseconomics/cic-internal-integration!108
2021-04-21 17:34:13 +00:00
Louis Holbrook
1bc7cde1f0 K8s health utilities for cic containers 2021-04-21 17:34:13 +00:00
Louis Holbrook
9c22ffca38 Merge branch 'lash/ussd-final-steps' into 'master'
USSD final steps

See merge request grassrootseconomics/cic-internal-integration!111
2021-04-21 17:25:57 +00:00
Louis Holbrook
39fe4a14ec USSD final steps 2021-04-21 17:25:57 +00:00
nolash
65250196cc cic-eth versionbump 2021-04-21 19:03:14 +02:00
Louis Holbrook
0123ce13ea Merge branch 'lash/settable-gas-price' into 'master'
Adapt deployment to Bloxberg

See merge request grassrootseconomics/cic-internal-integration!99
2021-04-21 05:46:42 +00:00
Louis Holbrook
03b3e8cd3f Adapt deployment to Bloxberg 2021-04-21 05:46:42 +00:00
Louis Holbrook
3ee84f780e Merge branch 'lash/cic-cache-syncer-backend-mixup' into 'master'
CIC-cache backend syncer mixup

See merge request grassrootseconomics/cic-internal-integration!106
2021-04-20 13:25:03 +00:00
Louis Holbrook
95269f69ed CIC-cache backend syncer mixup 2021-04-20 13:25:02 +00:00
621780e9b6 Update .cic-template.yml 2021-04-19 17:56:19 +00:00
eecdca1a55 Merge branch 'philip/ussd-db-fixes' into 'master'
Philip/ussd db fixes

See merge request grassrootseconomics/cic-internal-integration!107
2021-04-19 08:44:41 +00:00
6fef0ecec9 Philip/ussd db fixes 2021-04-19 08:44:40 +00:00
56 changed files with 1266 additions and 247 deletions

6
.gitignore vendored
View File

@@ -1,6 +1,10 @@
service-configs/* service-configs/*
!service-configs/.gitkeep !service-configs/.gitkeep
node_modules **/node_modules/
__pycache__ __pycache__
*.pyc *.pyc
*.o *.o
gmon.out
*.egg-info
dist/
build/

View File

@@ -67,6 +67,7 @@ class ERC20TransferFilter(SyncFilter):
tx.status == Status.SUCCESS, tx.status == Status.SUCCESS,
block.timestamp, block.timestamp,
) )
db_session.flush() #db_session.flush()
db_session.commit()
return True return True

View File

@@ -77,7 +77,7 @@ def main():
if len(syncer_backends) == 0: if len(syncer_backends) == 0:
logg.info('found no backends to resume') logg.info('found no backends to resume')
syncers.append(SQLBackend.initial(chain_spec, block_offset)) syncer_backends.append(SQLBackend.initial(chain_spec, block_offset))
else: else:
for syncer_backend in syncer_backends: for syncer_backend in syncer_backends:
logg.info('resuming sync session {}'.format(syncer_backend)) logg.info('resuming sync session {}'.format(syncer_backend))

View File

@@ -2,4 +2,9 @@
. ./db.sh . ./db.sh
if [ $? -ne "0" ]; then
>&2 echo db migrate fail
exit 1
fi
/usr/local/bin/cic-cache-trackerd $@ /usr/local/bin/cic-cache-trackerd $@

View File

@@ -32,7 +32,9 @@ def lock(chained_input, chain_spec_dict, address=ZERO_ADDRESS, flags=LockEnum.AL
:returns: New lock state for address :returns: New lock state for address
:rtype: number :rtype: number
""" """
chain_str = str(ChainSpec.from_dict(chain_spec_dict)) chain_str = '::'
if chain_spec_dict != None:
chain_str = str(ChainSpec.from_dict(chain_spec_dict))
r = Lock.set(chain_str, flags, address=address, tx_hash=tx_hash) r = Lock.set(chain_str, flags, address=address, tx_hash=tx_hash)
logg.debug('Locked {} for {}, flag now {}'.format(flags, address, r)) logg.debug('Locked {} for {}, flag now {}'.format(flags, address, r))
return chained_input return chained_input
@@ -51,7 +53,9 @@ def unlock(chained_input, chain_spec_dict, address=ZERO_ADDRESS, flags=LockEnum.
:returns: New lock state for address :returns: New lock state for address
:rtype: number :rtype: number
""" """
chain_str = str(ChainSpec.from_dict(chain_spec_dict)) chain_str = '::'
if chain_spec_dict != None:
chain_str = str(ChainSpec.from_dict(chain_spec_dict))
r = Lock.reset(chain_str, flags, address=address) r = Lock.reset(chain_str, flags, address=address)
logg.debug('Unlocked {} for {}, flag now {}'.format(flags, address, r)) logg.debug('Unlocked {} for {}, flag now {}'.format(flags, address, r))
return chained_input return chained_input
@@ -127,7 +131,9 @@ def unlock_queue(chained_input, chain_spec_dict, address=ZERO_ADDRESS):
@celery_app.task(base=CriticalSQLAlchemyTask) @celery_app.task(base=CriticalSQLAlchemyTask)
def check_lock(chained_input, chain_spec_dict, lock_flags, address=None): def check_lock(chained_input, chain_spec_dict, lock_flags, address=None):
chain_str = str(ChainSpec.from_dict(chain_spec_dict)) chain_str = '::'
if chain_spec_dict != None:
chain_str = str(ChainSpec.from_dict(chain_spec_dict))
session = SessionBase.create_session() session = SessionBase.create_session()
r = Lock.check(chain_str, lock_flags, address=ZERO_ADDRESS, session=session) r = Lock.check(chain_str, lock_flags, address=ZERO_ADDRESS, session=session)
if address != None: if address != None:

View File

@@ -0,0 +1,19 @@
# 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,
}

View File

@@ -62,6 +62,18 @@ class Api:
) )
def default_token(self):
s_token = celery.signature(
'cic_eth.admin.token.default_token',
[],
queue=self.queue,
)
if self.callback_param != None:
s_token.link(self.callback_success)
return s_token.apply_async()
def convert_transfer(self, from_address, to_address, target_return, minimum_return, from_token_symbol, to_token_symbol): 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. """Executes a chain of celery tasks that performs conversion between two ERC20 tokens, and transfers to a specified receipient after convert has completed.

View File

View File

@@ -0,0 +1,8 @@
from cic_eth.db.models.base import SessionBase
def health(*args, **kwargs):
session = SessionBase.create_session()
session.execute('SELECT count(*) from alembic_version')
session.close()
return True

View File

@@ -0,0 +1,48 @@
# standard imports
import logging
# external imports
from chainlib.connection import RPCConnection
from chainlib.chain import ChainSpec
from chainlib.eth.gas import balance
# local imports
from cic_eth.db.models.role import AccountRole
from cic_eth.db.models.base import SessionBase
from cic_eth.db.enum import LockEnum
from cic_eth.error import LockedError
from cic_eth.admin.ctrl import check_lock
logg = logging.getLogger().getChild(__name__)
def health(*args, **kwargs):
session = SessionBase.create_session()
config = kwargs['config']
chain_spec = ChainSpec.from_chain_str(config.get('CIC_CHAIN_SPEC'))
logg.debug('check gas balance of gas gifter for chain {}'.format(chain_spec))
try:
check_lock(None, None, LockEnum.INIT)
except LockedError:
logg.warning('INIT lock is set, skipping GAS GIFTER balance check.')
return True
gas_provider = AccountRole.get_address('GAS_GIFTER', session=session)
session.close()
rpc = RPCConnection.connect(chain_spec, 'default')
o = balance(gas_provider)
r = rpc.do(o)
try:
r = int(r, 16)
except TypeError:
r = int(r)
gas_min = int(config.get('ETH_GAS_GIFTER_MINIMUM_BALANCE'))
if r < gas_min:
logg.error('EEK! gas gifter has balance {}, below minimum {}'.format(r, gas_min))
return False
return True

View File

@@ -0,0 +1,37 @@
# standard imports
import time
import logging
from urllib.error import URLError
# external imports
from chainlib.connection import RPCConnection
from chainlib.eth.constant import ZERO_ADDRESS
from chainlib.eth.sign import sign_message
from chainlib.error import JSONRPCException
logg = logging.getLogger().getChild(__name__)
def health(*args, **kwargs):
blocked = True
max_attempts = 5
conn = RPCConnection.connect(kwargs['config'].get('CIC_CHAIN_SPEC'), tag='signer')
for i in range(max_attempts):
idx = i + 1
logg.debug('attempt signer connection check {}/{}'.format(idx, max_attempts))
try:
conn.do(sign_message(ZERO_ADDRESS, '0x2a'))
except FileNotFoundError:
pass
except ConnectionError:
pass
except URLError:
pass
except JSONRPCException:
logg.debug('signer connection succeeded')
return True
if idx < max_attempts:
time.sleep(0.5)
return False

View File

@@ -74,10 +74,11 @@ class LockEnum(enum.IntEnum):
QUEUE: Disable queueing new or modified transactions QUEUE: Disable queueing new or modified transactions
""" """
STICKY=1 STICKY=1
CREATE=2 INIT=2
SEND=4 CREATE=4
QUEUE=8 SEND=8
QUERY=16 QUEUE=16
QUERY=32
ALL=int(0xfffffffffffffffe) ALL=int(0xfffffffffffffffe)

View File

@@ -5,8 +5,11 @@ Revises: 1f1b3b641d08
Create Date: 2021-04-02 18:41:20.864265 Create Date: 2021-04-02 18:41:20.864265
""" """
import datetime
from alembic import op from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
from chainlib.eth.constant import ZERO_ADDRESS
from cic_eth.db.enum import LockEnum
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
@@ -23,10 +26,11 @@ def upgrade():
sa.Column("address", sa.String(42), nullable=True), sa.Column("address", sa.String(42), nullable=True),
sa.Column('blockchain', sa.String), sa.Column('blockchain', sa.String),
sa.Column("flags", sa.BIGINT(), nullable=False, default=0), sa.Column("flags", sa.BIGINT(), nullable=False, default=0),
sa.Column("date_created", sa.DateTime, nullable=False), sa.Column("date_created", sa.DateTime, nullable=False, default=datetime.datetime.utcnow),
sa.Column("otx_id", sa.Integer, sa.ForeignKey('otx.id'), nullable=True), sa.Column("otx_id", sa.Integer, sa.ForeignKey('otx.id'), nullable=True),
) )
op.create_index('idx_chain_address', 'lock', ['blockchain', 'address'], unique=True) op.create_index('idx_chain_address', 'lock', ['blockchain', 'address'], unique=True)
op.execute("INSERT INTO lock (address, date_created, blockchain, flags) VALUES('{}', '{}', '::', {})".format(ZERO_ADDRESS, datetime.datetime.utcnow(), LockEnum.INIT | LockEnum.SEND | LockEnum.QUEUE))
def downgrade(): def downgrade():

View File

@@ -59,6 +59,7 @@ args_override = {
'CIC_CHAIN_SPEC': getattr(args, 'i'), 'CIC_CHAIN_SPEC': getattr(args, 'i'),
} }
# override args # override args
config.dict_override(args_override, 'cli')
config.censor('PASSWORD', 'DATABASE') config.censor('PASSWORD', 'DATABASE')
config.censor('PASSWORD', 'SSL') config.censor('PASSWORD', 'SSL')
logg.debug('config loaded from {}:\n{}'.format(config_dir, config)) logg.debug('config loaded from {}:\n{}'.format(config_dir, config))
@@ -67,7 +68,9 @@ celery_app = celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=confi
queue = args.q queue = args.q
chain_spec = ChainSpec.from_chain_str(config.get('CIC_CHAIN_SPEC')) chain_spec = None
if config.get('CIC_CHAIN_SPEC') != None and config.get('CIC_CHAIN_SPEC') != '::':
chain_spec = ChainSpec.from_chain_str(config.get('CIC_CHAIN_SPEC'))
admin_api = AdminApi(None) admin_api = AdminApi(None)
@@ -82,6 +85,9 @@ def lock_names_to_flag(s):
# TODO: move each command to submodule # TODO: move each command to submodule
def main(): def main():
chain_spec_dict = None
if chain_spec != None:
chain_spec_dict = chain_spec.asdict()
if args.command == 'unlock': if args.command == 'unlock':
flags = lock_names_to_flag(args.flags) flags = lock_names_to_flag(args.flags)
if not is_checksum_address(args.address): if not is_checksum_address(args.address):
@@ -91,7 +97,7 @@ def main():
'cic_eth.admin.ctrl.unlock', 'cic_eth.admin.ctrl.unlock',
[ [
None, None,
chain_spec.asdict(), chain_spec_dict,
args.address, args.address,
flags, flags,
], ],
@@ -110,7 +116,7 @@ def main():
'cic_eth.admin.ctrl.lock', 'cic_eth.admin.ctrl.lock',
[ [
None, None,
chain_spec.asdict(), chain_spec_dict,
args.address, args.address,
flags, flags,
], ],

View File

@@ -15,6 +15,9 @@ from chainlib.connection import RPCConnection
from chainlib.eth.connection import EthUnixSignerConnection from chainlib.eth.connection import EthUnixSignerConnection
from chainlib.chain import ChainSpec from chainlib.chain import ChainSpec
from chainqueue.db.models.otx import Otx from chainqueue.db.models.otx import Otx
from cic_eth_registry.error import UnknownContractError
import liveness.linux
# local imports # local imports
from cic_eth.eth import ( from cic_eth.eth import (
@@ -27,6 +30,7 @@ from cic_eth.eth import (
from cic_eth.admin import ( from cic_eth.admin import (
debug, debug,
ctrl, ctrl,
token,
) )
from cic_eth.queue import ( from cic_eth.queue import (
query, query,
@@ -51,6 +55,8 @@ from cic_eth.registry import (
connect_declarator, connect_declarator,
connect_token_registry, connect_token_registry,
) )
from cic_eth.task import BaseTask
logging.basicConfig(level=logging.WARNING) logging.basicConfig(level=logging.WARNING)
logg = logging.getLogger() logg = logging.getLogger()
@@ -62,6 +68,7 @@ argparser.add_argument('-p', '--provider', dest='p', type=str, help='rpc provide
argparser.add_argument('-c', type=str, default=config_dir, help='config file') argparser.add_argument('-c', type=str, default=config_dir, help='config file')
argparser.add_argument('-q', type=str, default='cic-eth', help='queue name for worker tasks') argparser.add_argument('-q', type=str, default='cic-eth', help='queue name for worker tasks')
argparser.add_argument('-r', type=str, help='CIC registry address') argparser.add_argument('-r', type=str, help='CIC registry address')
argparser.add_argument('--default-token-symbol', dest='default_token_symbol', type=str, help='Symbol of default token to use')
argparser.add_argument('--abi-dir', dest='abi_dir', type=str, help='Directory containing bytecode and abi') argparser.add_argument('--abi-dir', dest='abi_dir', type=str, help='Directory containing bytecode and abi')
argparser.add_argument('--trace-queue-status', default=None, dest='trace_queue_status', action='store_true', help='set to perist all queue entry status changes to storage') argparser.add_argument('--trace-queue-status', default=None, dest='trace_queue_status', action='store_true', help='set to perist all queue entry status changes to storage')
argparser.add_argument('-i', '--chain-spec', dest='i', type=str, help='chain spec') argparser.add_argument('-i', '--chain-spec', dest='i', type=str, help='chain spec')
@@ -81,6 +88,7 @@ config.process()
args_override = { args_override = {
'CIC_CHAIN_SPEC': getattr(args, 'i'), 'CIC_CHAIN_SPEC': getattr(args, 'i'),
'CIC_REGISTRY_ADDRESS': getattr(args, 'r'), 'CIC_REGISTRY_ADDRESS': getattr(args, 'r'),
'CIC_DEFAULT_TOKEN_SYMBOL': getattr(args, 'default_token_symbol'),
'ETH_PROVIDER': getattr(args, 'p'), 'ETH_PROVIDER': getattr(args, 'p'),
'TASKS_TRACE_QUEUE_STATUS': getattr(args, 'trace_queue_status'), 'TASKS_TRACE_QUEUE_STATUS': getattr(args, 'trace_queue_status'),
} }
@@ -90,14 +98,15 @@ config.censor('PASSWORD', 'DATABASE')
config.censor('PASSWORD', 'SSL') config.censor('PASSWORD', 'SSL')
logg.debug('config loaded from {}:\n{}'.format(args.c, config)) logg.debug('config loaded from {}:\n{}'.format(args.c, config))
health_modules = config.get('CIC_HEALTH_MODULES', [])
if len(health_modules) != 0:
health_modules = health_modules.split(',')
logg.debug('health mods {}'.format(health_modules))
# connect to database # connect to database
dsn = dsn_from_config(config) dsn = dsn_from_config(config)
SessionBase.connect(dsn, pool_size=int(config.get('DATABASE_POOL_SIZE')), debug=config.true('DATABASE_DEBUG')) SessionBase.connect(dsn, pool_size=int(config.get('DATABASE_POOL_SIZE')), debug=config.true('DATABASE_DEBUG'))
# verify database connection with minimal sanity query
session = SessionBase.create_session()
session.execute('select version_num from alembic_version')
session.close()
# set up celery # set up celery
current_app = celery.Celery(__name__) current_app = celery.Celery(__name__)
@@ -135,10 +144,15 @@ else:
chain_spec = ChainSpec.from_chain_str(config.get('CIC_CHAIN_SPEC')) chain_spec = ChainSpec.from_chain_str(config.get('CIC_CHAIN_SPEC'))
RPCConnection.register_location(config.get('ETH_PROVIDER'), chain_spec, 'default') RPCConnection.register_location(config.get('ETH_PROVIDER'), chain_spec, 'default')
RPCConnection.register_location(config.get('SIGNER_SOCKET_PATH'), chain_spec, 'signer', constructor=EthUnixSignerConnection) #RPCConnection.register_location(config.get('SIGNER_SOCKET_PATH'), chain_spec, 'signer', constructor=EthUnixSignerConnection)
RPCConnection.register_location(config.get('SIGNER_SOCKET_PATH'), chain_spec, 'signer')
Otx.tracing = config.true('TASKS_TRACE_QUEUE_STATUS') Otx.tracing = config.true('TASKS_TRACE_QUEUE_STATUS')
#import cic_eth.checks.gas
#if not cic_eth.checks.gas.health(config=config):
# raise RuntimeError()
liveness.linux.load(health_modules, rundir=config.get('CIC_RUN_DIR'), config=config)
def main(): def main():
argv = ['worker'] argv = ['worker']
@@ -162,7 +176,11 @@ def main():
rpc = RPCConnection.connect(chain_spec, 'default') rpc = RPCConnection.connect(chain_spec, 'default')
connect_registry(rpc, chain_spec, config.get('CIC_REGISTRY_ADDRESS')) try:
registry = connect_registry(rpc, chain_spec, config.get('CIC_REGISTRY_ADDRESS'))
except UnknownContractError as e:
logg.exception('Registry contract connection failed for {}: {}'.format(config.get('CIC_REGISTRY_ADDRESS'), e))
sys.exit(1)
trusted_addresses_src = config.get('CIC_TRUST_ADDRESS') trusted_addresses_src = config.get('CIC_TRUST_ADDRESS')
if trusted_addresses_src == None: if trusted_addresses_src == None:
@@ -171,10 +189,17 @@ def main():
trusted_addresses = trusted_addresses_src.split(',') trusted_addresses = trusted_addresses_src.split(',')
for address in trusted_addresses: for address in trusted_addresses:
logg.info('using trusted address {}'.format(address)) logg.info('using trusted address {}'.format(address))
connect_declarator(rpc, chain_spec, trusted_addresses) connect_declarator(rpc, chain_spec, trusted_addresses)
connect_token_registry(rpc, chain_spec) connect_token_registry(rpc, chain_spec)
BaseTask.default_token_symbol = config.get('CIC_DEFAULT_TOKEN_SYMBOL')
BaseTask.default_token_address = registry.by_name(BaseTask.default_token_symbol)
logg.info('default token set to {} {}'.format(BaseTask.default_token_symbol, BaseTask.default_token_address))
liveness.linux.set()
current_app.worker_main(argv) current_app.worker_main(argv)
liveness.linux.reset()
@celery.signals.eventlet_pool_postshutdown.connect @celery.signals.eventlet_pool_postshutdown.connect

View File

@@ -0,0 +1,65 @@
#!python3
# SPDX-License-Identifier: GPL-3.0-or-later
# standard imports
import logging
import argparse
import os
# external imports
import confini
import celery
# local imports
from cic_eth.api import Api
logging.basicConfig(level=logging.WARNING)
logg = logging.getLogger()
default_format = 'terminal'
default_config_dir = os.environ.get('CONFINI_DIR', '/usr/local/etc/cic')
argparser = argparse.ArgumentParser()
argparser.add_argument('-i', '--chain-spec', dest='i', type=str, help='chain spec')
argparser.add_argument('-c', type=str, default=default_config_dir, help='config root to use')
argparser.add_argument('-q', type=str, default='cic-eth', help='celery queue to submit transaction tasks to')
argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration')
argparser.add_argument('-v', action='store_true', help='Be verbose')
argparser.add_argument('-vv', help='be more verbose', action='store_true')
args = argparser.parse_args()
if args.v == True:
logging.getLogger().setLevel(logging.INFO)
elif args.vv == True:
logging.getLogger().setLevel(logging.DEBUG)
config_dir = os.path.join(args.c)
os.makedirs(config_dir, 0o777, True)
config = confini.Config(config_dir, args.env_prefix)
config.process()
args_override = {
'CIC_CHAIN_SPEC': getattr(args, 'i'),
}
config.dict_override(args_override, 'cli args')
config.censor('PASSWORD', 'DATABASE')
config.censor('PASSWORD', 'SSL')
logg.debug('config loaded from {}:\n{}'.format(config_dir, config))
celery_app = celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL'))
queue = args.q
api = Api(config.get('CIC_CHAIN_SPEC'), queue=queue)
def main():
t = api.default_token()
token_info = t.get()
print('Default token symbol: {}'.format(token_info['symbol']))
print('Default token address: {}'.format(token_info['address']))
if __name__ == '__main__':
main()

View File

@@ -29,6 +29,8 @@ class BaseTask(celery.Task):
call_address = ZERO_ADDRESS call_address = ZERO_ADDRESS
create_nonce_oracle = RPCNonceOracle create_nonce_oracle = RPCNonceOracle
create_gas_oracle = RPCGasOracle create_gas_oracle = RPCGasOracle
default_token_address = None
default_token_symbol = None
def create_session(self): def create_session(self):
return BaseTask.session_func() return BaseTask.session_func()
@@ -94,3 +96,8 @@ class CriticalWeb3AndSignerTask(CriticalTask):
def hello(self): def hello(self):
time.sleep(0.1) time.sleep(0.1)
return id(SessionBase.create_session) return id(SessionBase.create_session)
@celery_app.task()
def check_health(self):
celery.app.control.shutdown()

View File

@@ -10,7 +10,7 @@ version = (
0, 0,
11, 11,
0, 0,
'beta.6', 'beta.9',
) )
version_object = semver.VersionInfo( version_object = semver.VersionInfo(

View File

@@ -3,3 +3,6 @@ registry_address =
chain_spec = evm:bloxberg:8996 chain_spec = evm:bloxberg:8996
tx_retry_delay = tx_retry_delay =
trust_address = trust_address =
default_token_symbol = GFT
health_modules = cic_eth.check.db,cic_eth.check.signer,cic_eth.check.gas
run_dir = /run

View File

@@ -3,3 +3,6 @@ registry_address =
chain_spec = evm:bloxberg:8996 chain_spec = evm:bloxberg:8996
trust_address = 0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C trust_address = 0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C
tx_retry_delay = 20 tx_retry_delay = 20
default_token_symbol = GFT
health_modules = cic_eth.check.db,cic_eth.check.signer,cic_eth.check.gas
run_dir = /run

View File

@@ -1,8 +1,3 @@
[eth] [eth]
#ws_provider = ws://localhost:8546
#ttp_provider = http://localhost:8545
provider = http://localhost:63545 provider = http://localhost:63545
gas_provider_address = gas_gifter_minimum_balance = 10000000000000000000000
#chain_id =
abi_dir = /home/lash/src/ext/cic/grassrootseconomics/cic-contracts/abis
account_accounts_index_writer =

View File

@@ -1,5 +1,5 @@
[signer] [signer]
socket_path = /tmp/crypto-dev-signer/jsonrpc.ipc socket_path = ipc:///tmp/crypto-dev-signer/jsonrpc.ipc
secret = deedbeef secret = deedbeef
database_name = signer_test database_name = signer_test
dev_keys_path = dev_keys_path =

View File

@@ -1,8 +1,3 @@
[eth] [eth]
#ws_provider = ws://localhost:8546
#ttp_provider = http://localhost:8545
provider = http://localhost:8545 provider = http://localhost:8545
gas_provider_address = gas_gifter_minimum_balance = 10000000000000000000000
#chain_id =
abi_dir = /usr/local/share/cic/solidity/abi
account_accounts_index_writer =

View File

@@ -53,3 +53,5 @@ COPY cic-eth/crypto_dev_signer_config/ /usr/local/etc/crypto-dev-signer/
RUN git clone https://gitlab.com/grassrootseconomics/cic-contracts.git && \ RUN git clone https://gitlab.com/grassrootseconomics/cic-contracts.git && \
mkdir -p /usr/local/share/cic/solidity && \ mkdir -p /usr/local/share/cic/solidity && \
cp -R cic-contracts/abis /usr/local/share/cic/solidity/abi cp -R cic-contracts/abis /usr/local/share/cic/solidity/abi
COPY util/liveness/health.sh /usr/local/bin/health.sh

View File

@@ -1,6 +1,6 @@
cic-base~=0.1.2a76 cic-base==0.1.2b1
celery==4.4.7 celery==4.4.7
crypto-dev-signer~=0.4.14b2 crypto-dev-signer~=0.4.14b3
confini~=0.3.6rc3 confini~=0.3.6rc3
cic-eth-registry~=0.5.4a16 cic-eth-registry~=0.5.4a16
#cic-bancor~=0.0.6 #cic-bancor~=0.0.6

View File

@@ -38,6 +38,7 @@ packages =
cic_eth.runnable.daemons.filters cic_eth.runnable.daemons.filters
cic_eth.callbacks cic_eth.callbacks
cic_eth.sync cic_eth.sync
cic_eth.check
scripts = scripts =
./scripts/migrate.py ./scripts/migrate.py
@@ -52,6 +53,7 @@ console_scripts =
cic-eth-create = cic_eth.runnable.create:main cic-eth-create = cic_eth.runnable.create:main
cic-eth-inspect = cic_eth.runnable.view:main cic-eth-inspect = cic_eth.runnable.view:main
cic-eth-ctl = cic_eth.runnable.ctrl:main cic-eth-ctl = cic_eth.runnable.ctrl:main
cic-eth-info = cic_eth.runnable.info:main
# TODO: Merge this with ctl when subcmds sorted to submodules # TODO: Merge this with ctl when subcmds sorted to submodules
cic-eth-tag = cic_eth.runnable.tag:main cic-eth-tag = cic_eth.runnable.tag:main
cic-eth-resend = cic_eth.runnable.resend:main cic-eth-resend = cic_eth.runnable.resend:main

View File

@@ -3,8 +3,12 @@ import os
import sys import sys
import logging import logging
# external imports
from chainlib.eth.erc20 import ERC20
# local imports # local imports
from cic_eth.api import Api from cic_eth.api import Api
from cic_eth.task import BaseTask
script_dir = os.path.dirname(os.path.realpath(__file__)) script_dir = os.path.dirname(os.path.realpath(__file__))
root_dir = os.path.dirname(script_dir) root_dir = os.path.dirname(script_dir)
@@ -28,3 +32,26 @@ def api(
): ):
chain_str = str(default_chain_spec) chain_str = str(default_chain_spec)
return Api(chain_str, queue=None, callback_param='foo') return Api(chain_str, queue=None, callback_param='foo')
@pytest.fixture(scope='function')
def foo_token_symbol(
default_chain_spec,
foo_token,
eth_rpc,
contract_roles,
):
c = ERC20(default_chain_spec)
o = c.symbol(foo_token, sender_address=contract_roles['CONTRACT_DEPLOYER'])
r = eth_rpc.do(o)
return c.parse_symbol(r)
@pytest.fixture(scope='function')
def default_token(
foo_token,
foo_token_symbol,
):
BaseTask.default_token_symbol = foo_token_symbol
BaseTask.default_token_address = foo_token

View File

@@ -34,6 +34,7 @@ def celery_includes():
'cic_eth.admin.ctrl', 'cic_eth.admin.ctrl',
'cic_eth.admin.nonce', 'cic_eth.admin.nonce',
'cic_eth.admin.debug', 'cic_eth.admin.debug',
'cic_eth.admin.token',
'cic_eth.eth.account', 'cic_eth.eth.account',
'cic_eth.callbacks.noop', 'cic_eth.callbacks.noop',
'cic_eth.callbacks.http', 'cic_eth.callbacks.http',

View File

@@ -0,0 +1,21 @@
# external imports
import celery
def test_default_token(
default_token,
celery_session_worker,
foo_token,
foo_token_symbol,
):
s = celery.signature(
'cic_eth.admin.token.default_token',
[],
queue=None,
)
t = s.apply_async()
r = t.get()
assert r['address'] == foo_token
assert r['symbol'] == foo_token_symbol

View File

@@ -1,4 +1,4 @@
cic_base[full_graph]~=0.1.2a68 cic_base[full_graph]~=0.1.2ab2
cic-eth~=0.11.0b3 cic-eth~=0.11.0b9
cic-notify~=0.4.0a4 cic-notify~=0.4.0a4
cic-types~=0.1.0a10 cic-types~=0.1.0a10

View File

@@ -57,19 +57,22 @@ WORKDIR /home/grassroots
USER grassroots USER grassroots
ARG pip_extra_index_url=https://pip.grassrootseconomics.net:8433 ARG pip_extra_index_url=https://pip.grassrootseconomics.net:8433
ARG cic_base_version=0.1.2a77 ARG cic_base_version=0.1.2a79
ARG cic_eth_version=0.11.0b6 ARG cic_eth_version=0.11.0b8+build.c2286e5c
ARG sarafu_faucet_version=0.0.2a28 ARG sarafu_faucet_version=0.0.2a28
ARG sarafu_token_version==0.0.1a6
ARG cic_contracts_version=0.0.2a2 ARG cic_contracts_version=0.0.2a2
RUN pip install --user --extra-index-url $pip_extra_index_url cic-base[full_graph]==$cic_base_version \ RUN pip install --user --extra-index-url $pip_extra_index_url cic-base[full_graph]==$cic_base_version \
cic-eth==$cic_eth_version \ cic-eth==$cic_eth_version \
cic-contracts==$cic_contracts_version \ cic-contracts==$cic_contracts_version \
sarafu-faucet==$sarafu_faucet_version sarafu-faucet==$sarafu_faucet_version \
sarafu-token==$sarafu_token_version
FROM python:3.8.6-slim-buster as runtime-image FROM python:3.8.6-slim-buster as runtime-image
RUN apt-get update RUN apt-get update
RUN apt-get install -y --no-install-recommends gnupg libpq-dev RUN apt-get install -y --no-install-recommends gnupg libpq-dev
RUN apt-get install -y --no-install-recommends jq
COPY --from=compile-image /usr/local/bin/ /usr/local/bin/ COPY --from=compile-image /usr/local/bin/ /usr/local/bin/
COPY --from=compile-image /usr/local/etc/cic/ /usr/local/etc/cic/ COPY --from=compile-image /usr/local/etc/cic/ /usr/local/etc/cic/

View File

@@ -2,82 +2,111 @@
set -a set -a
DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER=0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C CIC_CHAIN_SPEC=${CIC_CHAIN_SPEC:-evm:bloxberg:8995}
CIC_DEFAULT_TOKEN_SYMBOL=${CIC_DEFAULT_TOKEN_SYMBOL:-GFT}
DEV_ETH_ACCOUNT_RESERVE_MINTER=${DEV_ETH_ACCOUNT_RESERVE_MINTER:-$DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER} DEV_ETH_ACCOUNT_RESERVE_MINTER=${DEV_ETH_ACCOUNT_RESERVE_MINTER:-$DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER}
DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER=${DEV_ETH_ACCOUNT_RESERVE_MINTER:-$DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER} DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER=${DEV_ETH_ACCOUNT_RESERVE_MINTER:-$DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER}
DEV_RESERVE_AMOUNT=${DEV_ETH_RESERVE_AMOUNT:-""10000000000000000000000000000000000} DEV_RESERVE_AMOUNT=${DEV_ETH_RESERVE_AMOUNT:-""10000000000000000000000000000000000}
faucet_amount=${DEV_FAUCET_AMOUNT:-0} DEV_FAUCET_AMOUNT=${DEV_FAUCET_AMOUNT:-0}
keystore_file=$(realpath ./keystore/UTC--2021-01-08T17-18-44.521011372Z--eb3907ecad74a0013c259d5874ae7f22dcbcc95c) DEV_ETH_KEYSTORE_FILE=${DEV_ETH_KEYSTORE_FILE:-`realpath ./keystore/UTC--2021-01-08T17-18-44.521011372Z--eb3907ecad74a0013c259d5874ae7f22dcbcc95c`}
set -e
DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER=`eth-checksum $(cat $DEV_ETH_KEYSTORE_FILE | jq -r .address)`
if [ ! -z $DEV_ETH_GAS_PRICE ]; then
gas_price_arg="--gas-price $DEV_ETH_GAS_PRICE"
>&2 echo using static gas price $DEV_ETH_GAS_PRICE
fi
if [[ $CIC_DEFAULT_TOKEN_SYMBOL != 'GFT' && $CIC_DEFAULT_TOKEN_SYMBOL != 'SRF' ]]; then
>&2 echo CIC_DEFAULT_TOKEN_SYMBOL must be one of [GFT,SRF], but was $CIC_DEFAULT_TOKEN_SYMBOL
exit 1
fi
echo "environment:" echo "environment:"
printenv printenv
echo \n echo \n
echo "using wallet address '$DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER' from keystore file $DEV_ETH_KEYSTORE_FILE"
# This is a grassroots team convention for building the Bancor contracts using the bancor protocol repository truffle setup # This is a grassroots team convention for building the Bancor contracts using the bancor protocol repository truffle setup
# Running this in docker-internal dev container (built from Docker folder in this repo) will write a # Running this in docker-internal dev container (built from Docker folder in this repo) will write a
# source-able env file to CIC_DATA_DIR. Services dependent on these contracts can mount this file OR # source-able env file to CIC_DATA_DIR. Services dependent on these contracts can mount this file OR
# define these parameters at runtime # define these parameters at runtime
# pushd /usr/src # pushd /usr/src
if [ -z $CIC_DATA_DIR ]; then
CIC_DATA_DIR=`mktemp -d`
fi
>&2 echo using data dir $CIC_DATA_DIR
init_level_file=${CIC_DATA_DIR}/.init init_level_file=${CIC_DATA_DIR}/.init
if [ ! -f ${CIC_DATA_DIR}/.init ]; then if [ ! -f ${CIC_DATA_DIR}/.init ]; then
echo "Creating .init file..." echo "Creating .init file..."
mkdir -p $CIC_DATA_DIR mkdir -p $CIC_DATA_DIR
touch /tmp/cic/config/.init touch $CIC_DATA_DIR/.init
# touch $init_level_file # touch $init_level_file
fi fi
echo -n 1 > $init_level_file echo -n 1 > $init_level_file
# Abort on any error (including if wait-for-it fails). # Abort on any error (including if wait-for-it fails).
set -e
# Wait for the backend to be up, if we know where it is. # Wait for the backend to be up, if we know where it is.
if [[ -n "${ETH_PROVIDER}" ]]; then if [[ -n "${ETH_PROVIDER}" ]]; then
echo "waiting for ${ETH_PROVIDER}..."
./wait-for-it.sh "${ETH_PROVIDER_HOST}:${ETH_PROVIDER_PORT}"
DEV_RESERVE_ADDRESS=`giftable-token-deploy -p $ETH_PROVIDER -y $keystore_file -i $CIC_CHAIN_SPEC -v -w --name "Sarafu" --symbol "SRF" --decimals 6` if [ ! -z "$DEV_USE_DOCKER_WAIT_SCRIPT" ]; then
giftable-token-gift -p $ETH_PROVIDER -y $keystore_file -i $CIC_CHAIN_SPEC -v -w -a $DEV_RESERVE_ADDRESS $DEV_RESERVE_AMOUNT echo "waiting for ${ETH_PROVIDER}..."
./wait-for-it.sh "${ETH_PROVIDER_HOST}:${ETH_PROVIDER_PORT}"
fi
#BANCOR_REGISTRY_ADDRESS=`cic-bancor-deploy --bancor-dir /usr/local/share/cic/bancor -z $DEV_ETH_RESERVE_ADDRESS -p $ETH_PROVIDER -o $DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER` if [ $CIC_DEFAULT_TOKEN_SYMBOL == 'GFT' ]; then
>&2 echo "deploying 'giftable token'"
DEV_RESERVE_ADDRESS=`giftable-token-deploy $gas_price_arg -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -vv -w --name "Giftable Token" --symbol "GFT" --decimals 6 -vv`
else
>&2 echo "deploying 'sarafu' token'"
DEV_RESERVE_ADDRESS=`sarafu-token-deploy $gas_price_arg -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -vv -w --name "Sarafu" --decimals 6 -vv SRF $DEV_SARAFU_DEMURRAGE_LEVEL`
fi
giftable-token-gift $gas_price_arg -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -vv -w -a $DEV_RESERVE_ADDRESS $DEV_RESERVE_AMOUNT
#BANCOR_REGISTRY_ADDRESS=`cic-bancor-deploy $gas_price_arg --bancor-dir /usr/local/share/cic/bancor -z $DEV_ETH_RESERVE_ADDRESS -p $ETH_PROVIDER -o $DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER`
>&2 echo "deploy account index contract" >&2 echo "deploy account index contract"
DEV_ACCOUNT_INDEX_ADDRESS=`eth-accounts-index-deploy -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -y $keystore_file -vv -w` DEV_ACCOUNT_INDEX_ADDRESS=`eth-accounts-index-deploy $gas_price_arg -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -y $DEV_ETH_KEYSTORE_FILE -vv -w`
>&2 echo "add deployer address as account index writer" >&2 echo "add deployer address as account index writer"
eth-accounts-index-writer -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -a $DEV_ACCOUNT_INDEX_ADDRESS -ww $debug $DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER eth-accounts-index-writer $gas_price_arg -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -a $DEV_ACCOUNT_INDEX_ADDRESS -ww -vv $debug $DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER
CIC_REGISTRY_ADDRESS=`eth-contract-registry-deploy -i $CIC_CHAIN_SPEC -y $keystore_file --identifier BancorRegistry --identifier AccountRegistry --identifier TokenRegistry --identifier AddressDeclarator --identifier Faucet --identifier TransferAuthorization -p $ETH_PROVIDER -vv -w` CIC_REGISTRY_ADDRESS=`eth-contract-registry-deploy $gas_price_arg -i $CIC_CHAIN_SPEC -y $DEV_ETH_KEYSTORE_FILE --identifier BancorRegistry --identifier AccountRegistry --identifier TokenRegistry --identifier AddressDeclarator --identifier Faucet --identifier TransferAuthorization -p $ETH_PROVIDER -vv -w`
eth-contract-registry-set -w -y $keystore_file -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv ContractRegistry $CIC_REGISTRY_ADDRESS eth-contract-registry-set $gas_price_arg -w -y $DEV_ETH_KEYSTORE_FILE -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv ContractRegistry $CIC_REGISTRY_ADDRESS
#cic-registry-set -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -k BancorRegistry -p $ETH_PROVIDER $BANCOR_REGISTRY_ADDRESS -vv eth-contract-registry-set $gas_price_arg -w -y $DEV_ETH_KEYSTORE_FILE -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv AccountRegistry $DEV_ACCOUNT_INDEX_ADDRESS
eth-contract-registry-set -w -y $keystore_file -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv AccountRegistry $DEV_ACCOUNT_INDEX_ADDRESS
# Deploy address declarator registry # Deploy address declarator registry
>&2 echo "deploy address declarator contract" >&2 echo "deploy address declarator contract"
declarator_description=0x546869732069732074686520434943206e6574776f726b000000000000000000 declarator_description=0x546869732069732074686520434943206e6574776f726b000000000000000000
DEV_DECLARATOR_ADDRESS=`eth-address-declarator-deploy -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w -v $declarator_description` DEV_DECLARATOR_ADDRESS=`eth-address-declarator-deploy -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w -vv $declarator_description`
eth-contract-registry-set -w -y $keystore_file -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv AddressDeclarator $DEV_DECLARATOR_ADDRESS eth-contract-registry-set $gas_price_arg -w -y $DEV_ETH_KEYSTORE_FILE -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv AddressDeclarator $DEV_DECLARATOR_ADDRESS
# Deploy transfer authorization contact # Deploy transfer authorization contact
>&2 echo "deploy address declarator contract" >&2 echo "deploy address declarator contract"
DEV_TRANSFER_AUTHORIZATION_ADDRESS=`erc20-transfer-auth-deploy -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w -v` DEV_TRANSFER_AUTHORIZATION_ADDRESS=`erc20-transfer-auth-deploy $gas_price_arg -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w -vv`
eth-contract-registry-set -w -y $keystore_file -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv TransferAuthorization $DEV_TRANSFER_AUTHORIZATION_ADDRESS eth-contract-registry-set $gas_price_arg -w -y $DEV_ETH_KEYSTORE_FILE -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv TransferAuthorization $DEV_TRANSFER_AUTHORIZATION_ADDRESS
# Deploy token index contract # Deploy token index contract
>&2 echo "deploy token index contract" >&2 echo "deploy token index contract"
DEV_TOKEN_INDEX_ADDRESS=`eth-token-index-deploy -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w -v` DEV_TOKEN_INDEX_ADDRESS=`eth-token-index-deploy $gas_price_arg -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w -vv`
eth-contract-registry-set -w -y $keystore_file -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv TokenRegistry $DEV_TOKEN_INDEX_ADDRESS eth-contract-registry-set $gas_price_arg -w -y $DEV_ETH_KEYSTORE_FILE -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv TokenRegistry $DEV_TOKEN_INDEX_ADDRESS
>&2 echo "add reserve token to token index" >&2 echo "add reserve token to token index"
eth-token-index-add -w -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv -a $DEV_TOKEN_INDEX_ADDRESS $DEV_RESERVE_ADDRESS eth-token-index-add $gas_price_arg -w -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv -a $DEV_TOKEN_INDEX_ADDRESS $DEV_RESERVE_ADDRESS
# Sarafu faucet contract # Sarafu faucet contract
>&2 echo "deploy token faucet contract" >&2 echo "deploy token faucet contract"
DEV_FAUCET_ADDRESS=`sarafu-faucet-deploy -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w -v --account-index-address $DEV_ACCOUNT_INDEX_ADDRESS $DEV_RESERVE_ADDRESS` DEV_FAUCET_ADDRESS=`sarafu-faucet-deploy $gas_price_arg -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -w -vv --account-index-address $DEV_ACCOUNT_INDEX_ADDRESS $DEV_RESERVE_ADDRESS`
eth-contract-registry-set -w -y $keystore_file -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv Faucet $DEV_FAUCET_ADDRESS eth-contract-registry-set $gas_price_arg -w -y $DEV_ETH_KEYSTORE_FILE -r $CIC_REGISTRY_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv Faucet $DEV_FAUCET_ADDRESS
>&2 echo "set faucet as token minter" >&2 echo "set faucet as token minter"
giftable-token-minter -w -y $keystore_file -a $DEV_RESERVE_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv $DEV_FAUCET_ADDRESS giftable-token-minter $gas_price_arg -w -y $DEV_ETH_KEYSTORE_FILE -a $DEV_RESERVE_ADDRESS -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -vv $DEV_FAUCET_ADDRESS
>&2 echo "set token faucet amount" >&2 echo "set token faucet amount"
sarafu-faucet-set -y $keystore_file -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -a $DEV_FAUCET_ADDRESS $faucet_amount sarafu-faucet-set $gas_price_arg -y $DEV_ETH_KEYSTORE_FILE -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -a $DEV_FAUCET_ADDRESS -vv $DEV_FAUCET_AMOUNT
else else

View File

@@ -32,6 +32,7 @@ default_config_dir = '/usr/local/etc/cic'
argparser = argparse.ArgumentParser() argparser = argparse.ArgumentParser()
argparser.add_argument('-c', type=str, default=default_config_dir, help='config file') argparser.add_argument('-c', type=str, default=default_config_dir, help='config file')
argparser.add_argument('-i', '--chain-spec', dest='i', type=str, help='Chain specification string') argparser.add_argument('-i', '--chain-spec', dest='i', type=str, help='Chain specification string')
argparser.add_argument('--old-chain-spec', type=str, dest='old_chain_spec', default='evm:oldchain:1', help='chain spec')
argparser.add_argument('--redis-host', dest='redis_host', type=str, help='redis host to use for task submission') argparser.add_argument('--redis-host', dest='redis_host', type=str, help='redis host to use for task submission')
argparser.add_argument('--redis-port', dest='redis_port', type=int, help='redis host to use for task submission') argparser.add_argument('--redis-port', dest='redis_port', type=int, help='redis host to use for task submission')
argparser.add_argument('--redis-db', dest='redis_db', type=int, help='redis db to use for task submission and callback') argparser.add_argument('--redis-db', dest='redis_db', type=int, help='redis db to use for task submission and callback')
@@ -76,6 +77,11 @@ os.makedirs(user_new_dir)
meta_dir = os.path.join(args.user_dir, 'meta') meta_dir = os.path.join(args.user_dir, 'meta')
os.makedirs(meta_dir) os.makedirs(meta_dir)
custom_dir = os.path.join(args.user_dir, 'custom')
os.makedirs(custom_dir)
os.makedirs(os.path.join(custom_dir, 'new'))
os.makedirs(os.path.join(custom_dir, 'meta'))
phone_dir = os.path.join(args.user_dir, 'phone') phone_dir = os.path.join(args.user_dir, 'phone')
os.makedirs(os.path.join(phone_dir, 'meta')) os.makedirs(os.path.join(phone_dir, 'meta'))
@@ -85,6 +91,11 @@ os.stat(user_old_dir)
txs_dir = os.path.join(args.user_dir, 'txs') txs_dir = os.path.join(args.user_dir, 'txs')
os.makedirs(txs_dir) os.makedirs(txs_dir)
user_dir = args.user_dir
old_chain_spec = ChainSpec.from_chain_str(args.old_chain_spec)
old_chain_str = str(old_chain_spec)
chain_spec = ChainSpec.from_chain_str(config.get('CIC_CHAIN_SPEC')) chain_spec = ChainSpec.from_chain_str(config.get('CIC_CHAIN_SPEC'))
chain_str = str(chain_spec) chain_str = str(chain_spec)
@@ -133,7 +144,17 @@ def register_eth(i, u):
if __name__ == '__main__': if __name__ == '__main__':
#fi = open(os.path.join(user_out_dir, 'addresses.csv'), 'a') user_tags = {}
f = open(os.path.join(user_dir, 'tags.csv'), 'r')
while True:
r = f.readline().rstrip()
if len(r) == 0:
break
(old_address, tags_csv) = r.split(':')
old_address = strip_0x(old_address)
user_tags[old_address] = tags_csv.split(',')
logg.debug('read tags {} for old address {}'.format(user_tags[old_address], old_address))
i = 0 i = 0
j = 0 j = 0
@@ -198,6 +219,29 @@ if __name__ == '__main__':
os.symlink(os.path.realpath(filepath), meta_phone_filepath) os.symlink(os.path.realpath(filepath), meta_phone_filepath)
# custom data
custom_key = generate_metadata_pointer(phone.encode('utf-8'), ':cic.custom')
custom_filepath = os.path.join(custom_dir, 'meta', custom_key)
filepath = os.path.join(
custom_dir,
'new',
custom_key[:2].upper(),
custom_key[2:4].upper(),
custom_key.upper() + '.json',
)
os.makedirs(os.path.dirname(filepath), exist_ok=True)
sub_old_chain_str = '{}:{}'.format(old_chain_spec.common_name(), old_chain_spec.network_id())
f = open(filepath, 'w')
k = u.identities['evm'][sub_old_chain_str][0]
tag_data = {'tags': user_tags[strip_0x(k)]}
f.write(json.dumps(tag_data))
f.close()
os.symlink(os.path.realpath(filepath), custom_filepath)
i += 1 i += 1
sys.stdout.write('imported {} {}'.format(i, u).ljust(200) + "\r") sys.stdout.write('imported {} {}'.format(i, u).ljust(200) + "\r")

View File

@@ -0,0 +1,139 @@
const fs = require('fs');
const path = require('path');
const http = require('http');
const cic = require('cic-client-meta');
const vcfp = require('vcard-parser');
//const conf = JSON.parse(fs.readFileSync('./cic.conf'));
const config = new cic.Config('./config');
config.process();
console.log(config);
function sendit(uid, envelope) {
const d = envelope.toJSON();
const contentLength = (new TextEncoder().encode(d)).length;
const opts = {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Content-Length': contentLength,
'X-CIC-AUTOMERGE': 'client',
},
};
let url = config.get('META_URL');
url = url.replace(new RegExp('^(.+://[^/]+)/*$'), '$1/');
console.log('posting to url: ' + url + uid);
const req = http.request(url + uid, opts, (res) => {
res.on('data', process.stdout.write);
res.on('end', () => {
console.log('result', res.statusCode, res.headers);
});
});
if (!req.write(d)) {
console.error('foo', d);
process.exit(1);
}
req.end();
}
function doOne(keystore, filePath, identifier) {
const signer = new cic.PGPSigner(keystore);
const o = JSON.parse(fs.readFileSync(filePath).toString());
//const b = Buffer.from(j['vcard'], 'base64');
//const s = b.toString();
//const o = vcfp.parse(s);
//const phone = o.tel[0].value;
//cic.Phone.toKey(phone).then((uid) => {
//const o = fs.readFileSync(filePath, 'utf-8');
const s = new cic.Syncable(identifier, o);
s.setSigner(signer);
s.onwrap = (env) => {
sendit(identifier, env);
};
s.sign();
//});
}
const privateKeyPath = path.join(config.get('PGP_EXPORTS_DIR'), config.get('PGP_PRIVATE_KEY_FILE'));
const publicKeyPath = path.join(config.get('PGP_EXPORTS_DIR'), config.get('PGP_PRIVATE_KEY_FILE'));
pk = fs.readFileSync(privateKeyPath);
pubk = fs.readFileSync(publicKeyPath);
new cic.PGPKeyStore(
config.get('PGP_PASSPHRASE'),
pk,
pubk,
undefined,
undefined,
importMetaCustom,
);
const batchSize = 16;
const batchDelay = 1000;
const total = parseInt(process.argv[3]);
const dataDir = process.argv[2];
const workDir = path.join(dataDir, 'custom/meta');
const userDir = path.join(dataDir, 'custom/new');
let count = 0;
let batchCount = 0;
function importMetaCustom(keystore) {
let err;
let files;
try {
err, files = fs.readdirSync(workDir);
} catch {
console.error('source directory not yet ready', workDir);
setTimeout(importMetaPhone, batchDelay, keystore);
return;
}
let limit = batchSize;
if (files.length < limit) {
limit = files.length;
}
for (let i = 0; i < limit; i++) {
const file = files[i];
if (file.length < 3) {
console.debug('skipping file', file);
continue;
}
//const identifier = file.substr(0,file.length-5);
const identifier = file;
const filePath = path.join(workDir, file);
console.log(filePath);
//const address = fs.readFileSync(filePath).toString().substring(2).toUpperCase();
const custom = JSON.parse(fs.readFileSync(filePath).toString());
const customFilePath = path.join(
userDir,
identifier.substring(0, 2),
identifier.substring(2, 4),
identifier + '.json',
);
doOne(keystore, filePath, identifier);
fs.unlinkSync(filePath);
count++;
batchCount++;
if (batchCount == batchSize) {
console.debug('reached batch size, breathing');
batchCount=0;
setTimeout(importMeta, batchDelay, keystore);
return;
}
}
if (count == total) {
return;
}
setTimeout(importMetaCustom, 100, keystore);
}

View File

@@ -37,6 +37,7 @@ config_dir = os.environ.get('CONFINI_DIR', os.path.join(script_dir, 'config'))
argparser = argparse.ArgumentParser() argparser = argparse.ArgumentParser()
argparser.add_argument('-c', type=str, default=config_dir, help='Config dir') argparser.add_argument('-c', type=str, default=config_dir, help='Config dir')
argparser.add_argument('--tag', type=str, action='append', help='Tags to add to record')
argparser.add_argument('--gift-threshold', type=int, help='If set, users will be funded with additional random balance (in token integer units)') argparser.add_argument('--gift-threshold', type=int, help='If set, users will be funded with additional random balance (in token integer units)')
argparser.add_argument('-v', action='store_true', help='Be verbose') argparser.add_argument('-v', action='store_true', help='Be verbose')
argparser.add_argument('-vv', action='store_true', help='Be more verbose') argparser.add_argument('-vv', action='store_true', help='Be more verbose')
@@ -81,6 +82,10 @@ phone_idx = []
user_dir = args.dir user_dir = args.dir
user_count = args.user_count user_count = args.user_count
tags = args.tag
if tags == None or len(tags) == 0:
tags = ['individual']
random.seed() random.seed()
def genPhoneIndex(phone): def genPhoneIndex(phone):
@@ -189,6 +194,7 @@ if __name__ == '__main__':
os.makedirs(base_dir, exist_ok=True) os.makedirs(base_dir, exist_ok=True)
fa = open(os.path.join(user_dir, 'balances.csv'), 'w') fa = open(os.path.join(user_dir, 'balances.csv'), 'w')
ft = open(os.path.join(user_dir, 'tags.csv'), 'w')
i = 0 i = 0
while i < user_count: while i < user_count:
@@ -215,10 +221,12 @@ if __name__ == '__main__':
f.write(eth) f.write(eth)
f.close() f.close()
ft.write('{}:{}\n'.format(eth, ','.join(tags)))
amount = genAmount() amount = genAmount()
fa.write('{},{}\n'.format(eth,amount)) fa.write('{},{}\n'.format(eth,amount))
logg.debug('pidx {}, uid {}, eth {}, amount {}, phone {}'.format(pidx, uid, eth, amount, phone)) logg.debug('pidx {}, uid {}, eth {}, amount {}, phone {}'.format(pidx, uid, eth, amount, phone))
i += 1 i += 1
ft.close()
fa.close() fa.close()

View File

@@ -24,7 +24,7 @@ from chainlib.eth.gas import RPCGasOracle
from chainlib.eth.nonce import RPCNonceOracle from chainlib.eth.nonce import RPCNonceOracle
from cic_types.processor import generate_metadata_pointer from cic_types.processor import generate_metadata_pointer
from eth_accounts_index import AccountRegistry from eth_accounts_index import AccountRegistry
from contract_registry import Registry from eth_contract_registry import Registry
from crypto_dev_signer.keystore.dict import DictKeystore from crypto_dev_signer.keystore.dict import DictKeystore
from crypto_dev_signer.eth.signer.defaultsigner import ReferenceSigner as EIP155Signer from crypto_dev_signer.eth.signer.defaultsigner import ReferenceSigner as EIP155Signer
from crypto_dev_signer.keystore.keyfile import to_dict as to_keyfile_dict from crypto_dev_signer.keystore.keyfile import to_dict as to_keyfile_dict
@@ -38,6 +38,7 @@ argparser = argparse.ArgumentParser()
argparser.add_argument('-p', '--provider', dest='p', default='http://localhost:8545', type=str, help='Web3 provider url (http only)') argparser.add_argument('-p', '--provider', dest='p', default='http://localhost:8545', type=str, help='Web3 provider url (http only)')
argparser.add_argument('-y', '--key-file', dest='y', type=str, help='Ethereum keystore file to use for signing') argparser.add_argument('-y', '--key-file', dest='y', type=str, help='Ethereum keystore file to use for signing')
argparser.add_argument('-c', type=str, default=default_config_dir, help='config file') argparser.add_argument('-c', type=str, default=default_config_dir, help='config file')
argparser.add_argument('--old-chain-spec', type=str, dest='old_chain_spec', default='evm:oldchain:1', help='chain spec')
argparser.add_argument('-i', '--chain-spec', dest='i', type=str, help='Chain specification string') argparser.add_argument('-i', '--chain-spec', dest='i', type=str, help='Chain specification string')
argparser.add_argument('-r', '--registry', dest='r', type=str, help='Contract registry address') argparser.add_argument('-r', '--registry', dest='r', type=str, help='Contract registry address')
argparser.add_argument('--batch-size', dest='batch_size', default=50, type=int, help='burst size of sending transactions to node') argparser.add_argument('--batch-size', dest='batch_size', default=50, type=int, help='burst size of sending transactions to node')
@@ -68,6 +69,11 @@ os.makedirs(user_new_dir)
meta_dir = os.path.join(args.user_dir, 'meta') meta_dir = os.path.join(args.user_dir, 'meta')
os.makedirs(meta_dir) os.makedirs(meta_dir)
custom_dir = os.path.join(args.user_dir, 'custom')
os.makedirs(custom_dir)
os.makedirs(os.path.join(custom_dir, 'new'))
os.makedirs(os.path.join(custom_dir, 'meta'))
phone_dir = os.path.join(args.user_dir, 'phone') phone_dir = os.path.join(args.user_dir, 'phone')
os.makedirs(os.path.join(phone_dir, 'meta')) os.makedirs(os.path.join(phone_dir, 'meta'))
@@ -77,9 +83,14 @@ os.stat(user_old_dir)
txs_dir = os.path.join(args.user_dir, 'txs') txs_dir = os.path.join(args.user_dir, 'txs')
os.makedirs(txs_dir) os.makedirs(txs_dir)
user_dir = args.user_dir
chain_spec = ChainSpec.from_chain_str(config.get('CIC_CHAIN_SPEC')) chain_spec = ChainSpec.from_chain_str(config.get('CIC_CHAIN_SPEC'))
chain_str = str(chain_spec) chain_str = str(chain_spec)
old_chain_spec = ChainSpec.from_chain_str(args.old_chain_spec)
old_chain_str = str(old_chain_spec)
batch_size = args.batch_size batch_size = args.batch_size
batch_delay = args.batch_delay batch_delay = args.batch_delay
@@ -127,12 +138,18 @@ def register_eth(i, u):
return address return address
def register_ussd(u):
pass
if __name__ == '__main__': if __name__ == '__main__':
user_tags = {}
f = open(os.path.join(user_dir, 'tags.csv'), 'r')
while True:
r = f.readline().rstrip()
if len(r) == 0:
break
(old_address, tags_csv) = r.split(':')
old_address = strip_0x(old_address)
user_tags[old_address] = tags_csv.split(',')
logg.debug('read tags {} for old address {}'.format(user_tags[old_address], old_address))
i = 0 i = 0
j = 0 j = 0
@@ -150,6 +167,7 @@ if __name__ == '__main__':
continue continue
f.close() f.close()
u = Person.deserialize(o) u = Person.deserialize(o)
logg.debug('u {}'.format(o))
new_address = register_eth(i, u) new_address = register_eth(i, u)
if u.identities.get('evm') == None: if u.identities.get('evm') == None:
@@ -157,8 +175,6 @@ if __name__ == '__main__':
sub_chain_str = '{}:{}'.format(chain_spec.common_name(), chain_spec.network_id()) sub_chain_str = '{}:{}'.format(chain_spec.common_name(), chain_spec.network_id())
u.identities['evm'][sub_chain_str] = [new_address] u.identities['evm'][sub_chain_str] = [new_address]
register_ussd(u)
new_address_clean = strip_0x(new_address) new_address_clean = strip_0x(new_address)
filepath = os.path.join( filepath = os.path.join(
user_new_dir, user_new_dir,
@@ -198,6 +214,29 @@ if __name__ == '__main__':
os.symlink(os.path.realpath(filepath), meta_phone_filepath) os.symlink(os.path.realpath(filepath), meta_phone_filepath)
# custom data
custom_key = generate_metadata_pointer(phone.encode('utf-8'), ':cic.custom')
custom_filepath = os.path.join(custom_dir, 'meta', custom_key)
filepath = os.path.join(
custom_dir,
'new',
custom_key[:2].upper(),
custom_key[2:4].upper(),
custom_key.upper() + '.json',
)
os.makedirs(os.path.dirname(filepath), exist_ok=True)
sub_old_chain_str = '{}:{}'.format(old_chain_spec.common_name(), old_chain_spec.network_id())
f = open(filepath, 'w')
k = u.identities['evm'][sub_old_chain_str][0]
tag_data = {'tags': user_tags[strip_0x(k)]}
f.write(json.dumps(tag_data))
f.close()
os.symlink(os.path.realpath(filepath), custom_filepath)
i += 1 i += 1
sys.stdout.write('imported {} {}'.format(i, u).ljust(200) + "\r") sys.stdout.write('imported {} {}'.format(i, u).ljust(200) + "\r")

View File

@@ -5,39 +5,40 @@
"packages": { "packages": {
"": { "": {
"dependencies": { "dependencies": {
"cic-client-meta": "^0.0.7-alpha.5", "cic-client-meta": "0.0.7-alpha.6",
"vcard-parser": "^1.0.0" "vcard-parser": "^1.0.0"
} }
}, },
"node_modules/@ethereumjs/common": { "node_modules/@ethereumjs/common": {
"version": "2.0.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.0.0.tgz", "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.2.0.tgz",
"integrity": "sha512-yL0zA7Xwgz8IFHKW0VoXGjdZDVxUJg8BQ/muMHvYPW7zHJNNC80gQmvLH+MpvIg1TCXZkFXxrpYRAyCElSm+aw==", "integrity": "sha512-PyQiTG00MJtBRkJmv46ChZL8u2XWxNBeAthznAUIUiefxPAXjbkuiCZOuncgJS34/XkMbNc9zMt/PlgKRBElig==",
"dependencies": { "dependencies": {
"crc-32": "^1.2.0" "crc-32": "^1.2.0",
"ethereumjs-util": "^7.0.9"
} }
}, },
"node_modules/@ethereumjs/tx": { "node_modules/@ethereumjs/tx": {
"version": "3.0.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.0.2.tgz", "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.1.3.tgz",
"integrity": "sha512-zmFCosjOdj1WoYEiQBdC4sCOAllBEwxdKuY85L9FgZ4zVDfZUVsQ4S9paczt4hVt65A7N8sJwgVEzDaQmrRaqw==", "integrity": "sha512-DJBu6cbwYtiPTFeCUR8DF5p+PF0jxs+0rALJZiEcTz2tiRPIEkM72GEbrkGuqzENLCzBrJHT43O0DxSYTqeo+g==",
"dependencies": { "dependencies": {
"@ethereumjs/common": "^2.0.0", "@ethereumjs/common": "^2.2.0",
"ethereumjs-util": "^7.0.8" "ethereumjs-util": "^7.0.10"
} }
}, },
"node_modules/@types/bn.js": { "node_modules/@types/bn.js": {
"version": "4.11.6", "version": "5.1.0",
"resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz",
"integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==",
"dependencies": { "dependencies": {
"@types/node": "*" "@types/node": "*"
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "14.14.30", "version": "14.14.41",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.30.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.41.tgz",
"integrity": "sha512-gUWhy8s45fQp4PqqKecsnOkdW0kt1IaKjgOIR3HPokkzTmQj9ji2wWFID5THu1MKrtO+d4s2lVrlEhXUsPXSvg==" "integrity": "sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g=="
}, },
"node_modules/@types/pbkdf2": { "node_modules/@types/pbkdf2": {
"version": "3.1.0", "version": "3.1.0",
@@ -48,9 +49,9 @@
} }
}, },
"node_modules/@types/secp256k1": { "node_modules/@types/secp256k1": {
"version": "4.0.1", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.1.tgz", "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.2.tgz",
"integrity": "sha512-+ZjSA8ELlOp8SlKi0YLB2tz9d5iPNEmOBd+8Rz21wTMdaXQIa9b6TEnD6l5qKOCypE7FSyPyck12qZJxSDNoog==", "integrity": "sha512-QMg+9v0bbNJ2peLuHRWxzmy0HRJIG6gFZNhaRSp7S3ggSbCCxiqQB2/ybvhXyhHOCequpNkrx7OavNhrWOsW0A==",
"dependencies": { "dependencies": {
"@types/node": "*" "@types/node": "*"
} }
@@ -158,9 +159,9 @@
} }
}, },
"node_modules/asn1.js/node_modules/bn.js": { "node_modules/asn1.js/node_modules/bn.js": {
"version": "4.11.9", "version": "4.12.0",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
}, },
"node_modules/assert-plus": { "node_modules/assert-plus": {
"version": "1.0.0", "version": "1.0.0",
@@ -204,9 +205,9 @@
"optional": true "optional": true
}, },
"node_modules/balanced-match": { "node_modules/balanced-match": {
"version": "1.0.0", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
}, },
"node_modules/base-x": { "node_modules/base-x": {
"version": "3.0.8", "version": "3.0.8",
@@ -243,9 +244,9 @@
} }
}, },
"node_modules/bn.js": { "node_modules/bn.js": {
"version": "5.1.3", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
"integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==" "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
}, },
"node_modules/brace-expansion": { "node_modules/brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
@@ -317,9 +318,9 @@
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
}, },
"node_modules/cic-client-meta": { "node_modules/cic-client-meta": {
"version": "0.0.7-alpha.5", "version": "0.0.7-alpha.6",
"resolved": "https://registry.npmjs.org/cic-client-meta/-/cic-client-meta-0.0.7-alpha.5.tgz", "resolved": "https://registry.npmjs.org/cic-client-meta/-/cic-client-meta-0.0.7-alpha.6.tgz",
"integrity": "sha512-h+0wmAKZIgezppBNYDmG387w6tI91FSWqONMTZbMuaO1Ej76Gg0Mk2UcDyAF/dmY6doXz3kHAbWkWat7mTzXAQ==", "integrity": "sha512-oIN1aHkPHfsxJKDV6k4f1kX2tcppw3Q+D1b4BoPh0hYjNKNb7gImBMWnGsy8uiD9W6SNYE4sIXyrtct8mvrhsw==",
"dependencies": { "dependencies": {
"@ethereumjs/tx": "^3.0.0-beta.1", "@ethereumjs/tx": "^3.0.0-beta.1",
"automerge": "^0.14.1", "automerge": "^0.14.1",
@@ -331,7 +332,7 @@
"yargs": "^16.1.0" "yargs": "^16.1.0"
}, },
"engines": { "engines": {
"node": "~15.3.0" "node": "~14.16.1"
} }
}, },
"node_modules/cipher-base": { "node_modules/cipher-base": {
@@ -370,9 +371,9 @@
} }
}, },
"node_modules/cliui/node_modules/string-width": { "node_modules/cliui/node_modules/string-width": {
"version": "4.2.0", "version": "4.2.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
"dependencies": { "dependencies": {
"emoji-regex": "^8.0.0", "emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0", "is-fullwidth-code-point": "^3.0.0",
@@ -562,9 +563,9 @@
} }
}, },
"node_modules/elliptic/node_modules/bn.js": { "node_modules/elliptic/node_modules/bn.js": {
"version": "4.11.9", "version": "4.12.0",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
}, },
"node_modules/emoji-regex": { "node_modules/emoji-regex": {
"version": "8.0.0", "version": "8.0.0",
@@ -602,11 +603,11 @@
} }
}, },
"node_modules/ethereumjs-util": { "node_modules/ethereumjs-util": {
"version": "7.0.8", "version": "7.0.10",
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.0.8.tgz", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.0.10.tgz",
"integrity": "sha512-JJt7tDpCAmDPw/sGoFYeq0guOVqT3pTE9xlEbBmc/nlCij3JRCoS2c96SQ6kXVHOT3xWUNLDm5QCJLQaUnVAtQ==", "integrity": "sha512-c/xThw6A+EAnej5Xk5kOzFzyoSnw0WX0tSlZ6pAsfGVvQj3TItaDg9b1+Fz1RJXA+y2YksKwQnuzgt1eY6LKzw==",
"dependencies": { "dependencies": {
"@types/bn.js": "^4.11.3", "@types/bn.js": "^5.1.0",
"bn.js": "^5.1.2", "bn.js": "^5.1.2",
"create-hash": "^1.1.2", "create-hash": "^1.1.2",
"ethereum-cryptography": "^0.1.3", "ethereum-cryptography": "^0.1.3",
@@ -1026,21 +1027,21 @@
} }
}, },
"node_modules/mime-db": { "node_modules/mime-db": {
"version": "1.46.0", "version": "1.47.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz",
"integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==", "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==",
"optional": true, "optional": true,
"engines": { "engines": {
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/mime-types": { "node_modules/mime-types": {
"version": "2.1.29", "version": "2.1.30",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz",
"integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==", "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==",
"optional": true, "optional": true,
"dependencies": { "dependencies": {
"mime-db": "1.46.0" "mime-db": "1.47.0"
}, },
"engines": { "engines": {
"node": ">= 0.6" "node": ">= 0.6"
@@ -1361,9 +1362,9 @@
} }
}, },
"node_modules/pbkdf2": { "node_modules/pbkdf2": {
"version": "3.1.1", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
"integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
"dependencies": { "dependencies": {
"create-hash": "^1.1.2", "create-hash": "^1.1.2",
"create-hmac": "^1.1.4", "create-hmac": "^1.1.4",
@@ -1382,15 +1383,15 @@
"optional": true "optional": true
}, },
"node_modules/pg": { "node_modules/pg": {
"version": "8.5.1", "version": "8.6.0",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.5.1.tgz", "resolved": "https://registry.npmjs.org/pg/-/pg-8.6.0.tgz",
"integrity": "sha512-9wm3yX9lCfjvA98ybCyw2pADUivyNWT/yIP4ZcDVpMN0og70BUWYEGXPCTAQdGTAqnytfRADb7NERrY1qxhIqw==", "integrity": "sha512-qNS9u61lqljTDFvmk/N66EeGq3n6Ujzj0FFyNMGQr6XuEv4tgNTXvJQTfJdcvGit5p5/DWPu+wj920hAJFI+QQ==",
"dependencies": { "dependencies": {
"buffer-writer": "2.0.0", "buffer-writer": "2.0.0",
"packet-reader": "1.0.0", "packet-reader": "1.0.0",
"pg-connection-string": "^2.4.0", "pg-connection-string": "^2.5.0",
"pg-pool": "^3.2.2", "pg-pool": "^3.3.0",
"pg-protocol": "^1.4.0", "pg-protocol": "^1.5.0",
"pg-types": "^2.1.0", "pg-types": "^2.1.0",
"pgpass": "1.x" "pgpass": "1.x"
}, },
@@ -1399,9 +1400,9 @@
} }
}, },
"node_modules/pg-connection-string": { "node_modules/pg-connection-string": {
"version": "2.4.0", "version": "2.5.0",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.4.0.tgz", "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz",
"integrity": "sha512-3iBXuv7XKvxeMrIgym7njT+HlZkwZqqGX4Bu9cci8xHZNT+Um1gWKqCsAzcC0d95rcKMU5WBg6YRUcHyV0HZKQ==" "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ=="
}, },
"node_modules/pg-int8": { "node_modules/pg-int8": {
"version": "1.0.1", "version": "1.0.1",
@@ -1412,14 +1413,14 @@
} }
}, },
"node_modules/pg-pool": { "node_modules/pg-pool": {
"version": "3.2.2", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.2.tgz", "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.3.0.tgz",
"integrity": "sha512-ORJoFxAlmmros8igi608iVEbQNNZlp89diFVx6yV5v+ehmpMY9sK6QgpmgoXbmkNaBAx8cOOZh9g80kJv1ooyA==" "integrity": "sha512-0O5huCql8/D6PIRFAlmccjphLYWC+JIzvUhSzXSpGaf+tjTZc4nn+Lr7mLXBbFJfvwbP0ywDv73EiaBsxn7zdg=="
}, },
"node_modules/pg-protocol": { "node_modules/pg-protocol": {
"version": "1.4.0", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.4.0.tgz", "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz",
"integrity": "sha512-El+aXWcwG/8wuFICMQjM5ZSAm6OWiJicFdNYo+VY3QP+8vI4SvLIWVe51PppTzMhikUJR+PsyIFKqfdXPz/yxA==" "integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ=="
}, },
"node_modules/pg-types": { "node_modules/pg-types": {
"version": "2.2.0", "version": "2.2.0",
@@ -1625,9 +1626,9 @@
} }
}, },
"node_modules/rlp/node_modules/bn.js": { "node_modules/rlp/node_modules/bn.js": {
"version": "4.11.9", "version": "4.12.0",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
}, },
"node_modules/safe-buffer": { "node_modules/safe-buffer": {
"version": "5.2.1", "version": "5.2.1",
@@ -1958,9 +1959,9 @@
} }
}, },
"node_modules/wrap-ansi/node_modules/string-width": { "node_modules/wrap-ansi/node_modules/string-width": {
"version": "4.2.0", "version": "4.2.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
"dependencies": { "dependencies": {
"emoji-regex": "^8.0.0", "emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0", "is-fullwidth-code-point": "^3.0.0",
@@ -2005,9 +2006,9 @@
} }
}, },
"node_modules/y18n": { "node_modules/y18n": {
"version": "5.0.5", "version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"engines": { "engines": {
"node": ">=10" "node": ">=10"
} }
@@ -2035,9 +2036,9 @@
} }
}, },
"node_modules/yargs-parser": { "node_modules/yargs-parser": {
"version": "20.2.5", "version": "20.2.7",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.5.tgz", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz",
"integrity": "sha512-jYRGS3zWy20NtDtK2kBgo/TlAoy5YUuhD9/LZ7z7W4j1Fdw2cqD0xEEclf8fxc8xjD6X5Qr+qQQwCEsP8iRiYg==", "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==",
"engines": { "engines": {
"node": ">=10" "node": ">=10"
} }
@@ -2059,9 +2060,9 @@
} }
}, },
"node_modules/yargs/node_modules/string-width": { "node_modules/yargs/node_modules/string-width": {
"version": "4.2.0", "version": "4.2.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
"dependencies": { "dependencies": {
"emoji-regex": "^8.0.0", "emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0", "is-fullwidth-code-point": "^3.0.0",
@@ -2085,34 +2086,35 @@
}, },
"dependencies": { "dependencies": {
"@ethereumjs/common": { "@ethereumjs/common": {
"version": "2.0.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.0.0.tgz", "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.2.0.tgz",
"integrity": "sha512-yL0zA7Xwgz8IFHKW0VoXGjdZDVxUJg8BQ/muMHvYPW7zHJNNC80gQmvLH+MpvIg1TCXZkFXxrpYRAyCElSm+aw==", "integrity": "sha512-PyQiTG00MJtBRkJmv46ChZL8u2XWxNBeAthznAUIUiefxPAXjbkuiCZOuncgJS34/XkMbNc9zMt/PlgKRBElig==",
"requires": { "requires": {
"crc-32": "^1.2.0" "crc-32": "^1.2.0",
"ethereumjs-util": "^7.0.9"
} }
}, },
"@ethereumjs/tx": { "@ethereumjs/tx": {
"version": "3.0.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.0.2.tgz", "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.1.3.tgz",
"integrity": "sha512-zmFCosjOdj1WoYEiQBdC4sCOAllBEwxdKuY85L9FgZ4zVDfZUVsQ4S9paczt4hVt65A7N8sJwgVEzDaQmrRaqw==", "integrity": "sha512-DJBu6cbwYtiPTFeCUR8DF5p+PF0jxs+0rALJZiEcTz2tiRPIEkM72GEbrkGuqzENLCzBrJHT43O0DxSYTqeo+g==",
"requires": { "requires": {
"@ethereumjs/common": "^2.0.0", "@ethereumjs/common": "^2.2.0",
"ethereumjs-util": "^7.0.8" "ethereumjs-util": "^7.0.10"
} }
}, },
"@types/bn.js": { "@types/bn.js": {
"version": "4.11.6", "version": "5.1.0",
"resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz",
"integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==",
"requires": { "requires": {
"@types/node": "*" "@types/node": "*"
} }
}, },
"@types/node": { "@types/node": {
"version": "14.14.30", "version": "14.14.41",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.30.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.41.tgz",
"integrity": "sha512-gUWhy8s45fQp4PqqKecsnOkdW0kt1IaKjgOIR3HPokkzTmQj9ji2wWFID5THu1MKrtO+d4s2lVrlEhXUsPXSvg==" "integrity": "sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g=="
}, },
"@types/pbkdf2": { "@types/pbkdf2": {
"version": "3.1.0", "version": "3.1.0",
@@ -2123,9 +2125,9 @@
} }
}, },
"@types/secp256k1": { "@types/secp256k1": {
"version": "4.0.1", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.1.tgz", "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.2.tgz",
"integrity": "sha512-+ZjSA8ELlOp8SlKi0YLB2tz9d5iPNEmOBd+8Rz21wTMdaXQIa9b6TEnD6l5qKOCypE7FSyPyck12qZJxSDNoog==", "integrity": "sha512-QMg+9v0bbNJ2peLuHRWxzmy0HRJIG6gFZNhaRSp7S3ggSbCCxiqQB2/ybvhXyhHOCequpNkrx7OavNhrWOsW0A==",
"requires": { "requires": {
"@types/node": "*" "@types/node": "*"
} }
@@ -2229,9 +2231,9 @@
}, },
"dependencies": { "dependencies": {
"bn.js": { "bn.js": {
"version": "4.11.9", "version": "4.12.0",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
} }
} }
}, },
@@ -2271,9 +2273,9 @@
"optional": true "optional": true
}, },
"balanced-match": { "balanced-match": {
"version": "1.0.0", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
}, },
"base-x": { "base-x": {
"version": "3.0.8", "version": "3.0.8",
@@ -2307,9 +2309,9 @@
} }
}, },
"bn.js": { "bn.js": {
"version": "5.1.3", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
"integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==" "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw=="
}, },
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
@@ -2378,9 +2380,9 @@
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
}, },
"cic-client-meta": { "cic-client-meta": {
"version": "0.0.7-alpha.5", "version": "0.0.7-alpha.6",
"resolved": "https://registry.npmjs.org/cic-client-meta/-/cic-client-meta-0.0.7-alpha.5.tgz", "resolved": "https://registry.npmjs.org/cic-client-meta/-/cic-client-meta-0.0.7-alpha.6.tgz",
"integrity": "sha512-h+0wmAKZIgezppBNYDmG387w6tI91FSWqONMTZbMuaO1Ej76Gg0Mk2UcDyAF/dmY6doXz3kHAbWkWat7mTzXAQ==", "integrity": "sha512-oIN1aHkPHfsxJKDV6k4f1kX2tcppw3Q+D1b4BoPh0hYjNKNb7gImBMWnGsy8uiD9W6SNYE4sIXyrtct8mvrhsw==",
"requires": { "requires": {
"@ethereumjs/tx": "^3.0.0-beta.1", "@ethereumjs/tx": "^3.0.0-beta.1",
"automerge": "^0.14.1", "automerge": "^0.14.1",
@@ -2422,9 +2424,9 @@
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
}, },
"string-width": { "string-width": {
"version": "4.2.0", "version": "4.2.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
"requires": { "requires": {
"emoji-regex": "^8.0.0", "emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0", "is-fullwidth-code-point": "^3.0.0",
@@ -2580,9 +2582,9 @@
}, },
"dependencies": { "dependencies": {
"bn.js": { "bn.js": {
"version": "4.11.9", "version": "4.12.0",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
} }
} }
}, },
@@ -2619,11 +2621,11 @@
} }
}, },
"ethereumjs-util": { "ethereumjs-util": {
"version": "7.0.8", "version": "7.0.10",
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.0.8.tgz", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.0.10.tgz",
"integrity": "sha512-JJt7tDpCAmDPw/sGoFYeq0guOVqT3pTE9xlEbBmc/nlCij3JRCoS2c96SQ6kXVHOT3xWUNLDm5QCJLQaUnVAtQ==", "integrity": "sha512-c/xThw6A+EAnej5Xk5kOzFzyoSnw0WX0tSlZ6pAsfGVvQj3TItaDg9b1+Fz1RJXA+y2YksKwQnuzgt1eY6LKzw==",
"requires": { "requires": {
"@types/bn.js": "^4.11.3", "@types/bn.js": "^5.1.0",
"bn.js": "^5.1.2", "bn.js": "^5.1.2",
"create-hash": "^1.1.2", "create-hash": "^1.1.2",
"ethereum-cryptography": "^0.1.3", "ethereum-cryptography": "^0.1.3",
@@ -2980,18 +2982,18 @@
} }
}, },
"mime-db": { "mime-db": {
"version": "1.46.0", "version": "1.47.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz",
"integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==", "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==",
"optional": true "optional": true
}, },
"mime-types": { "mime-types": {
"version": "2.1.29", "version": "2.1.30",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz",
"integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==", "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==",
"optional": true, "optional": true,
"requires": { "requires": {
"mime-db": "1.46.0" "mime-db": "1.47.0"
} }
}, },
"minimalistic-assert": { "minimalistic-assert": {
@@ -3249,9 +3251,9 @@
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
}, },
"pbkdf2": { "pbkdf2": {
"version": "3.1.1", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
"integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
"requires": { "requires": {
"create-hash": "^1.1.2", "create-hash": "^1.1.2",
"create-hmac": "^1.1.4", "create-hmac": "^1.1.4",
@@ -3267,23 +3269,23 @@
"optional": true "optional": true
}, },
"pg": { "pg": {
"version": "8.5.1", "version": "8.6.0",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.5.1.tgz", "resolved": "https://registry.npmjs.org/pg/-/pg-8.6.0.tgz",
"integrity": "sha512-9wm3yX9lCfjvA98ybCyw2pADUivyNWT/yIP4ZcDVpMN0og70BUWYEGXPCTAQdGTAqnytfRADb7NERrY1qxhIqw==", "integrity": "sha512-qNS9u61lqljTDFvmk/N66EeGq3n6Ujzj0FFyNMGQr6XuEv4tgNTXvJQTfJdcvGit5p5/DWPu+wj920hAJFI+QQ==",
"requires": { "requires": {
"buffer-writer": "2.0.0", "buffer-writer": "2.0.0",
"packet-reader": "1.0.0", "packet-reader": "1.0.0",
"pg-connection-string": "^2.4.0", "pg-connection-string": "^2.5.0",
"pg-pool": "^3.2.2", "pg-pool": "^3.3.0",
"pg-protocol": "^1.4.0", "pg-protocol": "^1.5.0",
"pg-types": "^2.1.0", "pg-types": "^2.1.0",
"pgpass": "1.x" "pgpass": "1.x"
} }
}, },
"pg-connection-string": { "pg-connection-string": {
"version": "2.4.0", "version": "2.5.0",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.4.0.tgz", "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz",
"integrity": "sha512-3iBXuv7XKvxeMrIgym7njT+HlZkwZqqGX4Bu9cci8xHZNT+Um1gWKqCsAzcC0d95rcKMU5WBg6YRUcHyV0HZKQ==" "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ=="
}, },
"pg-int8": { "pg-int8": {
"version": "1.0.1", "version": "1.0.1",
@@ -3291,14 +3293,14 @@
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="
}, },
"pg-pool": { "pg-pool": {
"version": "3.2.2", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.2.tgz", "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.3.0.tgz",
"integrity": "sha512-ORJoFxAlmmros8igi608iVEbQNNZlp89diFVx6yV5v+ehmpMY9sK6QgpmgoXbmkNaBAx8cOOZh9g80kJv1ooyA==" "integrity": "sha512-0O5huCql8/D6PIRFAlmccjphLYWC+JIzvUhSzXSpGaf+tjTZc4nn+Lr7mLXBbFJfvwbP0ywDv73EiaBsxn7zdg=="
}, },
"pg-protocol": { "pg-protocol": {
"version": "1.4.0", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.4.0.tgz", "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz",
"integrity": "sha512-El+aXWcwG/8wuFICMQjM5ZSAm6OWiJicFdNYo+VY3QP+8vI4SvLIWVe51PppTzMhikUJR+PsyIFKqfdXPz/yxA==" "integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ=="
}, },
"pg-types": { "pg-types": {
"version": "2.2.0", "version": "2.2.0",
@@ -3459,9 +3461,9 @@
}, },
"dependencies": { "dependencies": {
"bn.js": { "bn.js": {
"version": "4.11.9", "version": "4.12.0",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
} }
} }
}, },
@@ -3734,9 +3736,9 @@
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
}, },
"string-width": { "string-width": {
"version": "4.2.0", "version": "4.2.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
"requires": { "requires": {
"emoji-regex": "^8.0.0", "emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0", "is-fullwidth-code-point": "^3.0.0",
@@ -3774,9 +3776,9 @@
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
}, },
"y18n": { "y18n": {
"version": "5.0.5", "version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==" "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="
}, },
"yallist": { "yallist": {
"version": "3.1.1", "version": "3.1.1",
@@ -3808,9 +3810,9 @@
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
}, },
"string-width": { "string-width": {
"version": "4.2.0", "version": "4.2.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
"requires": { "requires": {
"emoji-regex": "^8.0.0", "emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0", "is-fullwidth-code-point": "^3.0.0",
@@ -3828,9 +3830,9 @@
} }
}, },
"yargs-parser": { "yargs-parser": {
"version": "20.2.5", "version": "20.2.7",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.5.tgz", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz",
"integrity": "sha512-jYRGS3zWy20NtDtK2kBgo/TlAoy5YUuhD9/LZ7z7W4j1Fdw2cqD0xEEclf8fxc8xjD6X5Qr+qQQwCEsP8iRiYg==" "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw=="
} }
} }
} }

View File

@@ -1,6 +1,6 @@
{ {
"dependencies": { "dependencies": {
"cic-client-meta": "^0.0.7-alpha.6", "cic-client-meta": "0.0.7-alpha.6",
"vcard-parser": "^1.0.0" "vcard-parser": "^1.0.0"
} }
} }

View File

@@ -22,7 +22,7 @@ from hexathon import (
strip_0x, strip_0x,
add_0x, add_0x,
) )
from chainsyncer.backend import MemBackend from chainsyncer.backend.memory import MemBackend
from chainsyncer.driver import HeadSyncer from chainsyncer.driver import HeadSyncer
from chainlib.chain import ChainSpec from chainlib.chain import ChainSpec
from chainlib.eth.connection import EthHTTPConnection from chainlib.eth.connection import EthHTTPConnection

View File

@@ -13,6 +13,12 @@ DEV_PIP_EXTRA_INDEX_URL=${DEV_PIP_EXTRA_INDEX_URL:-https://pip.grassrootseconomi
DEV_DATABASE_NAME_CIC_ETH=${DEV_DATABASE_NAME_CIC_ETH:-"cic-eth"} DEV_DATABASE_NAME_CIC_ETH=${DEV_DATABASE_NAME_CIC_ETH:-"cic-eth"}
CIC_DATA_DIR=${CIC_DATA_DIR:-/tmp/cic} CIC_DATA_DIR=${CIC_DATA_DIR:-/tmp/cic}
ETH_PASSPHRASE='' ETH_PASSPHRASE=''
DEV_TOKEN_TYPE=${DEV_TOKEN_TYPE:-giftable}
if [ $DEV_TOKEN_TYPE = 'giftable' ]; then
token_symbol='GFT'
else
token_symbol='SRF'
fi
# Debug flag # Debug flag
DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER=0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C DEV_ETH_ACCOUNT_CONTRACT_DEPLOYER=0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C
@@ -33,11 +39,11 @@ set -a
# get required addresses from registries # get required addresses from registries
DEV_TOKEN_INDEX_ADDRESS=`eth-contract-registry-list -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -r $CIC_REGISTRY_ADDRESS -f brief TokenRegistry` DEV_TOKEN_INDEX_ADDRESS=`eth-contract-registry-list -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -r $CIC_REGISTRY_ADDRESS -f brief TokenRegistry`
DEV_ACCOUNT_INDEX_ADDRESS=`eth-contract-registry-list -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -r $CIC_REGISTRY_ADDRESS -f brief AccountRegistry` DEV_ACCOUNT_INDEX_ADDRESS=`eth-contract-registry-list -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -r $CIC_REGISTRY_ADDRESS -f brief AccountRegistry`
DEV_RESERVE_ADDRESS=`eth-token-index-list -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -a $DEV_TOKEN_INDEX_ADDRESS -f brief SRF` DEV_RESERVE_ADDRESS=`eth-token-index-list -i $CIC_CHAIN_SPEC -p $ETH_PROVIDER -a $DEV_TOKEN_INDEX_ADDRESS -f brief $CIC_DEFAULT_TOKEN_SYMBOL`
cat <<EOF cat <<EOF
Token registry: $DEV_TOKEN_INDEX_ADDRESS Token registry: $DEV_TOKEN_INDEX_ADDRESS
Account reigstry: $DEV_ACCOUNT_INDEX_ADDRESS Account reigstry: $DEV_ACCOUNT_INDEX_ADDRESS
Reserve address: $DEV_RESERVE_ADDRESS Reserve address: $DEV_RESERVE_ADDRESS ($CIC_DEFAULT_TOKEN_SYMBOL)
EOF EOF
>&2 echo "create account for gas gifter" >&2 echo "create account for gas gifter"
@@ -46,6 +52,7 @@ DEV_ETH_ACCOUNT_GAS_GIFTER=`cic-eth-create $debug --redis-host-callback=$REDIS_H
echo DEV_ETH_ACCOUNT_GAS_GIFTER=$DEV_ETH_ACCOUNT_GAS_GIFTER >> $env_out_file echo DEV_ETH_ACCOUNT_GAS_GIFTER=$DEV_ETH_ACCOUNT_GAS_GIFTER >> $env_out_file
cic-eth-tag -i $CIC_CHAIN_SPEC GAS_GIFTER $DEV_ETH_ACCOUNT_GAS_GIFTER cic-eth-tag -i $CIC_CHAIN_SPEC GAS_GIFTER $DEV_ETH_ACCOUNT_GAS_GIFTER
>&2 echo "create account for sarafu gifter" >&2 echo "create account for sarafu gifter"
DEV_ETH_ACCOUNT_SARAFU_GIFTER=`cic-eth-create $debug --redis-host-callback=$REDIS_HOST --redis-port-callback=$REDIS_PORT --no-register` DEV_ETH_ACCOUNT_SARAFU_GIFTER=`cic-eth-create $debug --redis-host-callback=$REDIS_HOST --redis-port-callback=$REDIS_PORT --no-register`
echo DEV_ETH_ACCOUNT_SARAFU_GIFTER=$DEV_ETH_ACCOUNT_SARAFU_GIFTER >> $env_out_file echo DEV_ETH_ACCOUNT_SARAFU_GIFTER=$DEV_ETH_ACCOUNT_SARAFU_GIFTER >> $env_out_file
@@ -97,5 +104,10 @@ export DEV_ETH_SARAFU_TOKEN_ADDRESS=$DEV_ETH_RESERVE_ADDRESS
#echo -n 0 > $init_level_file #echo -n 0 > $init_level_file
# Remove the SEND (8), QUEUE (16) and INIT (2) locks (or'ed), set by default at migration
cic-eth-ctl -i :: unlock INIT
cic-eth-ctl -i :: unlock SEND
cic-eth-ctl -i :: unlock QUEUE
set +a set +a
set +e set +e

View File

@@ -0,0 +1 @@
include *health*.sh

View File

@@ -0,0 +1,10 @@
docs:
mkdir -p doc/texinfo/html
makeinfo doc/texinfo/index.texi --html -o doc/texinfo/html/
markdown: doc
pandoc -f html -t markdown --standalone doc/texinfo/html/liveness.html -o README.md
.PHONY dist:
python setup.py sdist

View File

@@ -0,0 +1,105 @@
---
description: liveness (Untitled Document)
distribution: global
Generator: makeinfo
keywords: liveness (Untitled Document)
lang: en
resource-type: document
title: liveness (Untitled Document)
---
[]{#liveness}[]{#liveness-1}
## 1 liveness {#liveness .chapter}
[]{#ilveness_005foverview}[]{#Overview}
### 1.1 Overview {#overview .section}
This is a cluster-specific convenience setup for enabling a
Kubernetes-style liveness/readiness test as outlined in
<https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/>.
Conceptually, it provides an application with means to:
- Run a collection of functions to validate sanity of the environment
- Set a no-error state before execution of the main routine
- Modify the error state during execution
- Invalidating all state when execution ends
[]{#Python-module}
### 1.2 Python module {#python-module .section}
Three python methods are provided.
[]{#load}
#### 1.2.1 load {#load .subsection}
This is meant to be called after configurations and environment has been
set up, but before the execution logic has commenced.
It receives a list of externally defined fully-qualified python modules.
Each of these modules must implement the method `health(*args,**kwargs)`
in its global namespace.
Any module returning `False` will cause a `RuntimeException`.
The component will not trap any other exception from the modules.
If successful, it will write the `pid` of the application to the
specified run data folder. By default this is `/run/<HOSTNAME>`, but the
path can be modified if desired.
[]{#set}
#### 1.2.2 set {#set .subsection}
This is meant to be called during the execution of the main program
routine begins.
[]{#at-startup}
#### 1.2.2.1 at startup {#at-startup .subsubsection}
It should be called once at the *start* of execution of the main program
routine.
For one-shot routines, this would mean the start of any code only run
when the module name is `__main__`.
For daemons, it would be just before handing over execution to the main
loop.
[]{#during-execution}
#### 1.2.2.2 during execution {#during-execution .subsubsection}
Call `set(error_code=<error>, ...` any time the health state temporarily
changes. Any `error` value other than `0` is considered an unhealthy
state.
[]{#at-shutdown}
#### 1.2.2.3 at shutdown {#at-shutdown .subsubsection}
Call `reset(...)`, which will indicate that the state is to be
considered the same as at startup.
[]{#shell}
### 1.3 shell {#shell .section}
A bash script is provided for *Kubernetes* to perform the health check.
It performs the following checks:
1. A numeric value exists in `<rundir>/<unitname>/pid`{.sample}.
2. The numeric value is a directory in `/proc`{.sample} (a valid pid)
3. The file `<rundir>/<unitname>/error`{.sample} contains \"0\"
If any of these checks fail should inditcate that the container is
unhealthy.
------------------------------------------------------------------------

View File

@@ -0,0 +1,71 @@
@node liveness
@chapter liveness
@anchor{ilveness_overview}
@section Overview
This is a cluster-specific convenience setup for enabling a Kubernetes-style liveness/readiness test as outlined in @url{https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/}.
Conceptually, it provides an application with means to:
@itemize
@item Run a collection of functions to validate sanity of the environment
@item Set a no-error state before execution of the main routine
@item Modify the error state during execution
@item Invalidating all state when execution ends
@end itemize
@section Python module
Three python methods are provided.
@subsection load
This is meant to be called after configurations and environment has been set up, but before the execution logic has commenced.
It receives a list of externally defined fully-qualified python modules. Each of these modules must implement the method @code{health(*args,**kwargs)} in its global namespace.
Any module returning @code{False} will cause a @code{RuntimeException}.
The component will not trap any other exception from the modules.
If successful, it will write the @code{pid} of the application to the specified run data folder. By default this is @code{/run/<HOSTNAME>}, but the path can be modified if desired.
@subsection set
This is meant to be called during the execution of the main program routine begins.
@subsubsection at startup
It should be called once at the @emph{start} of execution of the main program routine.
For one-shot routines, this would mean the start of any code only run when the module name is @code{__main__}.
For daemons, it would be just before handing over execution to the main loop.
@subsubsection during execution
Call @code{set(error_code=<error>, ...} any time the health state temporarily changes. Any @code{error} value other than @code{0} is considered an unhealthy state.
@subsubsection at shutdown
Call @code{reset(...)}, which will indicate that the state is to be considered the same as at startup.
@section shell
A bash script is provided for @emph{Kubernetes} to perform the health check.
It performs the following checks:
@enumerate
@item A numeric value exists in @file{<rundir>/<unitname>/pid}.
@item The numeric value is a directory in @file{/proc} (a valid pid)
@item The file @file{<rundir>/<unitname>/error} contains "0"
@end enumerate
If any of these checks fail should inditcate that the container is unhealthy.

View File

@@ -0,0 +1,35 @@
#!/bin/bash
rundir=${CIC_RUNDIR:-/run}
unit=${CIC_UNIT:-$HOSTNAME}
read p < $rundir/$unit/pid
if [ -z $p ]; then
>&2 echo unit $unit has no pid
exit 1
fi
if [ ! -d /proc/$p ]; then
>&2 echo unit $unit reports non-existent pid $p
exit 1
fi
>&2 echo unit $unit has pid $p
if [ ! -f $rundir/$unit/error ]; then
>&2 echo unit $unit has unspecified state
exit 1
fi
read e 2> /dev/null < $rundir/$unit/error
if [ -z $e ]; then
>&2 echo unit $unit has unspecified state
exit 1
fi
>&2 echo unit $unit has error $e
if [ $e -gt 0 ]; then
exit 1;
fi

View File

@@ -0,0 +1,54 @@
# standard imports
import importlib
import sys
import os
import logging
logg = logging.getLogger().getChild(__name__)
pid = os.getpid()
default_namespace = os.environ.get('LIVENESS_UNIT_NAME')
if default_namespace == None:
import socket
default_namespace = socket.gethostname()
def load(check_strs, namespace=default_namespace, rundir='/run', *args, **kwargs):
if namespace == None:
import socket
namespace = socket.gethostname()
logg.info('pid ' + str(pid))
checks = []
for m in check_strs:
logg.debug('added liveness check: {}'.format(str(m)))
module = importlib.import_module(m)
checks.append(module)
for check in checks:
r = check.health(*args, **kwargs)
if r == False:
raise RuntimeError('liveness check {} failed'.format(str(check)))
logg.info('liveness check passed: {}'.format(str(check)))
app_rundir = os.path.join(rundir, namespace)
os.makedirs(app_rundir, exist_ok=True) # should not already exist
f = open(os.path.join(app_rundir, 'pid'), 'w')
f.write(str(pid))
f.close()
def set(error=0, namespace=default_namespace, rundir='/run'):
app_rundir = os.path.join(rundir, namespace)
f = open(os.path.join(app_rundir, 'error'), 'w')
f.write(str(error))
f.close()
def reset(namespace=default_namespace, rundir='/run'):
app_rundir = os.path.join(rundir, namespace)
os.unlink(os.path.join(app_rundir, 'pid'))
os.unlink(os.path.join(app_rundir, 'error'))

View File

@@ -0,0 +1,7 @@
from setuptools import setup
setup(
name='liveness',
version='0.0.1a7',
packages=['liveness'],
include_package_data=True,
)

View File

@@ -0,0 +1,17 @@
#!/bin/bash
export CIC_RUNDIR=`realpath ./tests/testdata/run`
t=`mktemp -d -p $CIC_RUNDIR`
export CIC_UNIT=`basename $t`
>&2 echo test pid $$
echo $$ > $t/pid
echo 0 > $t/error
. health.sh
echo 1 > $t/error
#unlink $t/error
. health.sh
echo if error this is not printed

View File

@@ -0,0 +1,8 @@
a = ['foo']
kw = {
'bar': 42,
}
def health(*args, **kwargs):
args[0] == a[0]
kwargs['bar'] = kw['bar']

View File

@@ -0,0 +1,2 @@
def health(*args, **kwargs):
return False

View File

@@ -0,0 +1,2 @@
def health(*args, **kwargs):
return True

View File

@@ -0,0 +1,129 @@
# standard imports
import os
import unittest
import logging
import tempfile
import socket
# local imports
import liveness.linux
## test imports
import tests.imports
logging.basicConfig(level=logging.DEBUG)
logg = logging.getLogger()
script_dir = os.path.realpath(os.path.dirname(__file__))
data_dir = os.path.join(script_dir, 'testdata')
run_base_dir = os.path.join(data_dir, 'run')
class TestImports(unittest.TestCase):
def setUp(self):
os.makedirs(run_base_dir, exist_ok=True)
self.run_dir = tempfile.mkdtemp(dir=run_base_dir)
self.unit = 'unittest'
self.unit_dir = os.path.join(self.run_dir, self.unit)
self.pid_path = os.path.join(self.unit_dir, 'pid')
self.error_path = os.path.join(self.unit_dir, 'error')
self.host_path = os.path.join(self.run_dir, socket.gethostname())
def test_no_import(self):
liveness.linux.load([], namespace=self.unit, rundir=self.run_dir)
f = open(self.pid_path, 'r')
r = f.read()
f.close()
self.assertEqual(str(os.getpid()), r)
def test_hostname(self):
liveness.linux.load([], rundir=self.run_dir)
f = open(os.path.join(self.host_path, 'pid'), 'r')
r = f.read()
f.close()
self.assertEqual(str(os.getpid()), r)
def test_import_single_true(self):
checks = ['tests.imports.import_true']
liveness.linux.load(checks, namespace=self.unit, rundir=self.run_dir)
f = open(self.pid_path, 'r')
r = f.read()
f.close()
self.assertEqual(str(os.getpid()), r)
def test_import_single_false(self):
checks = ['tests.imports.import_false']
with self.assertRaises(RuntimeError):
liveness.linux.load(checks, namespace=self.unit, rundir=self.run_dir)
with self.assertRaises(FileNotFoundError):
os.stat(self.pid_path)
def test_import_false_then_true(self):
checks = ['tests.imports.import_false', 'tests.imports.import_true']
with self.assertRaises(RuntimeError):
liveness.linux.load(checks, namespace=self.unit, rundir=self.run_dir)
with self.assertRaises(FileNotFoundError):
os.stat(self.pid_path)
def test_import_multiple_true(self):
checks = ['tests.imports.import_true', 'tests.imports.import_true']
liveness.linux.load(checks, namespace=self.unit, rundir=self.run_dir)
f = open(self.pid_path, 'r')
r = f.read()
f.close()
self.assertEqual(str(os.getpid()), r)
def test_set(self):
liveness.linux.load([], namespace='unittest', rundir=self.run_dir)
liveness.linux.set(namespace='unittest', rundir=self.run_dir)
f = open(self.error_path, 'r')
r = f.read()
f.close()
self.assertEqual('0', r)
liveness.linux.set(error=42, namespace='unittest', rundir=self.run_dir)
f = open(self.error_path, 'r')
r = f.read()
f.close()
self.assertEqual('42', r)
liveness.linux.reset(namespace='unittest', rundir=self.run_dir)
with self.assertRaises(FileNotFoundError):
os.stat(self.error_path)
def test_set_hostname(self):
liveness.linux.load([], rundir=self.run_dir)
liveness.linux.set(rundir=self.run_dir)
error_path = os.path.join(self.host_path, 'error')
f = open(error_path, 'r')
r = f.read()
f.close()
self.assertEqual('0', r)
liveness.linux.reset(rundir=self.run_dir)
with self.assertRaises(FileNotFoundError):
os.stat(error_path)
def test_args(self):
checks = ['tests.imports.import_args']
aargs=['foo']
kwaargs={'bar': 42}
liveness.linux.load(checks, self.unit, self.run_dir, *aargs, **kwaargs)
f = open(self.pid_path, 'r')
r = f.read()
f.close()
self.assertEqual(str(os.getpid()), r)
if __name__ == '__main__':
unittest.main()

View File

@@ -24,7 +24,7 @@ variables:
IMAGE_TAG_BASE: $CI_REGISTRY_IMAGE/$APP_NAME:$CI_COMMIT_BRANCH-$CI_COMMIT_SHORT_SHA IMAGE_TAG_BASE: $CI_REGISTRY_IMAGE/$APP_NAME:$CI_COMMIT_BRANCH-$CI_COMMIT_SHORT_SHA
LATEST_TAG: $CI_REGISTRY_IMAGE/$APP_NAME:latest LATEST_TAG: $CI_REGISTRY_IMAGE/$APP_NAME:latest
script: script:
- export IMAGE_TAG="$IMAGE_TAG_BASE-$(date +%F.%H%M%S)" - export IMAGE_TAG="$IMAGE_TAG_BASE-$(date +%s)"
- mkdir -p /kaniko/.docker - mkdir -p /kaniko/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > "/kaniko/.docker/config.json" - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > "/kaniko/.docker/config.json"
# - /kaniko/executor --context $CONTEXT --dockerfile $DOCKERFILE_PATH $KANIKO_CACHE_ARGS --destination $IMAGE_TAG # - /kaniko/executor --context $CONTEXT --dockerfile $DOCKERFILE_PATH $KANIKO_CACHE_ARGS --destination $IMAGE_TAG

View File

@@ -85,6 +85,7 @@ services:
# ETH_PROVIDER should be broken out into host/port but cic-eth expects this # ETH_PROVIDER should be broken out into host/port but cic-eth expects this
ETH_PROVIDER: http://eth:8545 ETH_PROVIDER: http://eth:8545
# And these two are for wait-for-it (could parse this) # And these two are for wait-for-it (could parse this)
DEV_USE_DOCKER_WAIT_SCRIPT: 1
ETH_PROVIDER_HOST: eth ETH_PROVIDER_HOST: eth
ETH_PROVIDER_PORT: 8545 ETH_PROVIDER_PORT: 8545
CIC_CHAIN_SPEC: ${CIC_CHAIN_SPEC:-evm:bloxberg:8996} CIC_CHAIN_SPEC: ${CIC_CHAIN_SPEC:-evm:bloxberg:8996}
@@ -103,6 +104,9 @@ services:
DEV_PIP_EXTRA_INDEX_URL: ${DEV_PIP_EXTRA_INDEX_URL:-https://pip.grassrootseconomics.net:8433} DEV_PIP_EXTRA_INDEX_URL: ${DEV_PIP_EXTRA_INDEX_URL:-https://pip.grassrootseconomics.net:8433}
RUN_MASK: ${RUN_MASK:-0} # bit flags; 1: contract migrations 2: seed data RUN_MASK: ${RUN_MASK:-0} # bit flags; 1: contract migrations 2: seed data
DEV_FAUCET_AMOUNT: ${DEV_FAUCET_AMOUNT:-0} DEV_FAUCET_AMOUNT: ${DEV_FAUCET_AMOUNT:-0}
CIC_DEFAULT_TOKEN_SYMBOL: ${CIC_DEFAULT_TOKEN_SYMBOL:-GFT}
DEV_SARAFU_DEMURRAGE_LEVEL: ${DEV_SARAFU_DEMURRAGE_LEVEL:-196454828847045000000000000000000}
DEV_ETH_GAS_PRICE: ${DEV_ETH_GAS_PRICE:-1}
command: ["./run_job.sh"] command: ["./run_job.sh"]
#command: ["./reset.sh"] #command: ["./reset.sh"]
depends_on: depends_on:
@@ -245,6 +249,7 @@ services:
SIGNER_SECRET: ${SIGNER_SECRET:-deadbeef} SIGNER_SECRET: ${SIGNER_SECRET:-deadbeef}
ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER: ${DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER:-0xACB0BC74E1686D62dE7DC6414C999EA60C09F0eA} ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER: ${DEV_ETH_ACCOUNT_ACCOUNTS_INDEX_WRITER:-0xACB0BC74E1686D62dE7DC6414C999EA60C09F0eA}
TASKS_TRACE_QUEUE_STATUS: ${TASKS_TRACE_QUEUE_STATUS:-1} TASKS_TRACE_QUEUE_STATUS: ${TASKS_TRACE_QUEUE_STATUS:-1}
CIC_DEFAULT_TOKEN_SYMBOL: ${CIC_DEFAULT_TOKEN_SYMBOL:-GFT}
depends_on: depends_on:
- eth - eth
- postgres - postgres