diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..00bdd50 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +__pycache__ +*.egg-info +*.pyc +*.d/ diff --git a/ge_render/__init__.py b/ge_render/__init__.py index b781994..ca245ce 100644 --- a/ge_render/__init__.py +++ b/ge_render/__init__.py @@ -1,43 +1,105 @@ # standard imports import logging +import os # external imports from eth_accounts_index import AccountsIndex +from erc20_faucet import Faucet +from cic_contracts.erc20 import ERC20 from chainlib.eth.error import RequestMismatchException +from chainlib.eth.address import AddressChecksum +from chainlib.eth.constant import ZERO_ADDRESS +from hexathon import uniform logg = logging.getLogger(__name__) +faucet_token_cache = {} +token_cache = {} + def get_method(chain_str, tx): data = tx.payload s = None - if len(data) >= 8: - s = data[:8] - v = sigmap.get(chain_str) - if v != None: - return v.get(s) - raise ValueError('not minimum signature length') - + if len(data) < 8: + raise ValueError('not minimum signature length') -def apply(c, s, chain_str, conn, block, tx, db_session=None): + data = uniform(data[:8]) + + chainmap = addrmap.get(chain_str) + if chainmap != None: + contractmap = chainmap.get(uniform(tx.inputs[0])) + if contractmap != None: + m = contractmap.get(data) + if m != None: + return m + + chainmap = sigmap.get(chain_str) + if chainmap != None: + return chainmap.get(data) + + +def apply(c, s, chain_spec, conn, block, tx, db_session=None): try: - m = get_method(chain_str, tx) + m = get_method(str(chain_spec), tx) except ValueError as e: return s if m == None: return s - return m(c, s, conn, block, tx) + r = m(c, s, chain_spec, conn, block, tx) + if r != None: + s = r + + return s -def account_registry_add(c, s, conn, block, tx): +def account_registry_add(c, s, chain_spec, conn, block, tx): try: o = AccountsIndex.parse_add_request(tx.payload) - ss = '{} block {} tx {} account registration for {}'.format(c, block.number, tx.index, o[0]) - return ss + s = '{} block {} tx {} account registration for {}'.format(c, block.number, tx.index, o[0]) + return s except RequestMismatchException as e: - return None + pass + + return None + + +def ge_faucet_gift(i, s, chain_spec, conn, block, tx): + + c = Faucet(chain_spec) + o = c.token_amount(tx.inputs[0], sender_address=ZERO_ADDRESS, height=block.number) + r = conn.do(o) + v = c.parse_token_amount(r) + logg.info('retrieved token amount {} at block height {} for faucet {}'.format(v, block.number, tx.inputs[0])) + + token = faucet_token_cache.get(tx.inputs[0]) + if token == None: + o = c.token(tx.inputs[0], sender_address=ZERO_ADDRESS) + r = conn.do(o) + token = c.parse_token(r) + token = uniform(token) + faucet_token_cache[tx.inputs[0]] = token + logg.info('found token {} for faucet {}'.format(v, token, tx.inputs[0])) + + token_symbol = token_cache.get(token) + if token_symbol == None: + c = ERC20(chain_spec) + o = c.symbol(token, sender_address=ZERO_ADDRESS) + r = conn.do(o) + token_symbol = c.parse_symbol(r) + token_cache[token] = token_symbol + logg.info('resolved token {} to symbol'.format(v, block.number, tx.inputs[0])) + + try: + o = Faucet.parse_give_to_request(tx.payload) + s = '{} GE faucet was triggered for {} {} by {} on block {} tx {}'.format(i, v, token_symbol, o[0], block.number, tx.index) + return s + except RequestMismatchException as e: + pass + + return None + sigmap = { @@ -45,3 +107,11 @@ sigmap = { '0a3b0a4f': account_registry_add, }, } + +addrmap = { + 'evm:byzantium:8996:bloxberg': { + 'd462aadb7251d418e6a9e4f205928f678e1c6b3b': { + '63e4bff4': ge_faucet_gift, + }, + } + } diff --git a/requirements.txt b/requirements.txt index 5c4df54..f9d5844 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,4 @@ -eth-monitor~=0.0.4 +eth-monitor~=0.0.5 eth_accounts_index~=0.1.2 +erc20-faucet~=0.3.2 +cic-contracts~=0.0.5